{"model_name":"mimo-v2-flash","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int n;\n    cin >> n;\n    \n    vector<Company> companies(n);\n    for (int i = 0; i < n; i++) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n    \n    // Sort by desired area descending\n    sort(companies.begin(), companies.end(), [](const Company& a, const Company& b) {\n        return a.r > b.r;\n    });\n    \n    vector<Rect> assigned_rects;\n    \n    for (int i = 0; i < n; i++) {\n        int x = companies[i].x;\n        int y = companies[i].y;\n        int r = companies[i].r;\n        \n        // Start with 1x1 rectangle containing the center\n        int left = x;\n        int right = x + 1;\n        int top = y;\n        int bottom = y + 1;\n        \n        // Expand in all directions until no more expansion possible\n        bool expanded = true;\n        while (expanded) {\n            expanded = false;\n            \n            // Try expanding left\n            if (left > 0) {\n                int new_left = left - 1;\n                bool can_expand = true;\n                \n                // Check against other centers\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    if (companies[j].x == new_left && companies[j].y >= top && companies[j].y < bottom) {\n                        can_expand = false;\n                        break;\n                    }\n                }\n                \n                // Check against assigned rectangles\n                if (can_expand) {\n                    for (const auto& rect : assigned_rects) {\n                        if (rect.a <= new_left && new_left < rect.c && rect.b < bottom && rect.d > top) {\n                            can_expand = false;\n                            break;\n                        }\n                    }\n                }\n                \n                if (can_expand) {\n                    left = new_left;\n                    expanded = true;\n                    continue;\n                }\n            }\n            \n            // Try expanding right\n            if (right < 10000) {\n                int new_right = right;\n                bool can_expand = true;\n                \n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    if (companies[j].x == new_right && companies[j].y >= top && companies[j].y < bottom) {\n                        can_expand = false;\n                        break;\n                    }\n                }\n                \n                if (can_expand) {\n                    for (const auto& rect : assigned_rects) {\n                        if (rect.a <= new_right && new_right < rect.c && rect.b < &&\n && bottom && &&))) bottom) can can can can can can can can can can can) can);\n, =\u53ef\u4ee5)));\n))))) can can can;\n;. can;\n can) expanded);\n can can)))));\n) {\n {\n)) =,;\n,,>;\n>) can can;\n = = =;\n\n {\n), = and =.))) */\n>) {\n;\n;\n {\n */\n\n,. </);\n\n,. {\n>;\n assigned, {\n. and) and code\">\">\">.\n\n}}, }> */ */\n.>>>\">.. {\n\");\n\n\u300b\u300b\n\n                if (can_expand) {\n                    right = new_right + 1;\n                    expanded = true;\n                    continue;\n                }\n            }\n            \n            // Try expanding top\n            if (top > 0) {\n                int new_top = top - 1;\n                bool can_expand = true;\n                \n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    if (companies[j].y == new_top && companies[j].x >= left && companies[j].x < right) {\n                        can_expand = false;\n                        break;\n                    }\n                }\n                \n                if (can_expand) {\n                    for (const auto& rect : assigned_rects) {\n                        if (rect.b <= new_top && new_top < rect.d && rect.a < right && rect.c > left) {\n                            can_expand = false;\n                            break;\n                        }\n                    }\n                }\n                \n                if (can_expand) {\n                    top = new_top;\n                    expanded = true;\n                    continue;\n                }\n            }\n            \n            // Try expanding bottom\n            if (bottom < 10000) {\n                int new_bottom = bottom;\n                bool can_expand = true;\n                \n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    if (companies[j].y == new_bottom && companies[j].x >= left && companies[j].x < right) {\n                        can_expand = false;\n                        break;\n                    }\n                }\n                \n                if (can_expand) {\n                    for (const auto& rect : assigned_rects) {\n                        if (rect.b <= new_bottom && new_bottom < rect.d && rect.a < right && rect.c > left) {\n                            can_expand = false;\n                            break;\n                        }\n                    }\n                }\n                \n                if (can_expand) {\n                    bottom = new_bottom + 1;\n                    expanded = true;\n                    continue;\n                }\n            }\n        }\n        \n        // Calculate maximum possible area\n        int max_area = (right - left) * (bottom - top);\n        int a, b, c, d;\n        \n        if (max_area < r) {\n            // Use the entire expanded rectangle\n            a = left;\n            b = top;\n            c = right;\n            d = bottom;\n        } else {\n            // Find best sub-rectangle with area closest to r\n            int best_w = 1, best_h = 1;\n            int best_diff = 2000000000;\n            \n            // Precompute valid widths\n            vector<bool> valid_w(right - left + 1, false);\n            for (int w = 1; w <= right - left; w++) {\n                int a_min = max(left, x - w + 1);\n                int a_max = min(x, right - w);\n                if (a_min <= a_max) {\n                    valid_w[w] = true;\n                }\n            }\n            \n            // Precompute valid heights\n            vector<bool> valid_h(bottom - top + 1, false);\n            for (int h = 1; h <= bottom - top; h++) {\n                int b_min = max(top, y - h + 1);\n                int b_max = min(y, bottom - h);\n                if (b_min <= b_max) {\n                    valid_h[h] = true;\n                }\n            }\n            \n            // Search for best width and height\n            for (int w = 1; w <= right - left; w++) {\n                if (!valid_w[w]) continue;\n                \n                int h1 = r / w;\n                int h2 = (r + w - 1) / w;\n                \n                vector<int> candidates = {h1-1, h1, h1+1, h2-1, h2, h2+1};\n                for (int h : candidates) {\n                    if (h < 1 || h > bottom - top) continue;\n                    if (!valid_h[h]) continue;\n                    \n                    int area = w * h;\n                    int diff = abs(area - r);\n                    if (diff < best_diff) {\n                        best_diff = diff;\n                        best_w = w;\n                        best_h = h;\n                    }\n                }\n            }\n            \n            int a_min = max(left, x - best_w + 1);\n            int a_max = min(x, right - best_w);\n            int b_min = max(top, y - best_h + 1);\n            int b_max = min(y, bottom - best_h);\n            \n            a = a_min;\n            b = b_min;\n            c = a + best_w;\n            d = b + best_h;\n        }\n        \n        // Output the rectangle\n        cout << a << \" \" << b << \" \" << c << \" \" << d << \"\\n\";\n        \n        // Store the assigned rectangle\n        assigned_rects.push_back({a, b, c, d});\n    }\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int si, sj;\n    cin >> si >> sj;\n    vector<vector<int>> t(50, vector<int>(50));\n    vector<vector<int>> p(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n        }\n    }\n    \n    int M = 0;\n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            if (t[i][j] > M) {\n                M = t[i][j];\n            }\n        }\n    }\n    M++;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n        }\n    }\n    \n    vector<vector<bool>> visited(50, vector<bool>(50, false));\n    vector<bool> leftTiles(M, false);\n    string path = \"\";\n    int i = si, j = sj;\n    visited[i][j] = true;\n    int currentTile = t[i][j];\n    \n    while (true) {\n        vector<tuple<int, int, int, bool>> candidates1;\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 >= 50 || nj < 0 || nj >= 50) continue;\n            if (visited[ni][nj]) continue;\n            int tid = t[ni][nj];\n            if (tid == currentTile) {\n                candidates1.push_back(make_tuple(p[ni][nj], ni, nj, false));\n            } else if (!leftTiles[tid]) {\n                candidates1.push_back(make_tuple(p[ni][nj], ni, nj, true));\n            }\n        }\n        \n        if (candidates1.empty()) break;\n        \n        int best_two_move_score = -1;\n        int best_ni = -1, best_nj = -1;\n        bool best_is_inter = false;\n        \n        int best_one_move_score = -1;\n        int best_one_ni = -1, best_one_nj = -1;\n        bool best_one_is_inter = false;\n        \n        for (auto &cand : candidates1) {\n            int score1 = get<0>(cand);\n            int ni1 = get<1>(cand);\n            int nj1 = get<2>(cand);\n            bool is_inter1 = get<3>(cand);\n            \n            if (score1 > best_one_move_score) {\n                best_one_move_score = score1;\n                best_one_ni = ni1;\n                best_one_nj = nj1;\n                best_one_is_inter = is_inter1;\n            }\n            \n            set<int> temp_left_set;\n            for (int idx = 0; idx < M; idx++) {\n                if (leftTiles[idx]) {\n                    temp_left_set.insert(idx);\n                }\n            }\n            int temp_current = currentTile;\n            if (is_inter1) {\n                temp_left_set.insert(currentTile);\n                temp_current = t[ni1][nj1];\n            }\n            \n            int best_score2 = -1;\n            for (int d2 = 0; d2 < 4; d2++) {\n                int ni2 = ni1 + dx[d2];\n                int nj2 = nj1 + dy[d2];\n                if (ni2 < 0 || ni2 >= 50 || nj2 < 0 || nj2 >= 50) continue;\n                if (visited[ni2][nj2]) continue;\n                if (ni2 == i && nj2 == j) continue;\n                int tid2 = t[ni2][nj2];\n                if (tid2 == temp_current) {\n                    int total_score = score1 + p[ni2][nj2];\n                    if (total_score > best_score2) {\n                        best_score2 = total_score;\n                    }\n                } else if (temp_left_set.find(tid2) == temp_left_set.end()) {\n                    int total_score = score1 + p[ni2][nj2];\n                    if (total_score > best_score2) {\n                        best_score2 = total_score;\n                    }\n                }\n            }\n            \n            if (best_score2 != -1) {\n                if (best_score2 > best_two_move_score) {\n                    best_two_move_score = best_score2;\n                    best_ni = ni1;\n                    best_nj = nj1;\n                    best_is_inter = is_inter1;\n                }\n            }\n        }\n        \n        int chosen_i, chosen_j;\n        bool chosen_is_inter;\n        if (best_two_move_score != -1) {\n            chosen_i = best_ni;\n            chosen_j = best_nj;\n            chosen_is_inter = best_is_inter;\n        } else {\n            if (best_one_move_score == -1) break;\n            chosen_i = best_one_ni;\n            chosen_j = best_one_nj;\n            chosen_is_inter = best_one_is_inter;\n        }\n        \n        int di = chosen_i - i;\n        int dj = chosen_j - j;\n        if (di == -1) path += 'U';\n        else if (di == 1) path += 'D';\n        else if (dj == -1) path += 'L';\n        else if (dj == 1) path += 'R';\n        \n        visited[chosen_i][chosen_j] = true;\n        if (chosen_is_inter) {\n            leftTiles[currentTile] = true;\n            currentTile = t[chosen_i][chosen_j];\n        }\n        i = chosen_i;\n        j = chosen_j;\n    }\n    \n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <string>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nconst double alpha = 0.1;\nconst double low_bound = 1000.0;\nconst double high_bound = 9000.0;\n\ndouble H_est[30][29];\ndouble V_est[29][30];\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\ndouble get_edge_weight(int i, int j, int ni, int nj) {\n    if (ni == i-1 && nj == j) {\n        return V_est[i-1][j];\n    } else if (ni == i+1 && nj == j) {\n        return V_est[i][j];\n    } else if (ni == i && nj == j-1) {\n        return H_est[i][j-1];\n    } else if (ni == i && nj == j+1) {\n        return H_est[i][j];\n    }\n    return 1e18;\n}\n\nvoid update_edge(int i, int j, int ni, int nj, double delta) {\n    if (ni == i-1 && nj == j) {\n        V_est[i-1][j] += delta;\n        if (V_est[i-1][j] < low_bound) V_est[i-1][j] = low_bound;\n        if (V_est[i-1][j] > high_bound) V_est[i-1][j] = high_bound;\n    } else if (ni == i+1 && nj == j) {\n        V_est[i][j] += delta;\n        if (V_est[i][j] < low_bound) V_est[i][j] = low_bound;\n        if (V_est[i][j] > high_bound) V_est[i][j] = high_bound;\n    } else if (ni == i && nj == j-1) {\n        H_est[i][j-1] += delta;\n        if (H_est[i][j-1] < low_bound) H_est[i][j-1] = low_bound;\n        if (H_est[i][j-1] > high_bound) H_est[i][j-1] = high_bound;\n    } else if (ni == i && nj == j+1) {\n        H_est[i][j] += delta;\n        if (H_est[i][j] < low_bound) H_est[i][j] = low_bound;\n        if (H_est[i][j] > high_bound) H_est[i][j] = high_bound;\n    }\n}\n\nstring dijkstra(int si, int sj, int ti, int tj, double &est_length) {\n    vector<vector<double>> dist(30, vector<double>(30, 1e18));\n    vector<vector<pair<int, int>>> parent(30, vector<pair<int, int>>(30, {-1, -1}));\n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<tuple<double, int, int>>> pq;\n    dist[si][sj] = 0.0;\n    pq.push(make_tuple(0.0, si, sj));\n\n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        if (d != dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n            double w = get_edge_weight(i, j, ni, nj);\n            if (dist[ni][nj] > dist[i][j] + w) {\n                dist[ni][nj] = dist[i][j] + w;\n                parent[ni][nj] = make_pair(i, j);\n                pq.push(make_tuple(dist[ni][nj], ni, nj));\n            }\n        }\n    }\n\n    vector<pair<int, int>> path_nodes;\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        path_nodes.push_back({i, j});\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    path_nodes.push_back({si, sj});\n    reverse(path_nodes.begin(), path_nodes.end());\n\n    string path_str = \"\";\n    est_length = 0.0;\n    for (int idx = 0; idx < path_nodes.size()-1; idx++) {\n        int i1 = path_nodes[idx].first;\n        int j1 = path_nodes[idx].second;\n        int i2 = path_nodes[idx+1].first;\n        int j2 = path_nodes[idx+1].second;\n        char move;\n        if (i2 == i1-1) move = 'U';\n        else if (i2 == i1+1) move = 'D';\n        else if (j2 == j1-1) move = 'L';\n        else if (j2 == j1+1) move = 'R';\n        path_str += move;\n\n        double w = get_edge_weight(i1, j1, i2, j2);\n        est_length += w;\n    }\n\n    return path_str;\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 29; j++) {\n            H_est[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 30; j++) {\n            V_est[i][j] = 5000.0;\n        }\n    }\n\n    int si, sj, ti, tj;\n    for (int k = 0; k < 1000; k++) {\n        cin >> si >> sj >> ti >> tj;\n        double est_length;\n        string path = dijkstra(si, sj, ti, tj, est_length);\n        cout << path << endl;\n        cout.flush();\n\n        long long F;\n        cin >> F;\n\n        int n = path.size();\n        if (n == 0) continue;\n\n        double error = static_cast<double>(F) - est_length;\n        double delta = (error * alpha) / n;\n\n        int cur_i = si, cur_j = sj;\n        for (char move : path) {\n            int next_i = cur_i, next_j = cur_j;\n            if (move == 'U') next_i--;\n            else if (move == 'D') next_i++;\n            else if (move == 'L') next_j--;\n            else if (move == 'R') next_j++;\n\n            update_edge(cur_i, cur_j, next_i, next_j, delta);\n\n            cur_i = next_i;\n            cur_j = next_j;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) {\n        cin >> s[i];\n    }\n\n    vector<string> mat(N, string(N, '.'));\n    vector<tuple<int, string, int>> sorted;\n    for (int i = 0; i < M; i++) {\n        sorted.push_back(make_tuple(s[i].size(), s[i], i));\n    }\n    sort(sorted.begin(), sorted.end(), [](const tuple<int, string, int>& a, const tuple<int, string, int>& b) {\n        return get<0>(a) > get<0>(b);\n    });\n\n    vector<bool> covered(M, false);\n\n    for (auto &t : sorted) {\n        int len = get<0>(t);\n        string str = get<1>(t);\n        int idx = get<2>(t);\n        bool placed = false;\n\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int col = (j + p) % N;\n                    if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) {\n                    for (int p = 0; p < len; p++) {\n                        int col = (j + p) % N;\n                        mat[i][col] = str[p];\n                    }\n                    covered[idx] = true;\n                    placed = true;\n                }\n            }\n        }\n\n        if (placed) continue;\n\n        for (int j = 0; j < N && !placed; j++) {\n            for (int i = 0; i < N && !placed; i++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int row = (i + p) % N;\n                    if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) {\n                    for (int p = 0; p < len; p++) {\n                        int row = (i + p) % N;\n                        mat[row][j] = str[p];\n                    }\n                    covered[idx] = true;\n                    placed = true;\n                }\n            }\n        }\n    }\n\n    vector<string> uncovered;\n    for (int i = 0; i < M; i++) {\n        if (!covered[i]) {\n            uncovered.push_back(s[i]);\n        }\n    }\n\n    sort(uncovered.begin(), uncovered.end(), [](const string& a, const string& b) {\n        return a.size() > b.size();\n    });\n\n    for (string str : uncovered) {\n        int len = str.size();\n        bool placed = false;\n\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int col = (j + p) % N;\n                    if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) {\n                    for (int p = 0; p < len; p++) {\n                        int col = (j + p) % N;\n                        mat[i][col] = str[p];\n                    }\n                    placed = true;\n                }\n            }\n        }\n\n        if (placed) continue;\n\n        for (int j = 0; j < N && !placed; j++) {\n            for (int i = 0; i < N && !placed; i++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int row = (i + p) % N;\n                    if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) {\n                    for (int p = 0; p < len; p++) {\n                        int row = (i + p) % N;\n                        mat[row][j] = str[p];\n                    }\n                    placed = true;\n                }\n            }\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (mat[i][j] == '.') {\n                mat[i][j] = 'A';\n            }\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << mat[i] << endl;\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<vector<int>> hid(N, vector<int>(N, -1));\n    vector<vector<int>> vid(N, vector<int>(N, -1));\n    int totalH = 0, totalV = 0;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '#') continue;\n            if (j == 0 || grid[i][j-1] == '#') {\n                int k = j;\n                while (k < N && grid[i][k] != '#') {\n                    hid[i][k] = totalH;\n                    k++;\n                }\n                totalH++;\n            }\n        }\n    }\n\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][j] == '#') continue;\n            if (i == 0 || grid[i-1][j] == '#') {\n                int k = i;\n                while (k < N && grid[k][j] != '#') {\n                    vid[k][j] = totalV;\n                    k++;\n                }\n                totalV++;\n            }\n        }\n    }\n\n    vector<bool> uncoveredH(totalH, true);\n    vector<bool> uncoveredV(totalV, true);\n\n    int startH = hid[si][sj];\n    int startV = vid[si][sj];\n    if (startH != -1) uncoveredH[startH] = false;\n    if (startV != -1) uncoveredV[startV] = false;\n\n    int cur_i = si, cur_j = sj;\n    string route = \"\";\n\n    const int MAX_ITER = 1000;\n    int iter = 0;\n\n    while (iter < MAX_ITER) {\n        bool has_uncovered = false;\n        for (bool b : uncoveredH) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) for (bool b : uncoveredV) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) break;\n\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1,-1}));\n        vector<vector<char>> move_dir(N, vector<char>(N, 0));\n        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;\n\n        dist[cur_i][cur_j] = 0;\n        pq.push({0, cur_i, cur_j});\n\n        while (!pq.empty()) {\n            auto [cost, i, j] = pq.top();\n            pq.pop();\n            if (cost != dist[i][j]) continue;\n            const int dx[4] = {-1, 1, 0, 0};\n            const int dy[4] = {0, 0, -1, 1};\n            const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n                if (grid[ni][nj] == '#') continue;\n                int ncost = cost + (grid[ni][nj] - '0');\n                if (ncost < dist[ni][nj]) {\n                    dist[ni][nj] = ncost;\n                    parent[ni][nj] = {i, j};\n                    move_dir[ni][nj] = dirs[d];\n                    pq.push({ncost, ni, nj});\n                }\n            }\n        }\n\n        int best_i = -1, best_j = -1;\n        int best_cost = INF;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == '#' || dist[i][j] == INF) continue;\n                bool covers = false;\n                if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) covers = true;\n                if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) covers = true;\n                if (covers && dist[i][j] < best_cost) {\n                    best_cost = dist[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n\n        if (best_i == -1) break;\n\n        string path_moves = \"\";\n        int i = best_i, j = best_j;\n        while (i != cur_i || j != cur_j) {\n            char m = move_dir[i][j];\n            path_moves = m + path_moves;\n            if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) uncoveredH[hid[i][j]] = false;\n            if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) uncoveredV[vid[i][j]] = false;\n            auto [pi, pj] = parent[i][j];\n            i = pi;\n            j = pj;\n        }\n\n        route += path_moves;\n        cur_i = best_i;\n        cur_j = best_j;\n        iter++;\n    }\n\n    vector<vector<int>> dist_ret(N, vector<int>(N, INF));\n    vector<vector<pair<int,int>>> parent_ret(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<char>> move_dir_ret(N, vector<char>(N, 0));\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq_ret;\n\n    dist_ret[cur_i][cur_j] = 0;\n    pq_ret.push({0, cur_i, cur_j});\n\n    while (!pq_ret.empty()) {\n        auto [cost, i, j] = pq_ret.top();\n        pq_ret.pop();\n        if (cost != dist_ret[i][j]) continue;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n            if (grid[ni][nj] == '#') continue;\n            int ncost = cost + (grid[ni][nj] - '0');\n            if (ncost < dist_ret[ni][nj]) {\n                dist_ret[ni][nj] = ncost;\n                parent_ret[ni][nj] = {i, j};\n                move_dir_ret[ni][nj] = dirs[d];\n                pq_ret.push({ncost, ni, nj});\n            }\n        }\n    }\n\n    if (dist_ret[si][sj] == INF) {\n        cerr << \"No path back to start!\" << endl;\n    } else {\n        string return_path = \"\";\n        int i = si, j = sj;\n        while (i != cur_i || j != cur_j) {\n            auto [pi, pj] = parent_ret[i][j];\n            char m = move_dir_ret[i][j];\n            return_path = m + return_path;\n            i = pi;\n            j = pj;\n        }\n        route += return_path;\n    }\n\n    cout << route << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <map>\n#include <set>\n#include <cmath>\n#include <iomanip>\n#include <climits>\n\nusing namespace std;\n\nstruct Task {\n    int id;\n    vector<int> requirements;\n    vector<int> children;\n    int in_degree;\n    int depth_forward;\n    double criticality;\n};\n\nstruct TeamMember {\n    int id;\n    vector<int> skills; // estimated skills\n    int current_task; // -1 if free\n    int busy_until; // day when current task will complete (estimated)\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<Task> tasks(N);\n    for (int i = 0; i < N; i++) {\n        tasks[i].id = i;\n        tasks[i].requirements.resize(K);\n        for (int k = 0; k < K; k++) {\n            cin >> tasks[i].requirements[k];\n        }\n        tasks[i].in_degree = 0;\n    }\n    \n    // Read dependencies\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        tasks[u].children.push_back(v);\n        tasks[v].in_degree++;\n    }\n    \n    // Compute depth_forward (longest path to end)\n    for (int i = N-1; i >= 0; i--) {\n        if (tasks[i].children.empty()) {\n            tasks[i].depth_forward = 0;\n        } else {\n            int max_depth = 0;\n            for (int child : tasks[i].children) {\n                max_depth = max(max_depth, tasks[child].depth_forward);\n            }\n            tasks[i].depth_forward = 1 + max_depth;\n        }\n    }\n    \n    // Initialize team members\n    vector<TeamMember> members(M);\n    for (int i = 0; i < M; i++) {\n        members[i].id = i;\n        members[i].skills.assign(K, 0); // Start with 0 skills\n        members[i].current_task = -1;\n        members[i].busy_until = 0;\n    }\n    \n    // State tracking\n    vector<int> task_status(N, -1); // -1: not started, 0: assigned, 1: completed\n    vector<int> start_day(N, -1);\n    vector<int> current_in_degree = [&]() {\n        vector<int> deg(N);\n        for (int i = 0; i < N; i++) deg[i] = tasks[i].in_degree;\n        return deg;\n    }();\n    \n    // Learning parameters\n    const double LEARNING_RATE = 0.2;\n    const int MAX_DAYS = 2000;\n    \n    for (int day = 1; day <= MAX_DAYS; day++) {\n        // Read feedback from previous day\n        if (day > 1) {\n            int n_completed;\n            cin >> n_completed;\n            \n            if (n_completed == -1) {\n                break; // All tasks completed or day limit reached\n            }\n            \n            vector<int> completed_members(n_completed);\n            for (int i = 0; i < n_completed; i++) {\n                cin >> completed_members[i];\n                completed_members[i]--; // Convert to 0-indexed\n            }\n            \n            // Update skills based on completed tasks\n            for (int member_idx : completed_members) {\n                int task_idx = members[member_idx].current_task;\n                if (task_idx == -1) continue;\n                \n                // Calculate actual time taken\n                int time_taken = day - start_day[task_idx];\n                \n                // Update skill estimates\n                if (time_taken > 1) {\n                    int current_gap = 0;\n                    vector<int> gaps(K, 0);\n                    \n                    for (int k = 0; k < K; k++) {\n                        if (tasks[task_idx].requirements[k] > members[member_idx].skills[k]) {\n                            gaps[k] = tasks[task_idx].requirements[k] - members[member_idx].skills[k];\n                            current_gap += gaps[k];\n                        }\n                    }\n                    \n                    if (current_gap > 0) {\n                        double extra_time = time_taken - 1;\n                        for (int k = 0; k < K; k++) {\n                            if (gaps[k] > 0) {\n                                double increase = extra_time * LEARNING_RATE * (gaps[k] / (double)current_gap);\n                                int new_skill = members[member_idx].skills[k] + (int)round(increase);\n                                // Cap at requirement to avoid overestimation\n                                new_skill = min(new_skill, tasks[task_idx].requirements[k]);\n                                members[member_idx].skills[k] = new_skill;\n                            }\n                        }\n                    }\n                }\n                \n                // Mark task as completed\n                task_status[task_idx] = 1;\n                members[member_idx].current_task = -1;\n                members[member_idx].busy_until = 0;\n                \n                // Update dependencies for children\n                for (int child : tasks[task_idx].children) {\n                    current_in_degree[child]--;\n                }\n            }\n        }\n        \n        // Find available tasks (all dependencies completed, not started)\n        vector<int> available_tasks;\n        for (int i = 0; i < N; i++) {\n            if (current_in_degree[i] == 0 && task_status[i] == -1) {\n                available_tasks.push_back(i);\n            }\n        }\n        \n        // Find free team members\n        vector<int> free_members;\n        for (int i = 0; i < M; i++) {\n            if (members[i].current_task == -1) {\n                free_members.push_back(i);\n            }\n        }\n        \n        // If no work to do, output 0 and continue\n        if (available_tasks.empty() || free_members.empty()) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n        \n        // Assign tasks using greedy heuristic\n        vector<pair<int, int>> assignments;\n        \n        // Calculate estimated time for each (member, task) pair\n        auto estimate_time = [&](int member_idx, int task_idx) -> double {\n            int gap = 0;\n            for (int k = 0; k < K; k++) {\n                if (tasks[task_idx].requirements[k] > members[member_idx].skills[k]) {\n                    gap += tasks[task_idx].requirements[k] - members[member_idx].skills[k];\n                }\n            }\n            if (gap == 0) return 1.0;\n            // Expected time: max(1, gap + average_offset) \u2248 gap + 1 (since average offset is 0)\n            return gap + 1.0;\n        };\n        \n        // Greedy assignment: prioritize critical tasks and assign to best member\n        while (!free_members.empty() && !available_tasks.empty()) {\n            // Find the most critical available task\n            int best_task = -1;\n            double best_priority = -1;\n            int best_task_idx = -1;\n            \n            for (int i = 0; i < available_tasks.size(); i++) {\n                int task_idx = available_tasks[i];\n                // Priority: criticality (depth) - we could also consider task requirements\n                double priority = tasks[task_idx].depth_forward;\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_task = task_idx;\n                    best_task_idx = i;\n                }\n            }\n            \n            // Find the best member for this task\n            int best_member = -1;\n            double best_time = 1e9;\n            int best_member_idx = -1;\n            \n            for (int i = 0; i < free_members.size(); i++) {\n                int member_idx = free_members[i];\n                double est_time = estimate_time(member_idx, best_task);\n                if (est_time < best_time) {\n                    best_time = est_time;\n                    best_member = member_idx;\n                    best_member_idx = i;\n                }\n            }\n            \n            // Make assignment\n            assignments.push_back({best_member, best_task});\n            task_status[best_task] = 0;\n            members[best_member].current_task = best_task;\n            start_day[best_task] = day;\n            members[best_member].busy_until = day + (int)ceil(best_time) - 1;\n            \n            // Remove from available lists\n            available_tasks.erase(available_tasks.begin() + best_task_idx);\n            free_members.erase(free_members.begin() + best_member_idx);\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& assignment : assignments) {\n            cout << \" \" << assignment.first + 1 << \" \" << assignment.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Order {\n    int a, b, c, d;\n    int index;\n};\n\nint manhattan(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\n// Calculate cost if we serve order alone (office -> pickup -> delivery -> office)\nint individualCost(const Order& order) {\n    Point office(400, 400);\n    Point pickup(order.a, order.b);\n    Point delivery(order.c, order.d);\n    return manhattan(office, pickup) + manhattan(pickup, delivery) + manhattan(delivery, office);\n}\n\n// Select 50 orders using greedy approach with clustering\nvector<Order> selectOrders(const vector<Order>& allOrders) {\n    vector<Order> selected;\n    \n    // Create a copy to work with\n    vector<Order> remaining = allOrders;\n    \n    // Start with the order closest to office\n    Point office(400, 400);\n    int bestIdx = -1;\n    int bestDist = 1e9;\n    for (int i = 0; i < remaining.size(); i++) {\n        int dist = manhattan(office, Point(remaining[i].a, remaining[i].b));\n        if (dist < bestDist) {\n            bestDist = dist;\n            bestIdx = i;\n        }\n    }\n    selected.push_back(remaining[bestIdx]);\n    remaining.erase(remaining.begin() + bestIdx);\n    \n    // Greedily add orders that are close to already selected ones\n    while (selected.size() < 50 && !remaining.empty()) {\n        int bestRemaining = -1;\n        int bestIncrease = 1e9;\n        \n        for (int i = 0; i < remaining.size(); i++) {\n            // Estimate cost increase by adding this order\n            int minIncrease = 1e9;\n            \n            // Check distance from all selected orders' endpoints\n            for (const Order& sel : selected) {\n                Point selEnd(sel.c, sel.d);\n                Point newPickup(remaining[i].a, remaining[i].b);\n                int inc = manhattan(selEnd, newPickup);\n                minIncrease = min(minIncrease, inc);\n            }\n            \n            // Also consider distance from office\n            int officeInc = manhattan(office, Point(remaining[i].a, remaining[i].b));\n            minIncrease = min(minIncrease, officeInc);\n            \n            if (minIncrease < bestIncrease) {\n                bestIncrease = minIncrease;\n                bestRemaining = i;\n            }\n        }\n        \n        if (bestRemaining != -1) {\n            selected.push_back(remaining[bestRemaining]);\n            remaining.erase(remaining.begin() + bestRemaining);\n        }\n    }\n    \n    // If we still need more orders, fill with those having smallest individual cost\n    while (selected.size() < 50 && !remaining.empty()) {\n        int bestIdx = -1;\n        int bestCost = 1e9;\n        for (int i = 0; i < remaining.size(); i++) {\n            int cost = individualCost(remaining[i]);\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestIdx = i;\n            }\n        }\n        selected.push_back(remaining[bestIdx]);\n        remaining.erase(remaining.begin() + bestIdx);\n    }\n    \n    return selected;\n}\n\n// Build route using greedy approach with precedence constraints\nvector<Point> buildRoute(const vector<Order>& selected) {\n    vector<Point> route;\n    Point office(400, 400);\n    route.push_back(office);\n    \n    // Track which orders have been picked up but not delivered\n    set<int> pickedUp;\n    set<int> delivered;\n    \n    // All orders start as not picked up\n    vector<int> remaining;\n    for (int i = 0; i < selected.size(); i++) {\n        remaining.push_back(i);\n    }\n    \n    Point current = office;\n    \n    while (!remaining.empty() || !pickedUp.empty()) {\n        int bestChoice = -1; // 0-49 for pickup, 50-99 for delivery\n        int bestDist = 1e9;\n        bool isDelivery = false;\n        \n        // Check available pickups\n        for (int idx : remaining) {\n            Point pickup(selected[idx].a, selected[idx].b);\n            int dist = manhattan(current, pickup);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestChoice = idx;\n                isDelivery = false;\n            }\n        }\n        \n        // Check available deliveries\n        for (int idx : pickedUp) {\n            Point delivery(selected[idx].c, selected[idx].d);\n            int dist = manhattan(current, delivery);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestChoice = idx;\n                isDelivery = true;\n            }\n        }\n        \n        if (bestChoice == -1) break;\n        \n        if (isDelivery) {\n            route.push_back(Point(selected[bestChoice].c, selected[bestChoice].d));\n            pickedUp.erase(bestChoice);\n            delivered.insert(bestChoice);\n        } else {\n            route.push_back(Point(selected[bestChoice].a, selected[bestChoice].b));\n            pickedUp.insert(bestChoice);\n            // Remove from remaining\n            for (int i = 0; i < remaining.size(); i++) {\n                if (remaining[i] == bestChoice) {\n                    remaining.erase(remaining.begin() + i);\n                    break;\n                }\n            }\n        }\n        \n        current = route.back();\n    }\n    \n    // Return to office\n    route.push_back(office);\n    \n    return route;\n}\n\n// Improve route using 2-opt like moves respecting precedence\nvector<Point> improveRoute(const vector<Point>& route, const vector<Order>& selected) {\n    vector<Point> improved = route;\n    bool improved_flag = true;\n    \n    // Create mapping from points to orders for precedence checking\n    // For each order, we need to know if pickup has been visited before delivery\n    vector<int> orderPickupIndex(selected.size(), -1);\n    vector<int> orderDeliveryIndex(selected.size(), -1);\n    \n    for (int i = 0; i < improved.size(); i++) {\n        for (int j = 0; j < selected.size(); j++) {\n            if (improved[i].x == selected[j].a && improved[i].y == selected[j].b) {\n                orderPickupIndex[j] = i;\n            }\n            if (improved[i].x == selected[j].c && improved[i].y == selected[j].d) {\n                orderDeliveryIndex[j] = i;\n            }\n        }\n    }\n    \n    // Check if swapping two points maintains precedence\n    auto canSwap = [&](int i, int j) {\n        // If both are from same order, check if swap would violate precedence\n        for (int k = 0; k < selected.size(); k++) {\n            bool iIsPickup = (improved[i].x == selected[k].a && improved[i].y == selected[k].b);\n            bool iIsDelivery = (improved[i].x == selected[k].c && improved[i].y == selected[k].d);\n            bool jIsPickup = (improved[j].x == selected[k].a && improved[j].y == selected[k].b);\n            bool jIsDelivery = (improved[j].x == selected[k].c && improved[j].y == selected[k].d);\n            \n            if (iIsPickup && jIsDelivery) {\n                return false; // Would put delivery before pickup\n            }\n            if (jIsPickup && iIsDelivery) {\n                return false; // Would put delivery before pickup\n            }\n        }\n        return true;\n    };\n    \n    int n = improved.size();\n    while (improved_flag) {\n        improved_flag = false;\n        for (int i = 1; i < n - 2; i++) {\n            for (int j = i + 1; j < n - 1; j++) {\n                if (!canSwap(i, j)) continue;\n                \n                // Calculate cost difference\n                int currentCost = manhattan(improved[i-1], improved[i]) + \n                                 manhattan(improved[i], improved[i+1]) + \n                                 manhattan(improved[j-1], improved[j]) + \n                                 manhattan(improved[j], improved[j+1]);\n                \n                if (i+1 == j) {\n                    // Adjacent swap\n                    int newCost = manhattan(improved[i-1], improved[j]) + \n                                 manhattan(improved[j], improved[i]) + \n                                 manhattan(improved[i], improved[j+1]);\n                    if (newCost < currentCost) {\n                        swap(improved[i], improved[j]);\n                        improved_flag = true;\n                    }\n                } else {\n                    int newCost = manhattan(improved[i-1], improved[j]) + \n                                 manhattan(improved[j], improved[i+1]) + \n                                 manhattan(improved[j-1], improved[i]) + \n                                 manhattan(improved[i], improved[j+1]);\n                    if (newCost < currentCost) {\n                        swap(improved[i], improved[j]);\n                        improved_flag = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    return improved;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read all orders\n    vector<Order> allOrders;\n    for (int i = 0; i < 1000; i++) {\n        Order order;\n        cin >> order.a >> order.b >> order.c >> order.d;\n        order.index = i + 1;\n        allOrders.push_back(order);\n    }\n    \n    // Select 50 orders\n    vector<Order> selected = selectOrders(allOrders);\n    \n    // Build initial route\n    vector<Point> route = buildRoute(selected);\n    \n    // Improve the route\n    route = improveRoute(route, selected);\n    \n    // Output selected orders\n    cout << selected.size();\n    for (const Order& order : selected) {\n        cout << \" \" << order.index;\n    }\n    cout << \"\\n\";\n    \n    // Output route\n    cout << route.size();\n    for (const Point& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int INF = 1000000000;\n\nvector<int> parent;\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<pair<int, int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n    }\n\n    vector<int> d(M);\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        long long dx = x[u] - x[v];\n        long long dy = y[u] - y[v];\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = (int)round(dist);\n    }\n\n    parent.resize(N);\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n\n    vector<vector<int>> count_between(N, vector<int>(N, 0));\n    vector<vector<int>> min_baseline_between(N, vector<int>(N, INF));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        count_between[u][v] = 1;\n        count_between[v][u] = 1;\n        min_baseline_between[u][v] = d[i];\n        min_baseline_between[v][u] = d[i];\n    }\n\n    vector<bool> is_rep(N, true);\n    int adopted_count = 0;\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n\n        int rep_u = find(u);\n        int rep_v = find(v);\n\n        if (rep_u == rep_v) {\n            cout << 0 << endl;\n        } else {\n            int current_count = count_between[rep_u][rep_v];\n            bool adopt = false;\n\n            if (current_count == 1) {\n                adopt = true;\n            } else {\n                if (l_i <= 2 * d[i]) {\n                    adopt = true;\n                } else {\n                    adopt = false;\n                }\n            }\n\n            count_between[rep_u][rep_v] = current_count - 1;\n            count_between[rep_v][rep_u] = current_count - 1;\n\n            if (adopt) {\n                cout << 1 << endl;\n                adopted_count++;\n\n                int new_rep = min(rep_u, rep_v);\n                int old_rep = max(rep_u, rep_v);\n\n                parent[old_rep] = new_rep;\n\n                for (int j = 0; j < N; j++) {\n                    if (is_rep[j] && j != new_rep && j != old_rep) {\n                        count_between[new_rep][j] += count_between[old_rep][j];\n                        if (min_baseline_between[new_rep][j] > min_baseline_between[old_rep][j]) {\n                            min_baseline_between[new_rep][j] = min_baseline_between[old_rep][j];\n                        }\n                        count_between[j][new_rep] = count_between[new_rep][j];\n                        min_baseline_between[j][new_rep] = min_baseline_between[new_rep][j];\n                    }\n                }\n\n                is_rep[old_rep] = false;\n\n                for (int j = 0; j < N; j++) {\n                    count_between[old_rep][j] = 0;\n                    count_between[j][old_rep] = 0;\n                    min_baseline_between[old_rep][j] = INF;\n                    min_baseline_between[j][old_rep] = INF;\n                }\n            } else {\n                cout << 0 << endl;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\nusing namespace std;\n\nconst int dx4[4] = {-1, 1, 0, 0};\nconst int dy4[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int N;\n    cin >> N;\n    vector<int> pet_x(N), pet_y(N), pet_type(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n        pet_x[i]--; \n        pet_y[i]--;\n    }\n\n    int M;\n    cin >> M;\n    vector<int> human_x(M), human_y(M);\n    for (int i = 0; i < M; i++) {\n        cin >> human_x[i] >> human_y[i];\n        human_x[i]--;\n        human_y[i]--;\n    }\n\n    bool blocked[30][30] = {false};\n\n    for (int turn = 0; turn < 300; turn++) {\n        string action_string = \"\";\n        vector<char> actions(M, '.');\n\n        for (int i = 0; i < M; i++) {\n            int hx = human_x[i], hy = human_y[i];\n            int best_dist = 1000;\n            int best_pet = -1;\n            for (int j = 0; j < N; j++) {\n                int dist = abs(hx - pet_x[j]) + abs(hy - pet_y[j]);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pet = j;\n                }\n            }\n\n            if (best_dist <= 3 && best_pet != -1) {\n                int px = pet_x[best_pet], py = pet_y[best_pet];\n                int dx = px - hx;\n                int dy = py - hy;\n                int block_x = hx, block_y = hy;\n                if (abs(dx) > abs(dy)) {\n                    block_x += (dx > 0 ? 1 : -1);\n                } else {\n                    block_y += (dy > 0 ? 1 : -1);\n                }\n                if (block_x >= 0 && block_x < 30 && block_y >= 0 && block_y < 30) {\n                    bool occupied = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == block_x && pet_y[j] == block_y) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    if (!occupied) {\n                        for (int j = 0; j < M; j++) {\n                            if (human_x[j] == block_x && human_y[j] == block_y) {\n                                occupied = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (!occupied) {\n                        bool adjacent_pet = false;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = block_x + dx4[d];\n                            int ny = block_y + dy4[d];\n                            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                            for (int j = 0; j < N; j++) {\n                                if (pet_x[j] == nx && pet_y[j] == ny) {\n                                    adjacent_pet = true;\n                                    break;\n                                }\n                            }\n                            if (adjacent_pet) break;\n                        }\n                        if (!adjacent_pet) {\n                            if (block_x == hx - 1) actions[i] = 'u';\n                            else if (block_x == hx + 1) actions[i] = 'd';\n                            else if (block_y == hy - 1) actions[i] = 'l';\n                            else if (block_y == hy + 1) actions[i] = 'r';\n                        }\n                    }\n                }\n                if (actions[i] == '.') {\n                    if (abs(dx) > abs(dy)) {\n                        if (dx > 0) actions[i] = 'U';\n                        else actions[i] = 'D';\n                    } else {\n                        if (dy > 0) actions[i] = 'L';\n                        else actions[i] = 'R';\n                    }\n                    int nx = hx, ny = hy;\n                    if (actions[i] == 'U') nx--;\n                    else if (actions[i] == 'D') nx++;\n                    else if (actions[i] == 'L') ny--;\n                    else if (actions[i] == 'R') ny++;\n                    if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30 || blocked[nx][ny]) {\n                        actions[i] = '.';\n                    } else {\n                        bool has_pet = false;\n                        for (int j = 0; j < N; j++) {\n                            if (pet_x[j] == nx && pet_y[j] == ny) {\n                                has_pet = true;\n                                break;\n                            }\n                        }\n                        if (has_pet) {\n                            actions[i] = '.';\n                        }\n                    }\n                }\n            } else {\n                int target_x = 14, target_y = 14;\n                int dx = target_x - hx;\n                int dy = target_y - hy;\n                if (abs(dx) > abs(dy)) {\n                    if (dx > 0) actions[i] = 'D';\n                    else actions[i] = 'U';\n                } else {\n                    if (dy > 0) actions[i] = 'R';\n                    else actions[i] = 'L';\n                }\n                int nx = hx, ny = hy;\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30 || blocked[nx][ny]) {\n                    actions[i] = '.';\n                } else {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (has_pet) {\n                        actions[i] = '.';\n                    }\n                }\n            }\n            action_string += actions[i];\n        }\n\n        cout << action_string << endl;\n        cout.flush();\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u' || actions[i] == 'd' || actions[i] == 'l' || actions[i] == 'r') {\n                int bx = human_x[i];\n                int by = human_y[i];\n                if (actions[i] == 'u') bx--;\n                else if (actions[i] == 'd') bx++;\n                else if (actions[i] == 'l') by--;\n                else if (actions[i] == 'r') by++;\n                if (bx >= 0 && bx < 30 && by >= 0 && by < 30) {\n                    blocked[bx][by] = true;\n                }\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U' || actions[i] == 'D' || actions[i] == 'L' || actions[i] == 'R') {\n                int nx = human_x[i];\n                int ny = human_y[i];\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx >= 0 && nx < 30 && ny >= 0 && ny < 30 && !blocked[nx][ny]) {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (!has_pet) {\n                        human_x[i] = nx;\n                        human_y[i] = ny;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            string move_str;\n            cin >> move_str;\n            if (move_str == \".\") continue;\n            for (char c : move_str) {\n                if (c == 'U') pet_x[i]--;\n                else if (c == 'D') pet_x[i]++;\n                else if (c == 'L') pet_y[i]--;\n                else if (c == 'R') pet_y[i]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <tuple>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int s_i, s_j, t_i, t_j;\n    double p;\n    cin >> s_i >> s_j >> t_i >> t_j >> p;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n\n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n\n    vector<vector<int>> dist(20, vector<int>(20, INT_MAX));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move_char(20, vector<char>(20, ' '));\n\n    queue<pair<int, int>> q;\n    dist[s_i][s_j] = 0;\n    q.push({s_i, s_j});\n\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (i == t_i && j == t_j) break;\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 >= 20 || nj < 0 || nj >= 20) continue;\n\n            bool canMove = true;\n            if (d == 0) {\n                if (i == 0) canMove = false;\n                else if (v[i-1][j] == '1') canMove = false;\n            } else if (d == 1) {\n                if (i == 19) canMove = false;\n                else if (v[i][j] == '1') canMove = false;\n            } else if (d == 2) {\n                if (j == 0) canMove = false;\n                else if (h[i][j-1] == '1') canMove = false;\n            } else if (d == 3) {\n                if (j == 19) canMove = false;\n                else if (h[i][j] == '1') canMove = false;\n            }\n\n            if (canMove && dist[ni][nj] == INT_MAX) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent[ni][nj] = {i, j};\n                move_char[ni][nj] = dir_char[d];\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    string path = \"\";\n    int i = t_i, j = t_j;\n    while (i != s_i || j != s_j) {\n        path += move_char[i][j];\n        auto [pi, pj] = parent[i][j];\n        i = pi;\n        j = pj;\n    }\n    reverse(path.begin(), path.end());\n\n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n\n    int L0 = path.size();\n    int r = 200 / L0;\n    if (r < 1) r = 1;\n\n    string result = \"\";\n    for (char c : path) {\n        for (int i = 0; i < r; i++) {\n            result += c;\n        }\n    }\n\n    if (result.size() > 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 di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nconst int base_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 to_table[8][4][4];\n\nvoid precompute_to_table() {\n    for (int t = 0; t < 8; t++) {\n        for (int r = 0; r < 4; r++) {\n            for (int d = 0; d < 4; d++) {\n                int s_in_orig = (d + r) % 4;\n                int s_out_orig = base_to[t][s_in_orig];\n                if (s_out_orig == -1) {\n                    to_table[t][r][d] = -1;\n                } else {\n                    to_table[t][r][d] = (s_out_orig - r + 4) % 4;\n                }\n            }\n        }\n    }\n}\n\nlong long compute_score(const vector<vector<int>>& grid, const vector<vector<int>>& rotations) {\n    bool visited[30][30][4] = {};\n    vector<long long> cycles;\n\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int si = i, sj = j, sd = d;\n                    int ci = i, cj = j, cd = d;\n                    long long steps = 0;\n                    bool is_cycle = false;\n                    while (true) {\n                        if (visited[ci][cj][cd]) {\n                            break;\n                        }\n                        visited[ci][cj][cd] = true;\n                        int t = grid[ci][cj];\n                        int r = rotations[ci][cj];\n                        int d2 = to_table[t][r][cd];\n                        if (d2 == -1) {\n                            break;\n                        }\n                        int ni = ci + di[d2];\n                        int nj = cj + dj[d2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            break;\n                        }\n                        int nd = (d2 + 2) % 4;\n                        ci = ni;\n                        cj = nj;\n                        cd = nd;\n                        steps++;\n                        if (ci == si && cj == sj && cd == sd) {\n                            is_cycle = true;\n                            break;\n                        }\n                    }\n                    if (is_cycle) {\n                        cycles.push_back(steps);\n                    }\n                }\n            }\n        }\n    }\n\n    if (cycles.size() < 2) {\n        return 0;\n    }\n    sort(cycles.rbegin(), cycles.rend());\n    return cycles[0] * cycles[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    precompute_to_table();\n    const int num_test_cases = 100;\n\n    random_device rd;\n    mt19937 base_rng(rd());\n\n    for (int tc = 0; tc < num_test_cases; tc++) {\n        vector<vector<int>> grid(30, vector<int>(30));\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                cin >> grid[i][j];\n            }\n        }\n\n        mt19937 rng(base_rng());\n        vector<vector<int>> rotations(30, vector<int>(30));\n        uniform_int_distribution<int> dist(0, 3);\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                rotations[i][j] = dist(rng);\n            }\n        }\n\n        long long current_score = compute_score(grid, rotations);\n\n        int num_passes = 1;\n        for (int pass = 0; pass < num_passes; pass++) {\n            vector<pair<int, int>> tiles;\n            for (int i = 0; i < 30; i++) {\n                for (int j = 0; j < 30; j++) {\n                    tiles.push_back({i, j});\n                }\n            }\n            shuffle(tiles.begin(), tiles.end(), rng);\n\n            for (auto [i, j] : tiles) {\n                int best_rot = rotations[i][j];\n                long long best_score = current_score;\n                int orig_rot = rotations[i][j];\n\n                for (int r = 0; r < 4; r++) {\n                    if (r == orig_rot) continue;\n                    rotations[i][j] = r;\n                    long long score = compute_score(grid, rotations);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_rot = r;\n                    }\n                }\n\n                if (best_rot != orig_rot) {\n                    rotations[i][j] = best_rot;\n                    current_score = best_score;\n                } else {\n                    rotations[i][j] = orig_rot;\n                }\n            }\n        }\n\n        string output;\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                output += ('0' + rotations[i][j]);\n            }\n        }\n        cout << output << endl;\n    }\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\nusing namespace std;\n\nint compute_largest_component(vector<vector<int>>& board) {\n    int N = board.size();\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int largest = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] != 0 && !visited[i][j]) {\n                int count = 0;\n                queue<pair<int,int>> q;\n                q.push({i,j});\n                visited[i][j] = true;\n                while (!q.empty()) {\n                    auto [x,y] = q.front(); q.pop();\n                    count++;\n                    // Check up\n                    if (x-1 >= 0 && board[x-1][y] != 0 && !visited[x-1][y]) {\n                        if ((board[x][y] & 2) && (board[x-1][y] & 8)) {\n                            visited[x-1][y] = true;\n                            q.push({x-1,y});\n                        }\n                    }\n                    // Check down\n                    if (x+1 < N && board[x+1][y] != 0 && !visited[x+1][y]) {\n                        if ((board[x][y] & 8) && (board[x+1][y] & 2)) {\n                            visited[x+1][y] = true;\n                            q.push({x+1,y});\n                        }\n                    }\n                    // Check left\n                    if (y-1 >= 0 && board[x][y-1] != 0 && !visited[x][y-1]) {\n                        if ((board[x][y] & 1) && (board[x][y-1] & 4)) {\n                            visited[x][y-1] = true;\n                            q.push({x,y-1});\n                        }\n                    }\n                    // Check right\n                    if (y+1 < N && board[x][y+1] != 0 && !visited[x][y+1]) {\n                        if ((board[x][y] & 4) && (board[x][y+1] & 1)) {\n                            visited[x][y+1] = true;\n                            q.push({x,y+1});\n                        }\n                    }\n                }\n                if (count > largest) largest = count;\n            }\n        }\n    }\n    return largest;\n}\n\nint main() {\n    int N, T;\n    cin >> N >> T;\n    vector<vector<int>> board(N, vector<int>(N));\n    int empty_i = -1, empty_j = -1;\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            char c = s[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = 10 + c - 'a';\n            }\n            if (board[i][j] == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n\n    string ans = \"\";\n    vector<int> di = {-1, 1, 0, 0};\n    vector<int> dj = {0, 0, -1, 1};\n    vector<char> dir_char = {'U', 'D', 'L', 'R'};\n\n    for (int t = 0; t < T; t++) {\n        int current_largest = compute_largest_component(board);\n        if (current_largest == N * N - 1) break;\n\n        int best_largest = -1;\n        int best_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            int ni = empty_i + di[d];\n            int nj = empty_j + dj[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            swap(board[empty_i][empty_j], board[ni][nj]);\n            int new_largest = compute_largest_component(board);\n            swap(board[empty_i][empty_j], board[ni][nj]);\n            if (new_largest > best_largest) {\n                best_largest = new_largest;\n                best_dir = d;\n            }\n        }\n        if (best_dir == -1) break;\n        int ni = empty_i + di[best_dir];\n        int nj = empty_j + dj[best_dir];\n        swap(board[empty_i][empty_j], board[ni][nj]);\n        empty_i = ni;\n        empty_j = nj;\n        ans += dir_char[best_dir];\n    }\n\n    cout << ans << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Line {\n    Point p1, p2;\n};\n\nbool passes_through(const Line& l, const Point& s) {\n    ll dx = l.p2.x - l.p1.x;\n    ll dy = l.p2.y - l.p1.y;\n    ll cross = dx * (s.y - l.p1.y) - dy * (s.x - l.p1.x);\n    return cross == 0;\n}\n\nbool parallel(const Line& l1, const Line& l2) {\n    ll dx1 = l1.p2.x - l1.p1.x;\n    ll dy1 = l1.p2.y - l1.p1.y;\n    ll dx2 = l2.p2.x - l2.p1.x;\n    ll dy2 = l2.p2.y - l2.p1.y;\n    return dx1 * dy2 == dx2 * dy1;\n}\n\nbool concurrent(const Line& l1, const Line& l2, const Line& l3) {\n    ll dx1 = l1.p2.x - l1.p1.x;\n    ll dy1 = l1.p2.y - l1.p1.y;\n    ll a1 = dy1;\n    ll b1 = -dx1;\n    ll c1 = dy1 * l1.p1.x - dx1 * l1.p1.y;\n\n    ll dx2 = l2.p2.x - l2.p1.x;\n    ll dy2 = l2.p2.y - l2.p1.y;\n    ll a2 = dy2;\n    ll b2 = -dx2;\n    ll c2 = dy2 * l2.p1.x - dx2 * l2.p1.y;\n\n    ll dx3 = l3.p2.x - l3.p1.x;\n    ll dy3 = l3.p2.y - l3.p1.y;\n    ll a3 = dy3;\n    ll b3 = -dx3;\n    ll c3 = dy3 * l3.p1.x - dx3 * l3.p1.y;\n\n    __int128 det = (__int128)a1 * b2 - (__int128)a2 * b1;\n    if (det == 0) return false;\n\n    __int128 left = (__int128)a3 * ((__int128)c1 * b2 - (__int128)c2 * b1) + (__int128)b3 * ((__int128)a1 * c2 - (__int128)a2 * c1);\n    __int128 right = (__int128)c3 * det;\n\n    return left == right;\n}\n\nLine generate_line() {\n    Line l;\n    l.p1.x = rand() % 2000000001 - 1000000000;\n    l.p1.y = rand() % 2000000001 - 1000000000;\n    l.p2.x = rand() % 2000000001 - 1000000000;\n    l.p2.y = rand() % 2000000001 - 1000000000;\n    while (l.p1.x == l.p2.x && l.p1.y == l.p2.y) {\n        l.p2.x = rand() % 2000000001 - 1000000000;\n        l.p2.y = rand() % 2000000001 - 1000000000;\n    }\n    return l;\n}\n\nint main() {\n    srand(time(0));\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    vector<Line> lines;\n    for (int i = 0; i < 100; i++) {\n        Line l;\n        bool valid = false;\n        while (!valid) {\n            l = generate_line();\n            bool through = false;\n            for (const Point& s : strawberries) {\n                if (passes_through(l, s)) {\n                    through = true;\n                    break;\n                }\n            }\n            if (through) continue;\n\n            bool is_parallel = false;\n            for (const Line& existing : lines) {\n                if (parallel(existing, l)) {\n                    is_parallel = true;\n                    break;\n                }\n            }\n            if (is_parallel) continue;\n\n            bool is_concurrent = false;\n            for (int j = 0; j < (int)lines.size(); j++) {\n                for (int k = j + 1; k < (int)lines.size(); k++) {\n                    if (concurrent(lines[j], lines[k], l)) {\n                        is_concurrent = true;\n                        break;\n                    }\n                }\n                if (is_concurrent) break;\n            }\n            if (is_concurrent) continue;\n            valid = true;\n        }\n        lines.push_back(l);\n    }\n\n    map<string, int> piece_count;\n    for (const Point& s : strawberries) {\n        string key;\n        for (const Line& l : lines) {\n            ll dx = l.p2.x - l.p1.x;\n            ll dy = l.p2.y - l.p1.y;\n            ll cross = dx * (s.y - l.p1.y) - dy * (s.x - l.p1.x);\n            key += (cross > 0) ? '1' : '0';\n        }\n        piece_count[key]++;\n    }\n\n    vector<int> b(11, 0);\n    for (const auto& p : piece_count) {\n        int size = p.second;\n        if (size >= 1 && size <= 10) {\n            b[size]++;\n        }\n    }\n\n    cout << lines.size() << endl;\n    for (const Line& l : lines) {\n        cout << l.p1.x << \" \" << l.p1.y << \" \" << l.p2.x << \" \" << l.p2.y << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <unordered_set>\n#include <queue>\nusing namespace std;\n\nusing Point = pair<int, int>;\nusing Segment = pair<Point, Point>;\n\nstruct Candidate {\n    Point new_dot;\n    vector<Point> existing;\n    int type; // 0: axis-aligned, 1: 45-degree square\n    int weight;\n};\n\nSegment make_segment(Point a, Point b) {\n    if (a < b) {\n        return {a, b};\n    } else {\n        return {b, a};\n    }\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<Point> initial_dots;\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> row_set(N);\n    vector<set<int>> col_set(N);\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initial_dots.push_back({x, y});\n        grid[x][y] = true;\n        row_set[y].insert(x);\n        col_set[x].insert(y);\n    }\n\n    int c = (N-1)/2;\n    auto weight_func = [c](int x, int y) {\n        int dx = x - c;\n        int dy = y - c;\n        return dx*dx + dy*dy + 1;\n    };\n\n    set<Segment> drawn_segments;\n    vector<vector<int>> operations;\n\n    int max_operations = 10000;\n    int K_top = 1000;\n\n    for (int iter = 0; iter < max_operations; iter++) {\n        vector<Candidate> candidates;\n\n        for (int y = 0; y < N; y++) {\n            if (row_set[y].size() < 2) continue;\n            vector<int> xs(row_set[y].begin(), row_set[y].end());\n            sort(xs.begin(), xs.end());\n            for (int i = 0; i < xs.size(); i++) {\n                for (int j = i+1; j < xs.size(); j++) {\n                    int x1 = xs[i], x2 = xs[j];\n                    for (int y1 : col_set[x1]) {\n                        if (y1 == y) continue;\n                        if (!grid[x2][y1]) {\n                            Point new_dot = {x2, y1};\n                            vector<Point> existing = {{x1,y}, {x2,y}, {x1,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                    for (int y1 : col_set[x2]) {\n                        if (y1 == y) continue;\n                        if (!grid[x1][y1]) {\n                            Point new_dot = {x1, y1};\n                            vector<Point> existing = {{x1,y}, {x2,y}, {x2,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            if (col_set[x].size() < 2) continue;\n            vector<int> ys(col_set[x].begin(), col_set[x].end());\n            sort(ys.begin(), ys.end());\n            for (int i = 0; i < ys.size(); i++) {\n                for (int j = i+1; j < ys.size(); j++) {\n                    int y1 = ys[i], y2 = ys[j];\n                    for (int x1 : row_set[y1]) {\n                        if (x1 == x) continue;\n                        if (!grid[x1][y2]) {\n                            Point new_dot = {x1, y2};\n                            vector<Point> existing = {{x,y1}, {x,y2}, {x1,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                    for (int x1 : row_set[y2]) {\n                        if (x1 == x) continue;\n                        if (!grid[x1][y1]) {\n                            Point new_dot = {x1, y1};\n                            vector<Point> existing = {{x,y1}, {x,y2}, {x1,y2}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y]) continue;\n                int w = weight_func(x, y);\n                for (int type = 0; type < 4; type++) {\n                    if (type == 0) {\n                        int a_max = min({x, N-1-x, y/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x+a, y-a};\n                            Point C = {x, y-2*a};\n                            Point D = {x-a, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 1) {\n                        int a_max = min({y, N-1-y, (N-1-x)/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x, y+a};\n                            Point C = {x+2*a, y};\n                            Point D = {x, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 2) {\n                        int a_max = min({N-1-x, N-1-y, (N-1-y)/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x+a, y+a};\n                            Point C = {x, y+2*a};\n                            Point D = {x-a, y+a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 3) {\n                        int a_max = min({y, N-1-y, x/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x, y+a};\n                            Point C = {x-2*a, y};\n                            Point D = {x, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (candidates.empty()) {\n            break;\n        }\n\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            return a.weight > b.weight;\n        });\n\n        if (candidates.size() > K_top) {\n            candidates.resize(K_top);\n        }\n\n        bool found_valid = false;\n        for (const Candidate& cand : candidates) {\n            Point new_dot = cand.new_dot;\n            vector<Point> existing = cand.existing;\n            int type = cand.type;\n\n            set<Point> corners = {new_dot, existing[0], existing[1], existing[2]};\n\n            bool condition2_ok = true;\n            vector<Point> perimeter_points;\n\n            if (type == 0) {\n                int x_min = new_dot.first;\n                int x_max = new_dot.first;\n                int y_min = new_dot.second;\n                int y_max = new_dot.second;\n                for (const Point& p : existing) {\n                    x_min = min(x_min, p.first);\n                    x_max = max(x_max, p.first);\n                    y_min = min(y_min, p.second);\n                    y_max = max(y_max, p.second);\n                }\n                for (int x = x_min; x <= x_max; x++) {\n                    perimeter_points.push_back({x, y_min});\n                    perimeter_points.push_back({x, y_max});\n                }\n                for (int y = y_min+1; y < y_max; y++) {\n                    perimeter_points.push_back({x_min, y});\n                    perimeter_points.push_back({x_max, y});\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = abs(dx);\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k <= steps; k++) {\n                        perimeter_points.push_back(current);\n                        if (k < steps) {\n                            current.first += sx;\n                            current.second += sy;\n                        }\n                    }\n                }\n            }\n\n            for (const Point& p : perimeter_points) {\n                if (corners.find(p) == corners.end() && grid[p.first][p.second]) {\n                    condition2_ok = false;\n                    break;\n                }\n            }\n            if (!condition2_ok) continue;\n\n            bool condition3_ok = true;\n            vector<Segment> new_segments;\n\n            if (type == 0) {\n                int x_min = new_dot.first;\n                int x_max = new_dot.first;\n                int y_min = new_dot.second;\n                int y_max = new_dot.second;\n                for (const Point& p : existing) {\n                    x_min = min(x_min, p.first);\n                    x_max = max(x_max, p.first);\n                    y_min = min(y_min, p.second);\n                    y_max = max(y_max, p.second);\n                }\n                for (int x = x_min; x < x_max; x++) {\n                    Segment seg = make_segment({x, y_min}, {x+1, y_min});\n                    new_segments.push_back(seg);\n                }\n                for (int x = x_min; x < x_max; x++) {\n                    Segment seg = make_segment({x, y_max}, {x+1, y_max});\n                    new_segments.push_back(seg);\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    Segment seg = make_segment({x_min, y}, {x_min, y+1});\n                    new_segments.push_back(seg);\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    Segment seg = make_segment({x_max, y}, {x_max, y+1});\n                    new_segments.push_back(seg);\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = abs(dx);\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k < steps; k++) {\n                        Point next = {current.first + sx, current.second + sy};\n                        Segment seg = make_segment(current, next);\n                        new_segments.push_back(seg);\n                        current = next;\n                    }\n                }\n            }\n\n            for (const Segment& seg : new_segments) {\n                if (drawn_segments.find(seg) != drawn_segments.end()) {\n                    condition3_ok = false;\n                    break;\n                }\n            }\n            if (!condition3_ok) continue;\n\n            for (const Segment& seg : new_segments) {\n                drawn_segments.insert(seg);\n            }\n            grid[new_dot.first][new_dot.second] = true;\n            row_set[new_dot.second].insert(new_dot.first);\n            col_set[new_dot.first].insert(new_dot.second);\n\n            vector<int> op;\n            op.push_back(new_dot.first);\n            op.push_back(new_dot.second);\n            for (const Point& p : existing) {\n                op.push_back(p.first);\n                op.push_back(p.second);\n            }\n            operations.push_back(op);\n\n            found_valid = true;\n            break;\n        }\n\n        if (!found_valid) {\n            break;\n        }\n    }\n\n    cout << operations.size() << endl;\n    for (const vector<int>& op : operations) {\n        for (int i = 0; i < op.size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nvector<vector<int>> tilt_grid(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> new_grid(10, vector<int>(10, 0));\n    if (dir == 'F') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 9;\n            for (int k = candies.size() - 1; k >= 0; k--) {\n                new_grid[idx][j] = candies[k];\n                idx--;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 0;\n            for (int k = 0; k < candies.size(); k++) {\n                new_grid[idx][j] = candies[k];\n                idx++;\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 0;\n            for (int k = 0; k < candies.size(); k++) {\n                new_grid[i][idx] = candies[k];\n                idx++;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 9;\n            for (int k = candies.size() - 1; k >= 0; k--) {\n                new_grid[i][idx] = candies[k];\n                idx--;\n            }\n        }\n    }\n    return new_grid;\n}\n\nint compute_components(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dx[4] = {1, -1, 0, 0};\n    int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0 && !visited[i][j]) {\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int flavor = grid[i][j];\n                int size = 0;\n\n                while (!q.empty()) {\n                    int x = q.front().first;\n                    int y = q.front().second;\n                    q.pop();\n                    size++;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x + dx[d];\n                        int ny = y + dy[d];\n                        if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n\n        int count = 0;\n        int i0 = -1, j0 = -1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == 0) {\n                    count++;\n                    if (count == p) {\n                        i0 = i;\n                        j0 = j;\n                        break;\n                    }\n                }\n            }\n            if (i0 != -1) break;\n        }\n\n        grid[i0][j0] = flavors[t];\n\n        int best_score = -1;\n        char best_dir = 'F';\n        string dirs = \"FBLR\";\n        for (char d : dirs) {\n            vector<vector<int>> temp_grid = grid;\n            vector<vector<int>> tilted = tilt_grid(temp_grid, d);\n            int score = compute_components(tilted);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        cout << best_dir << endl;\n\n        grid = tilt_grid(grid, best_dir);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\nusing namespace std;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    const int N = 20;\n    const int T = N * (N - 1) / 2;\n\n    double std_dev = sqrt(T * epsilon * (1 - epsilon));\n    double gap_needed = 3 * std_dev / (1 - 2 * epsilon);\n    int g = ceil(gap_needed);\n    if (g < 1) g = 1;\n\n    if (g * (M - 1) > T) {\n        g = T / (M - 1);\n        if (g < 1) g = 1;\n    }\n\n    vector<vector<int>> proto_degrees;\n    vector<vector<double>> proto_expected;\n\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        vector<int> deg(N, 0);\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (count < edge_count) {\n                    deg[i]++;\n                    deg[j]++;\n                    count++;\n                } else {\n                    break;\n                }\n            }\n            if (count >= edge_count) break;\n        }\n        sort(deg.begin(), deg.end());\n        proto_degrees.push_back(deg);\n\n        vector<double> expected(N);\n        for (int i = 0; i < N; i++) {\n            expected[i] = deg[i] * (1 - 2 * epsilon) + (N - 1) * epsilon;\n        }\n        proto_expected.push_back(expected);\n    }\n\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        string s = \"\";\n        int count_edges = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (count_edges < edge_count) {\n                    s += '1';\n                } else {\n                    s += '0';\n                }\n                count_edges++;\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        vector<int> obs_deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (s[idx] == '1') {\n                    obs_deg[i]++;\n                    obs_deg[j]++;\n                }\n                idx++;\n            }\n        }\n        sort(obs_deg.begin(), obs_deg.end());\n\n        if (g > 1) {\n            int e_obs = 0;\n            for (char c : s) {\n                if (c == '1') e_obs++;\n            }\n            double e0_est = (e_obs - T * epsilon) / (1 - 2 * epsilon);\n            if (e0_est < 0) e0_est = 0;\n            if (e0_est > T) e0_est = T;\n            int k_est = round(e0_est / g);\n            if (k_est < 0) k_est = 0;\n            if (k_est >= M) k_est = M - 1;\n            cout << k_est << endl;\n        } else {\n            double best_dist = 1e18;\n            int best_k = 0;\n            for (int k = 0; k < M; k++) {\n                double dist = 0.0;\n                for (int i = 0; i < N; i++) {\n                    double diff = obs_deg[i] - proto_expected[k][i];\n                    dist += diff * diff;\n                }\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_k = k;\n                }\n            }\n            cout << best_k << endl;\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long LL;\ntypedef long double LD;\n\nstruct Edge {\n    int to;\n    LL w;\n    int id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<tuple<int, int, LL>> edges;\n    vector<vector<Edge>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        LL w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges.push_back({u, v, w});\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<LD> betweenness(M, 0.0);\n\n    for (int s = 0; s < N; s++) {\n        vector<LL> dist(N, LLONG_MAX);\n        vector<LD> sigma(N, 0.0);\n        vector<vector<pair<int, int>>> pred(N);\n\n        priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<pair<LL, int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1;\n        pq.push({0, s});\n\n        while (!pq.empty()) {\n            LL d = pq.top().first;\n            int u = pq.top().second;\n            pq.pop();\n            if (d != dist[u]) continue;\n            for (const Edge &e : adj[u]) {\n                int v = e.to;\n                LL w = e.w;\n                LL nd = dist[u] + w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    sigma[v] = sigma[u];\n                    pred[v].clear();\n                    pred[v].push_back({u, e.id});\n                    pq.push({nd, v});\n                } else if (nd == dist[v]) {\n                    sigma[v] += sigma[u];\n                    pred[v].push_back({u, e.id});\n                }\n            }\n        }\n\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            if (dist[a] != dist[b])\n                return dist[a] > dist[b];\n            return a > b;\n        });\n\n        vector<LD> delta(N, 0.0);\n        for (int i = 0; i < N; i++) {\n            int v = order[i];\n            if (dist[v] == LLONG_MAX) continue;\n            if (v == s) continue;\n            for (auto &p : pred[v]) {\n                int u = p.first;\n                int eid = p.second;\n                if (sigma[v] == 0) continue;\n                LD contrib = (sigma[u] / sigma[v]) * (1.0 + delta[v]);\n                delta[u] += contrib;\n                betweenness[eid] += contrib;\n            }\n        }\n    }\n\n    vector<LD> cost(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, w] = edges[i];\n        cost[i] = betweenness[i] * (LD)w;\n    }\n\n    vector<pair<LD, int>> sorted_edges;\n    for (int i = 0; i < M; i++) {\n        sorted_edges.push_back({cost[i], i});\n    }\n    sort(sorted_edges.rbegin(), sorted_edges.rend());\n\n    vector<LD> total_cost(D, 0.0);\n    vector<int> count(D, 0);\n    vector<int> ans(M, -1);\n\n    for (auto &p : sorted_edges) {\n        LD c = p.first;\n        int eid = p.second;\n        int best_day = -1;\n        LD min_cost = 1e30;\n        for (int d = 0; d < D; d++) {\n            if (count[d] < K) {\n                if (total_cost[d] < min_cost) {\n                    min_cost = total_cost[d];\n                    best_day = d;\n                }\n            }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if (count[d] < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n            if (best_day == -1) {\n                best_day = 0;\n            }\n        }\n        ans[eid] = best_day;\n        total_cost[best_day] += c;\n        count[best_day]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << \" \";\n        cout << ans[i] + 1;\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> is_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\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                bool in1 = (f1[z][x] == '1' && r1[z][y] == '1');\n                bool in2 = (f2[z][x] == '1' && r2[z][y] == '1');\n                if (in1 && in2) {\n                    is_common[x][y][z] = true;\n                } else if (in1) {\n                    is_only1[x][y][z] = true;\n                } else if (in2) {\n                    is_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<int>>> block1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> block2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    int next_block_id = 1;\n    vector<int> dx = {1, -1, 0, 0, 0, 0};\n    vector<int> dy = {0, 0, 1, -1, 0, 0};\n    vector<int> dz = {0, 0, 0, 0, 1, -1};\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 (is_common[x][y][z] && !visited[x][y][z]) {\n                    queue<tuple<int, int, int>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    block1[x][y][z] = next_block_id;\n                    block2[x][y][z] = next_block_id;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D) {\n                                if (is_common[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                    visited[nx][ny][nz] = true;\n                                    block1[nx][ny][nz] = next_block_id;\n                                    block2[nx][ny][nz] = next_block_id;\n                                    q.push({nx, ny, nz});\n                                }\n                            }\n                        }\n                    }\n                    next_block_id++;\n                }\n            }\n        }\n    }\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 (is_only1[x][y][z]) {\n                    block1[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n                if (is_only2[x][y][z]) {\n                    block2[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n            }\n        }\n    }\n\n    cout << next_block_id - 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 << block1[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 << block2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstring>\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nconst double INF = 1e18;\nconst int MAXN = 100;\nconst int MAXM = 300;\nconst int MAXK = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nvector<pii> edges;\nint w[MAXM];\ndouble resident_x[MAXK], resident_y[MAXK];\n\nvector<pair<int, int>> adj[MAXN];\ndouble dist_2d[MAXN][MAXN];\nint parent_2d[MAXN][MAXN];\n\nint best_node[MAXK];\ndouble min_dist[MAXK];\n\nvector<int> T_list;\ndouble d_T[MAXK];\nbool inT[MAXN];\n\nvector<pii> MST_edges;\n\nmap<pii, int> edge_index_map;\n\ndouble euclid(double x1, double y1, double x2, double y2) {\n    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));\n}\n\nvoid dijkstra(int src) {\n    for (int i = 0; i < N; i++) {\n        dist_2d[src][i] = INF;\n        parent_2d[src][i] = -1;\n    }\n    dist_2d[src][src] = 0;\n    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n    pq.push({0, src});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n        if (d != dist_2d[src][u]) continue;\n        for (auto &edge : adj[u]) {\n            int v = edge.first;\n            int weight = edge.second;\n            double new_d = d + weight;\n            if (new_d < dist_2d[src][v]) {\n                dist_2d[src][v] = new_d;\n                parent_2d[src][v] = u;\n                pq.push({new_d, v});\n            }\n        }\n    }\n}\n\nvector<int> get_path(int src, int dest) {\n    vector<int> path;\n    if (dist_2d[src][dest] >= INF) return path;\n    int cur = dest;\n    while (cur != src) {\n        path.push_back(cur);\n        cur = parent_2d[src][cur];\n    }\n    path.push_back(src);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstruct Edge {\n    int u, v;\n    double weight;\n    bool operator<(const Edge& other) const {\n        return weight < other.weight;\n    }\n};\n\nvector<int> parent_kruskal;\n\nint find_set(int v) {\n    if (v == parent_kruskal[v]) return v;\n    return parent_kruskal[v] = find_set(parent_kruskal[v]);\n}\n\nbool union_sets(int a, int b) {\n    a = find_set(a);\n    b = find_set(b);\n    if (a == b) return false;\n    parent_kruskal[b] = a;\n    return true;\n}\n\nvoid build_MST_on_T() {\n    int t_size = T_list.size();\n    map<int, int> comp;\n    for (int i = 0; i < t_size; i++) {\n        comp[T_list[i]] = i;\n    }\n\n    vector<Edge> edges_complete;\n    for (int i = 0; i < t_size; i++) {\n        for (int j = i+1; j < t_size; j++) {\n            int u = T_list[i];\n            int v = T_list[j];\n            double d = dist_2d[u][v];\n            edges_complete.push_back({u, v, d});\n        }\n    }\n\n    sort(edges_complete.begin(), edges_complete.end());\n\n    parent_kruskal.resize(t_size);\n    for (int i = 0; i < t_size; i++) parent_kruskal[i] = i;\n\n    MST_edges.clear();\n    for (const Edge& e : edges_complete) {\n        int u_comp = comp[e.u];\n        int v_comp = comp[e.v];\n        if (union_sets(u_comp, v_comp)) {\n            MST_edges.push_back({e.u, e.v});\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> K;\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    for (int j = 0; j < M; j++) {\n        int u, v, weight;\n        cin >> u >> v >> weight;\n        u--; v--;\n        edges.push_back({u, v});\n        w[j] = weight;\n        adj[u].push_back({v, weight});\n        adj[v].push_back({u, weight});\n        int a = min(u, v);\n        int b = max(u, v);\n        edge_index_map[{a, b}] = j;\n    }\n    for (int k = 0; k < K; k++) {\n        cin >> resident_x[k] >> resident_y[k];\n    }\n\n    for (int i = 0; i < N; i++) {\n        dijkstra(i);\n    }\n\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best = -1;\n        for (int i = 0; i < N; i++) {\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d < min_d) {\n                min_d = d;\n                best = i;\n            }\n        }\n        best_node[k] = best;\n        min_dist[k] = min_d;\n    }\n\n    memset(inT, 0, sizeof(inT));\n    T_list.clear();\n    T_list.push_back(0);\n    inT[0] = true;\n\n    for (int k = 0; k < K; k++) {\n        d_T[k] = euclid(resident_x[k], resident_y[k], x[0], y[0]);\n    }\n\n    set<int> uncovered;\n    for (int k = 0; k < K; k++) {\n        uncovered.insert(k);\n    }\n\n    while (!uncovered.empty()) {\n        int k0 = -1;\n        double max_d = -1;\n        for (int k : uncovered) {\n            if (d_T[k] > max_d) {\n                max_d = d_T[k];\n                k0 = k;\n            }\n        }\n        if (d_T[k0] <= 5000) {\n            uncovered.erase(k0);\n            continue;\n        }\n        int i = best_node[k0];\n        if (!inT[i]) {\n            T_list.push_back(i);\n            inT[i] = true;\n            for (int k = 0; k < K; k++) {\n                double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n                if (d < d_T[k]) {\n                    d_T[k] = d;\n                }\n            }\n        }\n        vector<int> to_remove;\n        for (int k : uncovered) {\n            if (d_T[k] <= 5000) {\n                to_remove.push_back(k);\n            }\n        }\n        for (int k : to_remove) {\n            uncovered.erase(k);\n        }\n    }\n\n    if (T_list.size() > 1) {\n        build_MST_on_T();\n    } else {\n        MST_edges.clear();\n    }\n\n    set<int> activated_edges;\n\n    for (auto &e : MST_edges) {\n        int u = e.first;\n        int v = e.second;\n        vector<int> path = get_path(u, v);\n        for (int idx = 0; idx < (int)path.size()-1; idx++) {\n            int a = path[idx];\n            int b = path[idx+1];\n            int aa = min(a, b);\n            int bb = max(a, b);\n            auto key = make_pair(aa, bb);\n            if (edge_index_map.find(key) != edge_index_map.end()) {\n                int j = edge_index_map[key];\n                activated_edges.insert(j);\n            }\n        }\n    }\n\n    vector<bool> inV_prime(N, false);\n    vector<vector<int>> adj_steiner(N);\n    for (int j : activated_edges) {\n        int u = edges[j].first;\n        int v = edges[j].second;\n        adj_steiner[u].push_back(v);\n        adj_steiner[v].push_back(u);\n    }\n    queue<int> q;\n    q.push(0);\n    inV_prime[0] = true;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj_steiner[u]) {\n            if (!inV_prime[v]) {\n                inV_prime[v] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    vector<int> V_prime;\n    for (int i = 0; i < N; i++) {\n        if (inV_prime[i]) {\n            V_prime.push_back(i);\n        }\n    }\n\n    vector<double> max_dist_node(N, 0.0);\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best_i = -1;\n        for (int i : V_prime) {\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d < min_d) {\n                min_d = d;\n                best_i = i;\n            }\n        }\n        if (best_i != -1) {\n            if (min_d > max_dist_node[best_i]) {\n                max_dist_node[best_i] = min_d;\n            }\n        }\n    }\n\n    vector<int> P(N, 0);\n    for (int i = 0; i < N; i++) {\n        if (inV_prime[i]) {\n            if (max_dist_node[i] > 0) {\n                double d = max_dist_node[i];\n                int ceil_d = ceil(d);\n                if (ceil_d > 5000) ceil_d = 5000;\n                P[i] = ceil_d;\n            } else {\n                P[i] = 0;\n            }\n        } else {\n            P[i] = 0;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << endl;\n\n    vector<int> B(M, 0);\n    for (int j = 0; j < M; j++) {\n        if (activated_edges.find(j) != activated_edges.end()) {\n            B[j] = 1;\n        }\n        if (j > 0) cout << \" \";\n        cout << B[j];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N = 30;\n    vector<vector<int>> grid(N);\n    for (int x = 0; x < N; x++) {\n        grid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> grid[x][y];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n    int K = 0;\n\n    while (K < 10000) {\n        bool any_swap = false;\n        for (int x = 0; x < N-1; x++) {\n            for (int y = 0; y <= x; y++) {\n                int left_child = grid[x+1][y];\n                int right_child = grid[x+1][y+1];\n                if (grid[x][y] > left_child || grid[x][y] > right_child) {\n                    if (left_child < right_child) {\n                        swap(grid[x][y], grid[x+1][y]);\n                        swaps.push_back({x, y, x+1, y});\n                    } else {\n                        swap(grid[x][y], grid[x+1][y+1]);\n                        swaps.push_back({x, y, x+1, y+1});\n                    }\n                    K++;\n                    any_swap = true;\n                }\n            }\n        }\n        if (!any_swap) break;\n    }\n\n    cout << K << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <utility>\nusing namespace std;\n\nconst int MAX_D = 9;\nconst int entrance_i = 0;\nconst int entrance_j = 4;\nint dx[4] = {1, -1, 0, 0};\nint dy[4] = {0, 0, 1, -1};\n\nint main() {\n    int D, N;\n    cin >> D >> N;\n    bool obstacle[MAX_D][MAX_D] = {false};\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N;\n    bool occupied[MAX_D][MAX_D] = {false};\n    int container_number[MAX_D][MAX_D];\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            container_number[i][j] = -1;\n        }\n    }\n\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n\n        vector<vector<int>> dist(MAX_D, vector<int>(MAX_D, -1));\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                        dist[ni][nj] = dist[i][j] + 1;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> available;\n        for (int i = 0; i < MAX_D; i++) {\n            for (int j = 0; j < MAX_D; j++) {\n                if (dist[i][j] != -1 && !(i == entrance_i && j == entrance_j)) {\n                    available.push_back({i, j});\n                }\n            }\n        }\n\n        sort(available.begin(), available.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            if (dist[a.first][a.second] != dist[b.first][b.second]) {\n                return dist[a.first][a.second] < dist[b.first][b.second];\n            }\n            if (a.first != b.first) {\n                return a.first < b.first;\n            }\n            return a.second < b.second;\n        });\n\n        if (available.empty()) {\n            continue;\n        }\n\n        int k = (t * available.size()) / M;\n        auto chosen = available[k];\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n\n        occupied[chosen.first][chosen.second] = true;\n        container_number[chosen.first][chosen.second] = t;\n    }\n\n    vector<vector<bool>> empty(MAX_D, vector<bool>(MAX_D, false));\n    empty[entrance_i][entrance_j] = true;\n\n    vector<pair<int, int>> containers;\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            if (occupied[i][j]) {\n                containers.push_back({i, j});\n            }\n        }\n    }\n\n    vector<pair<int, int>> removal_order;\n\n    while (!containers.empty()) {\n        vector<vector<bool>> visited(MAX_D, vector<bool>(MAX_D, false));\n        queue<pair<int, int>> q;\n        q.push({entrance_i, entrance_j});\n        visited[entrance_i][entrance_j] = true;\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && empty[ni][nj] && !visited[ni][nj]) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<int> removable_indices;\n        for (int idx = 0; idx < containers.size(); idx++) {\n            auto [i, j] = containers[idx];\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (visited[ni][nj]) {\n                        removable_indices.push_back(idx);\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (removable_indices.empty()) {\n            break;\n        }\n\n        int min_num = 1000000;\n        int best_idx = -1;\n        for (int idx : removable_indices) {\n            auto [i, j] = containers[idx];\n            int num = container_number[i][j];\n            if (num < min_num) {\n                min_num = num;\n                best_idx = idx;\n            }\n        }\n\n        auto coord = containers[best_idx];\n        removal_order.push_back(coord);\n        empty[coord.first][coord.second] = true;\n        swap(containers[best_idx], containers.back());\n        containers.pop_back();\n    }\n\n    for (auto [i, j] : removal_order) {\n        cout << i << \" \" << j << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c;\n            cin >> c;\n            cout << c;\n            if (j < n-1) cout << \" \";\n        }\n        cout << endl;\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    vector<int> score(N, 0);\n    vector<vector<int>> compared(N, vector<int>(N, 0));\n    \n    for (int q = 0; q < Q; q++) {\n        int i_min = -1, j_min = -1;\n        int min_count = 1e9;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (compared[i][j] < min_count) {\n                    min_count = compared[i][j];\n                    i_min = i;\n                    j_min = j;\n                }\n            }\n        }\n        cout << \"1 1 \" << i_min << \" \" << j_min << endl;\n        cout.flush();\n        string res;\n        cin >> res;\n        if (res == \">\") {\n            score[i_min] += 1;\n            score[j_min] -= 1;\n        } else if (res == \"<\") {\n            score[i_min] -= 1;\n            score[j_min] += 1;\n        }\n        compared[i_min][j_min]++;\n        compared[j_min][i_min]++;\n    }\n    \n    vector<int> items(N);\n    for (int i = 0; i < N; i++) items[i] = i;\n    sort(items.begin(), items.end(), [&](int a, int b) {\n        return score[a] > score[b];\n    });\n    \n    vector<int> set_weights(D, 0);\n    vector<int> assignment(N);\n    for (int item : items) {\n        int min_set = 0;\n        for (int d = 1; d < D; d++) {\n            if (set_weights[d] < set_weights[min_set]) {\n                min_set = d;\n            }\n        }\n        assignment[item] = min_set;\n        set_weights[min_set] += score[item];\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cout.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    int per_stack = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < per_stack; ++j) {\n            int x;\n            cin >> x;\n            stacks[i].push_back(x);   // bottom to top\n        }\n    }\n\n    // arrays to store position of each box\n    vector<int> stack_of(n + 1, -1);\n    vector<int> idx_in_stack(n + 1, -1);\n\n    // function to recompute positions\n    auto recompute = [&]() {\n        fill(stack_of.begin(), stack_of.end(), -1);\n        fill(idx_in_stack.begin(), idx_in_stack.end(), -1);\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                int box = stacks[i][j];\n                stack_of[box] = i;\n                idx_in_stack[box] = j;\n            }\n        }\n    };\n\n    vector<pair<int, int>> ops;\n    int op_count = 0;\n\n    for (int v = 1; v <= n; ++v) {\n        recompute();\n        int s = stack_of[v];\n        int i = idx_in_stack[v];\n\n        // if v is already on top, carry out\n        if (i == (int)stacks[s].size() - 1) {\n            ops.emplace_back(v, 0);\n            ++op_count;\n            stacks[s].pop_back();\n            continue;\n        }\n\n        // otherwise, move boxes above v one by one\n        while (true) {\n            recompute();\n            s = stack_of[v];\n            i = idx_in_stack[v];\n            if (i == (int)stacks[s].size() - 1) break;   // v is now top\n\n            int w = stacks[s].back();   // current top box\n\n            // choose destination stack t (0\u2011based)\n            int t = -1;\n            vector<int> empty, good, other;\n            for (int idx = 0; idx < m; ++idx) {\n                if (idx == s) continue;\n                if (stacks[idx].empty()) {\n                    empty.push_back(idx);\n                } else if (stacks[idx].back() > w) {\n                    good.push_back(idx);\n                } else {\n                    other.push_back(idx);\n                }\n            }\n\n            if (!empty.empty()) {\n                t = empty[0];   // prefer empty stack\n            } else if (!good.empty()) {\n                // choose stack with smallest top > w\n                int best_top = 1e9;\n                for (int idx : good) {\n                    int top = stacks[idx].back();\n                    if (top < best_top) {\n                        best_top = top;\n                        t = idx;\n                    }\n                }\n            } else if (!other.empty()) {\n                // fallback: choose stack with largest top (< w)\n                int best_top = -1;\n                for (int idx : other) {\n                    int top = stacks[idx].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        t = idx;\n                    }\n                }\n            } else {\n                // should not happen (m>=2), but fallback\n                t = (s + 1) % m;\n            }\n\n            // output move operation (convert to 1\u2011based stack index)\n            ops.emplace_back(w, t + 1);\n            ++op_count;\n\n            // perform the move\n            stacks[s].pop_back();\n            stacks[t].push_back(w);\n        }\n\n        // v is now on top, carry out\n        ops.emplace_back(v, 0);\n        ++op_count;\n        stacks[s].pop_back();   // remove v\n    }\n\n    // output all operations\n    for (auto &p : ops) {\n        cout << p.first << \" \" << p.second << \"\\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;\nvector<vector<bool>> visited;\nstring moves = \"\";\n\n// Direction vectors: right, down, left, up\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'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    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check walls based on direction\n    if (dir == 0) { // right\n        return v[i][j] == '0';\n    } else if (dir == 1) { // down\n        return h[i][j] == '0';\n    } else if (dir == 2) { // left\n        return j > 0 && v[i][j-1] == '0';\n    } else { // up\n        return i > 0 && h[i-1][j] == '0';\n    }\n}\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    \n    // Collect all possible moves to unvisited squares\n    vector<tuple<int, int, int>> candidates; // (d_value, new_i, new_j)\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n            !visited[ni][nj] && can_move(i, j, dir)) {\n            candidates.emplace_back(d[ni][nj], ni, nj);\n        }\n    }\n    \n    // Sort by susceptibility in descending order - visit high-susceptibility squares first\n    sort(candidates.begin(), candidates.end(), [](const tuple<int,int,int>& a, const tuple<int,int,int>& b) {\n        return get<0>(a) > get<0>(b);\n    });\n    \n    for (auto& candidate : candidates) {\n        int new_d = get<0>(candidate);\n        int ni = get<1>(candidate);\n        int nj = get<2>(candidate);\n        \n        // Determine direction\n        int dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (i + di[d] == ni && j + dj[d] == nj) {\n                dir = d;\n                break;\n            }\n        }\n        \n        // Move to the new square\n        moves += dir_char[dir];\n        dfs(ni, nj);\n        \n        // Move back\n        moves += dir_char[(dir + 2) % 4];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    visited.assign(N, vector<bool>(N, false));\n    \n    dfs(0, 0);\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 15;\nconst int NN = GRID_SIZE * GRID_SIZE;\nconst int INF = 1e9;\n\nvector<int> pos[26];  // positions (linear index) for each letter\n\ninline int row(int idx) { return idx / GRID_SIZE; }\ninline int col(int idx) { return idx % GRID_SIZE; }\n\n// Manhattan distance transform: out[v] = min_u (cur[u] + dist(u, v))\nvoid dist_transform(const vector<int>& cur, vector<int>& out) {\n    int val[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j)\n            val[i][j] = cur[i * GRID_SIZE + j];\n\n    int tmp[GRID_SIZE][GRID_SIZE];\n    // horizontal pass\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        // left to right\n        tmp[i][0] = val[i][0];\n        for (int j = 1; j < GRID_SIZE; ++j) {\n            int a = val[i][j];\n            int b = tmp[i][j-1] + 1;\n            tmp[i][j] = a < b ? a : b;\n        }\n        // right to left\n        for (int j = GRID_SIZE - 2; j >= 0; --j) {\n            int b = tmp[i][j+1] + 1;\n            if (b < tmp[i][j]) tmp[i][j] = b;\n        }\n    }\n\n    // vertical pass\n    for (int j = 0; j < GRID_SIZE; ++j) {\n        // top to bottom\n        out[0 * GRID_SIZE + j] = tmp[0][j];\n        for (int i = 1; i < GRID_SIZE; ++i) {\n            int a = tmp[i][j];\n            int b = out[(i-1) * GRID_SIZE + j] + 1;\n            out[i * GRID_SIZE + j] = a < b ? a : b;\n        }\n        // bottom to top\n        for (int i = GRID_SIZE - 2; i >= 0; --i) {\n            int b = out[(i+1) * GRID_SIZE + j] + 1;\n            if (b < out[i * GRID_SIZE + j]) out[i * GRID_SIZE + j] = b;\n        }\n    }\n}\n\n// Compute minimal additional cost to type X from current distribution dp\nint compute_cost(const vector<int>& dp, const string& X,\n                 vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    int ans = INF;\n    for (int v : pos[X.back() - 'A'])\n        if (cur[v] < ans) ans = cur[v];\n    return ans;\n}\n\n// Extend dp by typing X, returning the new distribution\nvector<int> extend_dp(const vector<int>& dp, const string& X,\n                      vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    return cur;\n}\n\n// Reconstruct the optimal sequence of squares for typing X\nvector<int> reconstruct_path(const vector<int>& dp, const string& X) {\n    int L = X.size();\n    vector<vector<int>> cost(L + 1, vector<int>(NN, INF));\n    vector<vector<int>> prev(L + 1, vector<int>(NN, -1));\n\n    // pos 0\n    for (int u = 0; u < NN; ++u) cost[0][u] = dp[u];\n\n    for (int p = 0; p < L; ++p) {\n        char c = X[p];\n        for (int v : pos[c - 'A']) {\n            for (int u = 0; u < NN; ++u) {\n                if (cost[p][u] == INF) continue;\n                int d = abs(row(u) - row(v)) + abs(col(u) - col(v));\n                int new_cost = cost[p][u] + d + 1;\n                if (new_cost < cost[p+1][v]) {\n                    cost[p+1][v] = new_cost;\n                    prev[p+1][v] = u;\n                }\n            }\n        }\n    }\n\n    // find best end\n    int best_v = -1, best_cost = INF;\n    for (int v : pos[X.back() - 'A']) {\n        if (cost[L][v] < best_cost) {\n            best_cost = cost[L][v];\n            best_v = v;\n        }\n    }\n\n    // backtrack\n    vector<int> path(L);\n    int cur_v = best_v;\n    for (int p = L; p >= 1; --p) {\n        path[p-1] = cur_v;\n        cur_v = prev[p][cur_v];\n    }\n    return path;\n}\n\n// Compute maximum overlap (0..4) between suffix of S and prefix of tk\nint compute_overlap(const string& S, const string& tk) {\n    int slen = S.size();\n    int max_possible = min(4, slen);\n    for (int l = max_possible; l >= 1; --l) {\n        if (S.compare(slen - l, l, tk, 0, l) == 0)\n            return l;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_input, M;\n    cin >> N_input >> M;\n    int si, sj;\n    cin >> si >> sj;\n\n    // read grid\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            char c = row[j];\n            pos[c - 'A'].push_back(i * GRID_SIZE + j);\n        }\n    }\n\n    // read target strings\n    vector<string> t(M);\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    // initial state\n    vector<int> dp(NN, INF);\n    int start_idx = si * GRID_SIZE + sj;\n    dp[start_idx] = 0;\n\n    string S = \"\";\n    vector<pair<int, int>> ops;\n    vector<bool> covered(M, false);\n\n    // buffers for DP\n    vector<int> cur_buf(NN), minDist_buf(NN), next_buf(NN);\n\n    while (true) {\n        // check if all covered\n        bool all_covered = true;\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k]) {\n                all_covered = false;\n                break;\n            }\n        }\n        if (all_covered) break;\n\n        int best_k = -1;\n        int best_cost_val = INF;\n        string best_X;\n\n        // evaluate all uncovered t_k\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n            const string& tk = t[k];\n            int overlap = compute_overlap(S, tk);\n            string X = tk.substr(overlap);\n            if (X.empty()) {   // already covered\n                covered[k] = true;\n                continue;\n            }\n            int cost = compute_cost(dp, X, cur_buf, minDist_buf, next_buf);\n            if (cost < best_cost_val) {\n                best_cost_val = cost;\n                best_k = k;\n                best_X = X;\n            }\n        }\n\n        if (best_k == -1) break;  // nothing left to type\n\n        // reconstruct the optimal path for best_X\n        vector<int> path = reconstruct_path(dp, best_X);\n        for (int idx : path) {\n            ops.push_back({row(idx), col(idx)});\n        }\n\n        // update dp and S\n        dp = extend_dp(dp, best_X, cur_buf, minDist_buf, next_buf);\n        S += best_X;\n\n        // update covered set\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k] && S.find(t[k]) != string::npos)\n                covered[k] = true;\n        }\n    }\n\n    // output operations\n    for (auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    vector<vector<pair<int, int>>> polyominoes(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        vector<pair<int, int>> poly(d);\n        for (int i = 0; i < d; i++) {\n            cin >> poly[i].first >> poly[i].second;\n        }\n        polyominoes[k] = poly;\n    }\n\n    vector<pair<int, int>> has_oil;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int val;\n            cin >> val;\n            if (val > 0) {\n                has_oil.push_back({i, j});\n            }\n        }\n    }\n\n    cout << \"a \" << has_oil.size();\n    for (auto &p : has_oil) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl;\n    cout.flush();\n\n    int result;\n    cin >> result;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> A(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < N; i++) {\n            cin >> A[d][i];\n        }\n    }\n\n    vector<int> H(D);\n\n    for (int d = 0; d < D; d++) {\n        if (d == 0) {\n            int best_H = 1;\n            int best_value = 1e9;\n            for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                int total_width = 0;\n                for (int i = 0; i < N; i++) {\n                    total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                }\n                if (total_width <= W) {\n                    int value = total_width + N * H_candidate;\n                    if (value < best_value) {\n                        best_value = value;\n                        best_H = H_candidate;\n                    }\n                }\n            }\n            H[d] = best_H;\n        } else {\n            int H_prev = H[d-1];\n            int total_width = 0;\n            for (int i = 0; i < N; i++) {\n                total_width += (A[d][i] + H_prev - 1) / H_prev;\n            }\n            if (total_width <= W) {\n                H[d] = H_prev;\n            } else {\n                int best_H = 1;\n                int best_value = 1e9;\n                for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                    int total_width = 0;\n                    for (int i = 0; i < N; i++) {\n                        total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                    }\n                    if (total_width <= W) {\n                        int value = total_width + N * H_candidate;\n                        if (value < best_value) {\n                            best_value = value;\n                            best_H = H_candidate;\n                        }\n                    }\n                }\n                H[d] = best_H;\n            }\n        }\n    }\n\n    for (int d = 0; d < D; d++) {\n        int top, bottom;\n        if (d == 0) {\n            top = 0;\n            bottom = H[d];\n        } else {\n            if (H[d] <= H[d-1]) {\n                top = H[d-1] - H[d];\n                bottom = H[d-1];\n            } else {\n                top = 0;\n                bottom = H[d];\n            }\n        }\n        int left = 0;\n        for (int i = 0; i < N; i++) {\n            int width = (A[d][i] + H[d] - 1) / H[d];\n            int right = left + width;\n            cout << top << \" \" << left << \" \" << bottom << \" \" << right << endl;\n            left = right;\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <climits>\n\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    int rem[9][9];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> rem[i][j];\n            rem[i][j] %= MOD;\n        }\n    }\n\n    int s[20][3][3];\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n\n    for (int step = 0; step < K; step++) {\n        long long best_change = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= 6; p++) {\n                for (int q = 0; q <= 6; q++) {\n                    long long change = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int r = rem[p+i][q+j];\n                            int s_val = s[m][i][j];\n                            if (r + s_val < MOD) {\n                                change += s_val;\n                            } else {\n                                change += s_val - MOD;\n                            }\n                        }\n                    }\n                    if (change > best_change) {\n                        best_change = change;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_change <= 0) {\n            break;\n        }\n\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int &r = rem[best_p+i][best_q+j];\n                int s_val = s[best_m][i][j];\n                if (r + s_val < MOD) {\n                    r += s_val;\n                } else {\n                    r = r + s_val - MOD;\n                }\n            }\n        }\n\n        ops.push_back(make_tuple(best_m, best_p, best_q));\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto op : ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <cstring>\n#include <set>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\n\nstruct Crane {\n    int x, y;\n    int carrying; // -1 if not carrying, else container number\n};\n\nint grid[MAX_N][MAX_N]; // -1: empty, else container number\nCrane cranes[MAX_N];\nint next_arrival[MAX_N]; // next index to arrive for each row\nvector<int> dispatched[MAX_N]; // dispatched containers per gate\n\nint next_required[MAX_N]; // next required container for each gate\n\nvoid init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        cranes[i] = {i, 0, -1};\n        next_arrival[i] = 0;\n        next_required[i] = i * N; // smallest in the set\n    }\n}\n\nbool is_next_to_dispatch(int container, int gate) {\n    if (container < gate * N || container >= (gate + 1) * N) {\n        return false;\n    }\n    return container == next_required[gate];\n}\n\nvoid update_next_required(int gate) {\n    set<int> desired;\n    for (int i = 0; i < N; i++) {\n        desired.insert(gate * N + i);\n    }\n    for (int d : dispatched[gate]) {\n        desired.erase(d);\n    }\n    if (!desired.empty()) {\n        next_required[gate] = *desired.begin();\n    } else {\n        next_required[gate] = -1;\n    }\n}\n\nint main() {\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    init();\n\n    vector<string> actions_per_crane(N, \"\");\n    int total_containers = N * N;\n    int dispatched_count = 0;\n    int turn = 0;\n\n    while (turn < MAX_TURNS && dispatched_count < total_containers) {\n        // Step 1: New container arrival\n        for (int i = 0; i < N; i++) {\n            if (next_arrival[i] < N) {\n                bool gate_occupied = false;\n                if (grid[i][0] != -1) {\n                    gate_occupied = true;\n                }\n                for (int k = 0; k < N; k++) {\n                    if (cranes[k].x == i && cranes[k].y == 0) {\n                        gate_occupied = true;\n                        break;\n                    }\n                }\n                if (!gate_occupied) {\n                    grid[i][0] = A[i][next_arrival[i]];\n                    next_arrival[i]++;\n                }\n            }\n        }\n\n        // Prepare for crane actions\n        Crane next_cranes[MAX_N];\n        for (int i = 0; i < N; i++) {\n            next_cranes[i] = cranes[i];\n        }\n        int next_grid[MAX_N][MAX_N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                next_grid[i][j] = grid[i][j];\n            }\n        }\n\n        // For collision detection: record intended next positions\n        int intended_x[MAX_N], intended_y[MAX_N];\n        for (int i = 0; i < N; i++) {\n            intended_x[i] = cranes[i].x;\n            intended_y[i] = cranes[i].y;\n        }\n\n        // Process each crane in order (large crane first, then small cranes)\n        for (int idx = 0; idx < N; idx++) {\n            char action = '.';\n            Crane& crane = cranes[idx];\n            int x = crane.x;\n            int y = crane.y;\n            int carrying = crane.carrying;\n\n            if (carrying != -1) {\n                int target_gate = carrying / N;\n                int target_x = target_gate;\n                int target_y = N-1;\n\n                if (x == target_x && y == target_y) {\n                    if (is_next_to_dispatch(carrying, target_gate)) {\n                        action = 'Q';\n                    } else {\n                        if (x+1 < N && next_grid[x+1][y] == -1) {\n                            action = 'D';\n                        } else if (x-1 >=0 && next_grid[x-1][y] == -1) {\n                            action = 'U';\n                        } else if (y-1 >=0 && next_grid[x][y-1] == -1) {\n                            action = 'L';\n                        } else {\n                            action = '.';\n                        }\n                    }\n                } else {\n                    if (y < target_y) {\n                        action = 'R';\n                    } else if (x < target_x) {\n                        action = 'D';\n                    } else if (x > target_x) {\n                        action = 'U';\n                    } else {\n                        action = '.';\n                    }\n                }\n            } else {\n                if (grid[x][y] != -1) {\n                    action = 'P';\n                } else {\n                    if (y < N-1) {\n                        action = 'R';\n                    } else {\n                        action = '.';\n                    }\n                }\n            }\n\n            // Validate action and update intended position\n            int nx = x, ny = y;\n            bool valid = true;\n            if (action == 'U') nx--;\n            else if (action == 'D') nx++;\n            else if (action == 'L') ny--;\n            else if (action == 'R') ny++;\n\n            if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) valid = false;\n                else {\n                    if (carrying != -1 && idx >= 1) {\n                        if (next_grid[nx][ny] != -1) valid = false;\n                    }\n                    for (int i = 0; i < N; i++) {\n                        if (i != idx) {\n                            if (intended_x[i] == nx && intended_y[i] == ny) {\n                                valid = false;\n                                break;\n                            }\n                            if (intended_x[i] == x && intended_y[i] == y && \n                                intended_x[idx] == nx && intended_y[idx] == ny) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                    }\n                }\n            } else if (action == 'P') {\n                if (carrying != -1 || next_grid[x][y] == -1) valid = false;\n            } else if (action == 'Q') {\n                if (carrying == -1 || next_grid[x][y] != -1) valid = false;\n            }\n\n            if (!valid) {\n                action = '.';\n                nx = x;\n                ny = y;\n            }\n\n            // Apply action\n            if (action == 'P') {\n                next_cranes[idx].carrying = next_grid[x][y];\n                next_grid[x][y] = -1;\n            } else if (action == 'Q') {\n                next_grid[x][y] = carrying;\n                next_cranes[idx].carrying = -1;\n            } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                next_cranes[idx].x = nx;\n                next_cranes[idx].y = ny;\n                intended_x[idx] = nx;\n                intended_y[idx] = ny;\n            }\n\n            actions_per_crane[idx] += action;\n        }\n\n        // Update global state\n        for (int i = 0; i < N; i++) {\n            cranes[i] = next_cranes[i];\n            for (int j = 0; j < N; j++) {\n                grid[i][j] = next_grid[i][j];\n            }\n        }\n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container = grid[i][N-1];\n                grid[i][N-1] = -1;\n                dispatched[i].push_back(container);\n                dispatched_count++;\n                update_next_required(i);\n            }\n        }\n\n        turn++;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << actions_per_crane[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(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    vector<tuple<int, int, int>> surp;\n    vector<tuple<int, int, int>> def;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                surp.push_back(make_tuple(i, j, grid[i][j]));\n            } else if (grid[i][j] < 0) {\n                def.push_back(make_tuple(i, j, -grid[i][j]));\n            }\n        }\n    }\n\n    int cur_i = 0, cur_j = 0;\n    vector<string> ops;\n\n    auto move_to = [&](int target_i, int target_j) {\n        while (cur_i < target_i) {\n            ops.push_back(\"D\");\n            cur_i++;\n        }\n        while (cur_i > target_i) {\n            ops.push_back(\"U\");\n            cur_i--;\n        }\n        while (cur_j < target_j) {\n            ops.push_back(\"R\");\n            cur_j++;\n        }\n        while (cur_j > target_j) {\n            ops.push_back(\"L\");\n            cur_j--;\n        }\n    };\n\n    while (!surp.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < surp.size(); idx++) {\n            auto [i, j, amt] = surp[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = surp[best_idx];\n        move_to(i, j);\n        ops.push_back(\"+\" + to_string(amt));\n        surp.erase(surp.begin() + best_idx);\n    }\n\n    while (!def.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < def.size(); idx++) {\n            auto [i, j, amt] = def[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = def[best_idx];\n        move_to(i, j);\n        ops.push_back(\"-\" + to_string(amt));\n        def.erase(def.begin() + best_idx);\n    }\n\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n\n    vector<int> di = {-1, 1, 0, 0};\n    vector<int> dj = {0, 0, -1, 1};\n\n    for (int t = 0; t < T; t++) {\n        vector<int> total(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            for (int l = 0; l < M; l++) {\n                total[i] += seeds[i][l];\n            }\n        }\n\n        vector<int> indices(seed_count);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(), [&](int i, int j) { return total[i] > total[j]; });\n\n        vector<int> selected_indices;\n        for (int i = 0; i < 36; i++) {\n            selected_indices.push_back(indices[i]);\n        }\n\n        vector<vector<int>> selected_seeds;\n        for (int idx : selected_indices) {\n            selected_seeds.push_back(seeds[idx]);\n        }\n\n        vector<vector<double>> dist(36, vector<double>(36, 0.0));\n        for (int i = 0; i < 36; i++) {\n            for (int j = 0; j < 36; j++) {\n                if (i == j) continue;\n                double d2 = 0.0;\n                for (int l = 0; l < M; l++) {\n                    double diff = selected_seeds[i][l] - selected_seeds[j][l];\n                    d2 += diff * diff;\n                }\n                dist[i][j] = d2;\n            }\n        }\n\n        vector<vector<int>> grid_comp(N, vector<int>(N, -1));\n        vector<vector<int>> grid_output(N, vector<int>(N, -1));\n        vector<vector<int>> neighbor_count(N, vector<int>(N, 0));\n        vector<bool> seed_used(36, false);\n\n        int start_i = N / 2;\n        int start_j = N / 2;\n        grid_comp[start_i][start_j] = 0;\n        grid_output[start_i][start_j] = selected_indices[0];\n        seed_used[0] = true;\n\n        for (int d = 0; d < 4; d++) {\n            int ni = start_i + di[d];\n            int nj = start_j + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                neighbor_count[ni][nj]++;\n            }\n        }\n\n        for (int count = 0; count < 35; count++) {\n            int best_i = -1, best_j = -1;\n            int max_count = -1;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid_comp[i][j] == -1) {\n                        if (neighbor_count[i][j] > max_count) {\n                            max_count = neighbor_count[i][j];\n                            best_i = i;\n                            best_j = j;\n                        } else if (neighbor_count[i][j] == max_count) {\n                            if (best_i == -1 || i < best_i || (i == best_i && j < best_j)) {\n                                best_i = i;\n                                best_j = j;\n                            }\n                        }\n                    }\n                }\n            }\n\n            double best_cost = -1;\n            int best_seed = -1;\n            for (int s = 0; s < 36; s++) {\n                if (!seed_used[s]) {\n                    double cost = 0.0;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = best_i + di[d];\n                        int nj = best_j + dj[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid_comp[ni][nj] != -1) {\n                            int t = grid_comp[ni][nj];\n                            cost += dist[s][t];\n                        }\n                    }\n                    if (cost > best_cost) {\n                        best_cost = cost;\n                        best_seed = s;\n                    }\n                }\n            }\n\n            grid_comp[best_i][best_j] = best_seed;\n            grid_output[best_i][best_j] = selected_indices[best_seed];\n            seed_used[best_seed] = true;\n\n            for (int d = 0; d < 4; d++) {\n                int ni = best_i + di[d];\n                int nj = best_j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid_comp[ni][nj] == -1) {\n                    neighbor_count[ni][nj]++;\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid_output[i][j];\n                if (j < N - 1) {\n                    cout << \" \";\n                }\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <queue>\n#include <map>\n#include <set>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nPoint get_grab_pos(Point s, char dir, int d) {\n    if (dir == 'R') return Point(s.x - d, s.y);\n    if (dir == 'L') return Point(s.x + d, s.y);\n    if (dir == 'D') return Point(s.x, s.y - d);\n    if (dir == 'U') return Point(s.x, s.y + d);\n    return Point();\n}\n\nPoint get_release_pos(Point t, char dir, int d) {\n    if (dir == 'R') return Point(t.x - d, t.y);\n    if (dir == 'L') return Point(t.x + d, t.y);\n    if (dir == 'D') return Point(t.x, t.y - d);\n    if (dir == 'U') return Point(t.x, t.y + d);\n    return Point();\n}\n\nbool is_valid(Point p, int N) {\n    return p.x >= 0 && p.x < N && p.y >= 0 && p.y < N;\n}\n\nvector<char> get_path(Point from, Point to) {\n    vector<char> path;\n    int x = from.x;\n    int y = from.y;\n    while (x != to.x) {\n        if (x < to.x) {\n            path.push_back('R');\n            x++;\n        } else {\n            path.push_back('L');\n            x--;\n        }\n    }\n    while (y != to.y) {\n        if (y < to.y) {\n            path.push_back('D');\n            y++;\n        } else {\n            path.push_back('U');\n            y--;\n        }\n    }\n    return path;\n}\n\nstring create_turn(char movement, int leaf_index, char direction, bool grab, int V) {\n    string s(2 * V, '.');\n    s[0] = movement;\n    if (leaf_index != -1) {\n        s[leaf_index] = direction;\n        if (grab) {\n            s[V + leaf_index] = 'P';\n        }\n    }\n    return s;\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\n    vector<string> S(N), T(N);\n    for (int i = 0; i < N; i++) cin >> S[i];\n    for (int i = 0; i < N; i++) cin >> T[i];\n\n    vector<Point> initial_positions;\n    vector<Point> target_positions;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (S[i][j] == '1') initial_positions.push_back(Point(i, j));\n            if (T[i][j] == '1') target_positions.push_back(Point(i, j));\n        }\n    }\n\n    vector<pair<Point, Point>> pairs;\n    vector<bool> assigned(M, false);\n\n    for (int i = 0; i < M; i++) {\n        Point s = initial_positions[i];\n        int best_j = -1;\n        int best_dist = 1e9;\n        for (int j = 0; j < M; j++) {\n            if (assigned[j]) continue;\n            int dist = manhattan(s, target_positions[j]);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_j = j;\n            }\n        }\n        assigned[best_j] = true;\n        pairs.push_back({s, target_positions[best_j]});\n    }\n\n    Point current_root(N / 2, N / 2);\n    vector<string> turns;\n\n    vector<pair<Point, Point>> remaining = pairs;\n\n    while (!remaining.empty()) {\n        int best_cost = 1e9;\n        int best_index = -1;\n        int best_leaf = -1;\n        char best_grab_dir = ' ';\n        char best_release_dir = ' ';\n        Point best_grab_pos, best_release_pos;\n\n        for (int i = 0; i < remaining.size(); i++) {\n            Point s = remaining[i].first;\n            Point t = remaining[i].second;\n            for (int leaf = 1; leaf < V; leaf++) {\n                int d = leaf;\n                for (char grab_dir : {'L', 'R', 'U', 'D'}) {\n                    Point grab_pos = get_grab_pos(s, grab_dir, d);\n                    if (!is_valid(grab_pos, N)) continue;\n                    for (char release_dir : {'L', 'R', 'U', 'D'}) {\n                        Point release_pos = get_release_pos(t, release_dir, d);\n                        if (!is_valid(release_pos, N)) continue;\n                        int cost = manhattan(current_root, grab_pos) + manhattan(grab_pos, release_pos);\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_index = i;\n                            best_leaf = leaf;\n                            best_grab_dir = grab_dir;\n                            best_release_dir = release_dir;\n                            best_grab_pos = grab_pos;\n                            best_release_pos = release_pos;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_index == -1) {\n            break;\n        }\n\n        vector<char> path1 = get_path(current_root, best_grab_pos);\n        if (path1.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_grab_dir, true, V));\n        } else {\n            for (int j = 0; j < path1.size(); j++) {\n                bool grab = (j == path1.size() - 1);\n                turns.push_back(create_turn(path1[j], best_leaf, best_grab_dir, grab, V));\n            }\n        }\n        current_root = best_grab_pos;\n\n        vector<char> path2 = get_path(best_grab_pos, best_release_pos);\n        if (path2.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_release_dir, true, V));\n        } else {\n            for (int j = 0; j < path2.size(); j++) {\n                bool release = (j == path2.size() - 1);\n                turns.push_back(create_turn(path2[j], best_leaf, best_release_dir, release, V));\n            }\n        }\n        current_root = best_release_pos;\n\n        remaining.erase(remaining.begin() + best_index);\n    }\n\n    cout << V << endl;\n    for (int i = 1; i < V; i++) {\n        cout << 0 << \" \" << i << endl;\n    }\n    cout << N/2 << \" \" << N/2 << endl;\n\n    for (const string& turn : turns) {\n        cout << turn << endl;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cstdlib>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    int weight;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N;\n    cin >> N;\n    vector<Point> points;\n    set<pair<int, int>> point_set;\n\n    for (int i = 0; i < 2 * N; i++) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 0});\n        point_set.insert({x, y});\n    }\n\n    for (int i = 0; i < N; i++) {\n        points[i].weight = 1;\n    }\n    for (int i = N; i < 2 * N; i++) {\n        points[i].weight = -1;\n    }\n\n    vector<int> xs, ys;\n    for (auto& p : points) {\n        xs.push_back(p.x);\n        ys.push_back(p.y);\n    }\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n\n    if (xs.size() < 2 || ys.size() < 2) {\n        cout << 4 << endl;\n        cout << \"0 0\" << endl;\n        cout << \"0 1\" << endl;\n        cout << \"1 1\" << endl;\n        cout << \"1 0\" << endl;\n        return 0;\n    }\n\n    vector<int> candidate_x;\n    candidate_x.push_back(xs[0]);\n    for (int i = 1; i < 10; i++) {\n        int index = (xs.size() * i) / 10;\n        candidate_x.push_back(xs[index]);\n    }\n    candidate_x.push_back(xs.back());\n\n    vector<int> candidate_y;\n    candidate_y.push_back(ys[0]);\n    for (int i = 1; i < 10; i++) {\n        int index = (ys.size() * i) / 10;\n        candidate_y.push_back(ys[index]);\n    }\n    candidate_y.push_back(ys.back());\n\n    sort(candidate_x.begin(), candidate_x.end());\n    candidate_x.erase(unique(candidate_x.begin(), candidate_x.end()), candidate_x.end());\n    sort(candidate_y.begin(), candidate_y.end());\n    candidate_y.erase(unique(candidate_y.begin(), candidate_y.end()), candidate_y.end());\n\n    int best_score = -1e9;\n    int best_x1 = 0, best_y1 = 0, best_x2 = 1, best_y2 = 1;\n\n    for (int i = 0; i < candidate_x.size(); i++) {\n        for (int j = i + 1; j < candidate_x.size(); j++) {\n            int x1 = candidate_x[i];\n            int x2 = candidate_x[j];\n            for (int k = 0; k < candidate_y.size(); k++) {\n                for (int l = k + 1; l < candidate_y.size(); l++) {\n                    int y1 = candidate_y[k];\n                    int y2 = candidate_y[l];\n                    int score = 0;\n                    for (auto& p : points) {\n                        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) {\n                            score += p.weight;\n                        }\n                    }\n                    if (score > best_score) {\n                        best_score = score;\n                        best_x1 = x1;\n                        best_y1 = y1;\n                        best_x2 = x2;\n                        best_y2 = y2;\n                    }\n                }\n            }\n        }\n    }\n\n    if (best_score < 1) {\n        srand(0);\n        for (int attempt = 0; attempt < 10; attempt++) {\n            int x0 = rand() % 100000;\n            int y0 = rand() % 100000;\n            int x1 = x0 + 1;\n            int y1 = y0 + 1;\n            if (point_set.find({x0, y0}) == point_set.end() &&\n                point_set.find({x0, y1}) == point_set.end() &&\n                point_set.find({x1, y0}) == point_set.end() &&\n                point_set.find({x1, y1}) == point_set.end()) {\n                best_x1 = x0;\n                best_y1 = y0;\n                best_x2 = x1;\n                best_y2 = y1;\n                best_score = 1;\n                break;\n            }\n        }\n        if (best_score < 1) {\n            best_x1 = 0;\n            best_y1 = 0;\n            best_x2 = 1;\n            best_y2 = 1;\n        }\n    }\n\n    cout << 4 << endl;\n    cout << best_x1 << \" \" << best_y1 << endl;\n    cout << best_x1 << \" \" << best_y2 << endl;\n    cout << best_x2 << \" \" << best_y2 << endl;\n    cout << best_x2 << \" \" << best_y1 << endl;\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int id;\n    double w_est, h_est;  // Estimated dimensions\n    double w_var, h_var;  // Variance estimates\n    double w_obs, h_obs;  // Observed values\n};\n\nstruct Placement {\n    int id;\n    int rotated;\n    char direction;\n    int reference;\n};\n\nclass Packer {\nprivate:\n    vector<Rectangle> rects;\n    double sigma;\n    int N, T;\n    \n    // Random number generator\n    mt19937 rng;\n    \n    // Update estimates using Bayesian approach\n    void updateEstimates(int turn, double W_meas, double H_meas, const vector<Placement>& placement) {\n        // For each placed rectangle, adjust estimates based on bounding box measurement\n        for (const auto& p : placement) {\n            Rectangle& rect = rects[p.id];\n            double expected_W = rect.w_est;\n            double expected_H = rect.h_est;\n            \n            // Simple adjustment: if measured box is larger than expected, increase estimates\n            double adjustment_factor = 1.0;\n            if (W_meas > 0 && H_meas > 0) {\n                // Use harmonic mean of ratios to avoid extreme adjustments\n                double w_ratio = W_meas / (expected_W + 1e-9);\n                double h_ratio = H_meas / (expected_H + 1e-9);\n                adjustment_factor = 2.0 / (1.0/w_ratio + 1.0/h_ratio);\n            }\n            \n            // Adjust with damping to prevent overcorrection\n            double damping = 0.1;\n            rect.w_est = rect.w_est * (1 - damping) + rect.w_est * adjustment_factor * damping;\n            rect.h_est = rect.h_est * (1 - damping) + rect.h_est * adjustment_factor * damping;\n            \n            // Update variance estimates (simplified)\n            rect.w_var = rect.w_var * 0.95 + (W_meas - rect.w_est) * (W_meas - rect.w_est) * 0.05;\n            rect.h_var = rect.h_var * 0.95 + (H_meas - rect.h_est) * (H_meas - rect.h_est) * 0.05;\n            \n            // Clamp values\n            rect.w_est = max(1.0, min(1e9, rect.w_est));\n            rect.h_est = max(1.0, min(1e9, rect.h_est));\n        }\n    }\n    \n    // Simulated annealing for packing optimization\n    vector<Placement> optimizePacking(int turn, int num_rects) {\n        vector<Placement> best_solution;\n        double best_score = 1e18;\n        \n        int iterations = 200 + turn * 10;  // More iterations in later turns\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            vector<Placement> candidate;\n            vector<bool> used(N, false);\n            \n            // Randomly select subset of rectangles (in increasing order)\n            vector<int> selected;\n            for (int i = 0; i < N; i++) {\n                if (rng() % 2) {\n                    selected.push_back(i);\n                }\n            }\n            sort(selected.begin(), selected.end());\n            \n            // Greedy packing with randomization\n            for (int id : selected) {\n                Placement p;\n                p.id = id;\n                p.rotated = rng() % 2;\n                p.direction = (rng() % 2) ? 'U' : 'L';\n                \n                // For reference, try existing placed rectangles or -1\n                if (candidate.empty()) {\n                    p.reference = -1;\n                } else {\n                    p.reference = candidate[rng() % candidate.size()].id;\n                }\n                \n                candidate.push_back(p);\n            }\n            \n            // Evaluate score\n            double score = evaluateScore(candidate, turn);\n            \n            // Simulated annealing acceptance\n            double temperature = 100.0 / (1 + turn);\n            if (score < best_score || \n                (exp((best_score - score) / temperature) > (double)(rng() % 10000) / 10000.0)) {\n                best_solution = candidate;\n                best_score = score;\n            }\n        }\n        \n        return best_solution;\n    }\n    \n    // Evaluate score for a packing\n    double evaluateScore(const vector<Placement>& placement, int turn) {\n        if (placement.empty()) {\n            // If no rectangles placed, all contribute to penalty\n            double penalty = 0;\n            for (const auto& rect : rects) {\n                penalty += rect.w_est + rect.h_est;\n            }\n            return penalty;\n        }\n        \n        // Simulate packing to get bounding box\n        // This is a simplified simulation - in practice, we'd need to track positions\n        double total_width = 0;\n        double total_height = 0;\n        \n        // Simple heuristic: sum of widths if placed horizontally, heights if vertically\n        // More sophisticated simulation would be better but is complex\n        double sum_w = 0, sum_h = 0;\n        for (const auto& p : placement) {\n            const Rectangle& rect = rects[p.id];\n            if (p.rotated) {\n                sum_w += rect.h_est;\n                sum_h += rect.w_est;\n            } else {\n                sum_w += rect.w_est;\n                sum_h += rect.h_est;\n            }\n        }\n        \n        // Use more compact dimension\n        total_width = min(sum_w, sum_h * 1.5);\n        total_height = min(sum_h, sum_w * 1.5);\n        \n        // Add penalty for unused rectangles\n        double penalty = 0;\n        vector<bool> used(N, false);\n        for (const auto& p : placement) {\n            used[p.id] = true;\n        }\n        for (int i = 0; i < N; i++) {\n            if (!used[i]) {\n                penalty += rects[i].w_est + rects[i].h_est;\n            }\n        }\n        \n        return total_width + total_height + penalty;\n    }\n    \n    // Select which rectangles to pack based on value vs size\n    vector<int> selectRectangles(int turn) {\n        vector<int> selected;\n        \n        // Calculate \"value\" of each rectangle (high penalty if not packed)\n        vector<pair<double, int>> values;\n        for (int i = 0; i < N; i++) {\n            double value = rects[i].w_est + rects[i].h_est;\n            values.push_back({value, i});\n        }\n        \n        // Sort by value (descending)\n        sort(values.begin(), values.end(), greater<pair<double, int>>());\n        \n        // Select top K rectangles, where K increases with turn\n        int k = min(N, max(5, (int)(N * (0.3 + turn * 0.02))));\n        for (int i = 0; i < k; i++) {\n            selected.push_back(values[i].second);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n\npublic:\n    Packer(int n, int t, double s, const vector<pair<double, double>>& observed) : N(n), T(t), sigma(s), rng(12345 + n) {\n        rects.resize(N);\n        for (int i = 0; i < N; i++) {\n            rects[i].id = i;\n            rects[i].w_obs = observed[i].first;\n            rects[i].h_obs = observed[i].second;\n            // Initialize estimates with observed values plus some random noise\n            normal_distribution<double> dist(0, sigma * 0.1);\n            rects[i].w_est = observed[i].first + dist(rng);\n            rects[i].h_est = observed[i].second + dist(rng);\n            rects[i].w_var = sigma * sigma;\n            rects[i].h_var = sigma * sigma;\n            \n            // Clamp\n            rects[i].w_est = max(1.0, min(1e9, rects[i].w_est));\n            rects[i].h_est = max(1.0, min(1e9, rects[i].h_est));\n        }\n    }\n    \n    vector<Placement> solve(int turn, double W_meas, double H_meas, const vector<Placement>& last_placement) {\n        // Update estimates based on previous measurement\n        if (turn > 0) {\n            updateEstimates(turn, W_meas, H_meas, last_placement);\n        }\n        \n        // Select which rectangles to pack\n        vector<int> selected = selectRectangles(turn);\n        \n        // If we haven't packed many rectangles yet, try to pack more\n        if (turn < T / 4 && selected.size() < N) {\n            // Add some more rectangles in later turns\n            int additional = min(N - (int)selected.size(), (turn + 1) * 2);\n            for (int i = 0; i < additional; i++) {\n                selected.push_back((selected.size() + i) % N);\n            }\n            sort(selected.begin(), selected.end());\n            selected.erase(unique(selected.begin(), selected.end()), selected.end());\n        }\n        \n        // Optimize packing\n        vector<Placement> placement = optimizePacking(turn, selected.size());\n        \n        return placement;\n    }\n};\n\nint main() {\n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<double, double>> observed(N);\n    for (int i = 0; i < N; i++) {\n        cin >> observed[i].first >> observed[i].second;\n    }\n    \n    Packer packer(N, T, sigma, observed);\n    \n    vector<Placement> last_placement;\n    \n    for (int turn = 0; turn < T; turn++) {\n        double W_meas = 0, H_meas = 0;\n        \n        // Get measurement from previous turn (except first turn)\n        if (turn > 0) {\n            cin >> W_meas >> H_meas;\n        }\n        \n        // Solve for current turn\n        vector<Placement> placement = packer.solve(turn, W_meas, H_meas, last_placement);\n        \n        // Output\n        cout << placement.size() << endl;\n        for (const auto& p : placement) {\n            cout << p.id << \" \" << p.rotated << \" \" << p.direction << \" \" << p.reference << endl;\n        }\n        cout.flush();\n        \n        last_placement = placement;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> order_asc, order_desc;\n\n    // State for current forest\n    vector<bool> covered;\n    vector<int> parent, depth;\n    vector<vector<int>> children;\n    vector<int> subtree_sum, max_depth_subtree;\n\n    void read_input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; ++i) cin >> A[i];\n        adj.assign(N, {});\n        for (int i = 0; i < M; ++i) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // read coordinates (unused)\n        for (int i = 0; i < N; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n\n        // prepare vertex orders\n        order_asc.resize(N);\n        iota(order_asc.begin(), order_asc.end(), 0);\n        sort(order_asc.begin(), order_asc.end(), [&](int i, int j) { return A[i] < A[j]; });\n        order_desc = order_asc;\n        reverse(order_desc.begin(), order_desc.end());\n    }\n\n    void build_initial_forest(const vector<int>& order) {\n        covered.assign(N, false);\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        for (int v : order) {\n            if (covered[v]) continue;\n            // BFS from v, depth limit H, only through uncovered vertices\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            covered[v] = true;\n            parent[v] = -1;\n            depth[v] = 0;\n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d == H) continue;          // cannot go deeper\n                for (int w : adj[u]) {\n                    if (!covered[w]) {\n                        covered[w] = true;\n                        parent[w] = u;\n                        depth[w] = d + 1;\n                        if (d + 1 < H) q.push({w, d + 1}); // push only if can be expanded later\n                    }\n                }\n            }\n        }\n        // build children lists\n        children.assign(N, {});\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] != -1) {\n                children[parent[v]].push_back(v);\n            }\n        }\n    }\n\n    void compute_subtree_info() {\n        subtree_sum.assign(N, 0);\n        max_depth_subtree.assign(N, 0);\n        function<void(int)> dfs = [&](int v) {\n            subtree_sum[v] = A[v];\n            max_depth_subtree[v] = 0;\n            for (int c : children[v]) {\n                dfs(c);\n                subtree_sum[v] += subtree_sum[c];\n                max_depth_subtree[v] = max(max_depth_subtree[v], max_depth_subtree[c] + 1);\n            }\n        };\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                dfs(v);\n            }\n        }\n    }\n\n    int get_root(int v) {\n        while (parent[v] != -1) v = parent[v];\n        return v;\n    }\n\n    void update_depths(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) {\n            update_depths(c, delta);\n        }\n    }\n\n    void improve_forest() {\n        const int MAX_PASS = 20;\n        bool changed = true;\n        int pass = 0;\n        while (changed && pass < MAX_PASS) {\n            changed = false;\n            ++pass;\n            compute_subtree_info();\n            for (int v : order_desc) {\n                int best_u = -1;\n                long long best_gain = -1;\n                int root_v = get_root(v);\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;           // same edge, no gain\n                    int root_u = get_root(u);\n                    if (root_v == root_u) continue;         // same tree -> would create cycle\n                    int new_depth_v = depth[u] + 1;\n                    if (new_depth_v > H) continue;\n                    if (new_depth_v + max_depth_subtree[v] > H) continue;\n                    int delta = new_depth_v - depth[v];\n                    if (delta <= 0) continue;\n                    long long gain = (long long)delta * subtree_sum[v];\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_u = u;\n                    }\n                }\n                if (best_u != -1) {\n                    // perform the move\n                    int old_parent = parent[v];\n                    if (old_parent != -1) {\n                        auto& vec = children[old_parent];\n                        vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n                    }\n                    children[best_u].push_back(v);\n                    parent[v] = best_u;\n                    int delta = (depth[best_u] + 1) - depth[v];\n                    update_depths(v, delta);\n                    changed = true;\n                    break;   // restart the while loop\n                }\n            }\n        }\n    }\n\n    long long compute_score() {\n        long long score = 0;\n        for (int v = 0; v < N; ++v) {\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    }\n\n    vector<int> solve_one(bool ascending) {\n        const vector<int>& order = ascending ? order_asc : order_desc;\n        build_initial_forest(order);\n        improve_forest();\n        return parent;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver solver;\n    solver.read_input();\n\n    long long best_score = -1;\n    vector<int> best_parent;\n\n    for (bool asc : {true, false}) {\n        vector<int> parent = solver.solve_one(asc);\n        long long score = solver.compute_score();\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n\n    for (int i = 0; i < (int)best_parent.size(); ++i) {\n        if (i > 0) cout << ' ';\n        cout << best_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>> operations;\n    const int MAX_OPERATIONS = 4 * N * N;\n\n    while (operations.size() < MAX_OPERATIONS) {\n        bool hasOni = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    hasOni = true;\n                    break;\n                }\n            }\n            if (hasOni) break;\n        }\n        if (!hasOni) break;\n\n        bool removed = false;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == 'x') {\n                operations.push_back({'L', i});\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[i][N-1] == 'x') {\n                operations.push_back({'R', i});\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == 'x') {\n                operations.push_back({'U', j});\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[N-1][j] == 'x') {\n                operations.push_back({'D', j});\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        int best_dist = 1000000;\n        char best_dir = 0;\n        int best_index = -1;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == '.') {\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        if (j < best_dist) {\n                            best_dist = j;\n                            best_dir = 'L';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][N-1] == '.') {\n                for (int j = N-1; j >= 0; j--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - j;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'R';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == '.') {\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        if (i < best_dist) {\n                            best_dist = i;\n                            best_dir = 'U';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[N-1][j] == '.') {\n                for (int i = N-1; i >= 0; i--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - i;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'D';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (best_index != -1) {\n            operations.push_back({best_dir, best_index});\n            if (best_dir == 'L') {\n                int i = best_index;\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n            } else if (best_dir == 'R') {\n                int i = best_index;\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n            } else if (best_dir == 'U') {\n                int j = best_index;\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n            } else if (best_dir == 'D') {\n                int j = best_index;\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n            }\n        } else {\n            break;\n        }\n    }\n\n    for (auto op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int N, L;\n    cin >> N >> L;\n    int T[100];\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    for (int i = 0; i < N; i++) {\n        int a = (i + 1) % N;\n        int b = (i + 2) % N;\n        cout << a << \" \" << b << endl;\n    }\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\n// Global variables for input and query counting\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> cx, cy;   // center coordinates\nint queries_used = 0;\n\n// Perform a query on a set of cities and return the MST edges\nvector<pair<int, int>> do_query(vector<int> cities) {\n    sort(cities.begin(), cities.end());\n    cout << \"? \" << cities.size();\n    for (int c : cities) {\n        cout << \" \" << c;\n    }\n    cout << endl;\n    vector<pair<int, int>> edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.push_back(make_pair(a, b));\n    }\n    queries_used++;\n    return edges;\n}\n\n// Recursively build a spanning tree for a set of cities (already sorted by center)\nvector<pair<int, int>> build_tree(vector<int> cities) {\n    int n = cities.size();\n    if (n == 1) {\n        return {};\n    }\n    if (n == 2) {\n        return {make_pair(cities[0], cities[1])};\n    }\n    if (n <= L) {\n        if (n >= 3 && queries_used < Q) {\n            return do_query(cities);\n        } else {\n            // Fallback: connect in a chain\n            vector<pair<int, int>> edges;\n            for (int i = 0; i < n - 1; i++) {\n                edges.push_back(make_pair(cities[i], cities[i + 1]));\n            }\n            return edges;\n        }\n    } else {\n        // Split into two halves\n        int mid = n / 2;\n        vector<int> A(cities.begin(), cities.begin() + mid);\n        vector<int> B(cities.begin() + mid, cities.end());\n\n        // Ensure both halves have at least 2 cities\n        if (A.size() < 2) {\n            A.push_back(B[0]);\n            B.erase(B.begin());\n        }\n        if (B.size() < 2) {\n            B.push_back(A.back());\n            A.pop_back();\n        }\n\n        // Build trees for both halves\n        vector<pair<int, int>> treeA = build_tree(A);\n        vector<pair<int, int>> treeB = build_tree(B);\n\n        // Connect the two halves\n        vector<pair<int, int>> edges_connect;\n        if (queries_used < Q) {\n            // Choose a set S of size L from the boundary\n            int k = min((int)A.size(), L / 2);\n            int l = L - k;\n            if (l > (int)B.size()) {\n                l = B.size();\n                k = L - l;\n            }\n            vector<int> S;\n            // Add last k cities from A\n            for (int i = A.size() - k; i < A.size(); i++) {\n                S.push_back(A[i]);\n            }\n            // Add first l cities from B\n            for (int i = 0; i < l; i++) {\n                S.push_back(B[i]);\n            }\n            vector<pair<int, int>> edges_S = do_query(S);\n            // Find the first edge that connects A and B\n            set<int> setA(A.begin(), A.end());\n            set<int> setB(B.begin(), B.end());\n            pair<int, int> connect_edge = make_pair(-1, -1);\n            for (auto& e : edges_S) {\n                int u = e.first, v = e.second;\n                if ((setA.count(u) && setB.count(v)) || (setA.count(v) && setB.count(u))) {\n                    connect_edge = e;\n                    break;\n                }\n            }\n            if (connect_edge.first == -1) {\n                // Fallback: connect the last of A and first of B\n                connect_edge = make_pair(A.back(), B[0]);\n            }\n            edges_connect.push_back(connect_edge);\n        } else {\n            // No queries left: use a direct edge between the two halves\n            edges_connect.push_back(make_pair(A.back(), B[0]));\n        }\n\n        // Combine all edges\n        vector<pair<int, int>> result;\n        result.reserve(treeA.size() + treeB.size() + edges_connect.size());\n        result.insert(result.end(), treeA.begin(), treeA.end());\n        result.insert(result.end(), treeB.begin(), treeB.end());\n        result.insert(result.end(), edges_connect.begin(), edges_connect.end());\n        return result;\n    }\n}\n\nint main() {\n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> G[i];\n    }\n    cx.resize(N);\n    cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cx[i] = (lx + rx) / 2;\n        cy[i] = (ly + ry) / 2;\n    }\n\n    // Sort cities by center\n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        if (cx[i] != cx[j]) return cx[i] < cx[j];\n        return cy[i] < cy[j];\n    });\n\n    // Split into groups according to G\n    vector<vector<int>> groups(M);\n    int start = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i] = vector<int>(indices.begin() + start, indices.begin() + start + G[i]);\n        start += G[i];\n    }\n\n    // Build spanning trees for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    for (int i = 0; i < M; i++) {\n        group_edges[i] = build_tree(groups[i]);\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        // Output cities of the group\n        for (int j = 0; j < groups[i].size(); j++) {\n            if (j) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // Output edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nbool can_slide(int r, int c, int tr, int tc, const vector<vector<bool>>& block, int N) {\n    if (r == tr) {\n        if (c < tc) {\n            for (int j = c+1; j <= tc; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc+1 < N) {\n                if (!block[r][tc+1]) return false;\n            }\n            return true;\n        } else if (c > tc) {\n            for (int j = tc; j < c; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc-1 >= 0) {\n                if (!block[r][tc-1]) return false;\n            }\n            return true;\n        }\n    } else if (c == tc) {\n        if (r < tr) {\n            for (int i = r+1; i <= tr; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr+1 < N) {\n                if (!block[tr+1][c]) return false;\n            }\n            return true;\n        } else if (r > tr) {\n            for (int i = tr; i < r; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr-1 >= 0) {\n                if (!block[tr-1][c]) return false;\n            }\n            return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.push_back({r, c});\n    }\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    int r = r0, c = c0;\n    vector<string> actions;\n\n    for (int idx = 0; idx < M; idx++) {\n        int tr = targets[idx].first;\n        int tc = targets[idx].second;\n\n        while (r != tr || c != tc) {\n            if (can_slide(r, c, tr, tc, block, N)) {\n                if (r == tr) {\n                    if (c < tc) {\n                        actions.push_back(\"S R\");\n                        c = tc;\n                    } else {\n                        actions.push_back(\"S L\");\n                        c = tc;\n                    }\n                } else if (c == tc) {\n                    if (r < tr) {\n                        actions.push_back(\"S D\");\n                        r = tr;\n                    } else {\n                        actions.push_back(\"S U\");\n                        r = tr;\n                    }\n                }\n                continue;\n            }\n\n            int dr = tr - r;\n            int dc = tc - c;\n            int adr = abs(dr);\n            int adc = abs(dc);\n\n            if (adr > adc) {\n                if (dr > 0) {\n                    actions.push_back(\"M D\");\n                    r++;\n                } else {\n                    actions.push_back(\"M U\");\n                    r--;\n                }\n            } else if (adc > adr) {\n                if (dc > 0) {\n                    actions.push_back(\"M R\");\n                    c++;\n                } else {\n                    actions.push_back(\"M L\");\n                    c--;\n                }\n            } else {\n                if (tr == N-1 || tr == 0) {\n                    if (dr > 0) {\n                        actions.push_back(\"M D\");\n                        r++;\n                    } else if (dr < 0) {\n                        actions.push_back(\"M U\");\n                        r--;\n                    } else {\n                        if (dc > 0) {\n                            actions.push_back(\"M R\");\n                            c++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            c--;\n                        }\n                    }\n                } else if (tc == N-1 || tc == 0) {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else if (dc < 0) {\n                        actions.push_back(\"M L\");\n                        c--;\n                    } else {\n                        if (dr > 0) {\n                            actions.push_back(\"M D\");\n                            r++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            r--;\n                        }\n                    }\n                } else {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        c--;\n                    }\n                }\n            }\n        }\n    }\n\n    for (const string& action : actions) {\n        cout << action << endl;\n    }\n\n    return 0;\n}"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n;\n    cin >> n;\n\n    vector<Company> companies(n);\n    for (int i = 0; i < n; i++) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n\n    // Sort by desired area descending\n    sort(companies.begin(), companies.end(), [](const Company& a, const Company& b) {\n        return a.r > b.r;\n    });\n\n    vector<Rect> assigned_rects;\n\n    for (int i = 0; i < n; i++) {\n        int L = companies[i].x;\n        int R = companies[i].x + 1;\n        int T = companies[i].y;\n        int B = companies[i].y + 1;\n\n        bool expanded = true;\n        while (expanded) {\n            expanded = false;\n            // try left\n            if (L > 0) {\n                int new_L = L - 1;\n                bool valid = true;\n                // Check centers\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (new_L <= xj && xj < R && T <= yj && yj < B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (new_L < rect.c && rect.a < R && T < rect.d && rect.b < B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    L = new_L;\n                    expanded = true;\n                    continue;\n                }\n            }\n            // try right\n            if (R < 10000) {\n                int new_R = R + 1;\n                bool valid = true;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (L <= xj && xj < new_R && T <= yj && yj < B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (L < rect.c && rect.a < new_R && T < rect.d && rect.b < B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    R = new_R;\n                    expanded = true;\n                    continue;\n                }\n            }\n            // try top\n            if (T > 0) {\n                int new_T = T - 1;\n                bool valid = true;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (L <= xj && xj < R && new_T <= yj && yj < B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (L < rect.c && rect.a < R && new_T < rect.d && rect.b < B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    T = new_T;\n                    expanded = true;\n                    continue;\n                }\n            }\n            // try bottom\n            if (B < 10000) {\n                int new_B = B + 1;\n                bool valid = true;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (L <= xj && xj < R && T <= yj && yj < new_B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (L < rect.c && rect.a < R && T < rect.d && rect.b < new_B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    B = new_B;\n                    expanded = true;\n                    continue;\n                }\n            }\n        }\n\n        // Find best sub-rectangle\n        int max_w = R - L;\n        int max_h = B - T;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - companies[i].r);\n\n        for (int w = 1; w <= max_w; w++) {\n            int left_min = max(L, companies[i].x - w + 1);\n            int left_max = min(companies[i].x, R - w);\n            if (left_min > left_max) continue;\n\n            int h0 = companies[i].r / w;\n            int h1 = (companies[i].r + w - 1) / w;\n            vector<int> candidates = {h0-1, h0, h0+1, h1-1, h1, h1+1};\n            for (int h : candidates) {\n                if (h < 1 || h > max_h) continue;\n                int top_min = max(T, companies[i].y - h + 1);\n                int top_max = min(companies[i].y, B - h);\n                if (top_min > top_max) continue;\n\n                int area = w * h;\n                int diff = abs(area - companies[i].r);\n                if (diff < best_diff) {\n                    best_diff = diff;\n                    best_w = w;\n                    best_h = h;\n                }\n            }\n        }\n\n        int left = max(L, companies[i].x - best_w + 1);\n        int top = max(T, companies[i].y - best_h + 1);\n        cout << left << \" \" << top << \" \" << left + best_w << \" \" << top + best_h << \"\\n\";\n\n        assigned_rects.push_back({left, top, left+best_w, top+best_h});\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int si, sj;\n    cin >> si >> sj;\n    vector<vector<int>> t(50, vector<int>(50));\n    vector<vector<int>> p(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n        }\n    }\n    \n    int M = 0;\n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            if (t[i][j] > M) {\n                M = t[i][j];\n            }\n        }\n    }\n    M++;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n        }\n    }\n    \n    vector<vector<bool>> visited(50, vector<bool>(50, false));\n    vector<bool> leftTiles(M, false);\n    string path = \"\";\n    int i = si, j = sj;\n    visited[i][j] = true;\n    int currentTile = t[i][j];\n    \n    while (true) {\n        vector<tuple<int, int, int, bool>> candidates1;\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 >= 50 || nj < 0 || nj >= 50) continue;\n            if (visited[ni][nj]) continue;\n            int tid = t[ni][nj];\n            if (tid == currentTile) {\n                candidates1.push_back(make_tuple(p[ni][nj], ni, nj, false));\n            } else if (!leftTiles[tid]) {\n                candidates1.push_back(make_tuple(p[ni][nj], ni, nj, true));\n            }\n        }\n        \n        if (candidates1.empty()) break;\n        \n        int best_two_move_score = -1;\n        int best_ni = -1, best_nj = -1;\n        bool best_is_inter = false;\n        \n        int best_one_move_score = -1;\n        int best_one_ni = -1, best_one_nj = -1;\n        bool best_one_is_inter = false;\n        \n        for (auto &cand : candidates1) {\n            int score1 = get<0>(cand);\n            int ni1 = get<1>(cand);\n            int nj1 = get<2>(cand);\n            bool is_inter1 = get<3>(cand);\n            \n            if (score1 > best_one_move_score) {\n                best_one_move_score = score1;\n                best_one_ni = ni1;\n                best_one_nj = nj1;\n                best_one_is_inter = is_inter1;\n            }\n            \n            set<int> temp_left_set;\n            for (int idx = 0; idx < M; idx++) {\n                if (leftTiles[idx]) {\n                    temp_left_set.insert(idx);\n                }\n            }\n            int temp_current = currentTile;\n            if (is_inter1) {\n                temp_left_set.insert(currentTile);\n                temp_current = t[ni1][nj1];\n            }\n            \n            int best_score2 = -1;\n            for (int d2 = 0; d2 < 4; d2++) {\n                int ni2 = ni1 + dx[d2];\n                int nj2 = nj1 + dy[d2];\n                if (ni2 < 0 || ni2 >= 50 || nj2 < 0 || nj2 >= 50) continue;\n                if (visited[ni2][nj2]) continue;\n                if (ni2 == i && nj2 == j) continue;\n                int tid2 = t[ni2][nj2];\n                if (tid2 == temp_current) {\n                    int total_score = score1 + p[ni2][nj2];\n                    if (total_score > best_score2) {\n                        best_score2 = total_score;\n                    }\n                } else if (temp_left_set.find(tid2) == temp_left_set.end()) {\n                    int total_score = score1 + p[ni2][nj2];\n                    if (total_score > best_score2) {\n                        best_score2 = total_score;\n                    }\n                }\n            }\n            \n            if (best_score2 != -1) {\n                if (best_score2 > best_two_move_score) {\n                    best_two_move_score = best_score2;\n                    best_ni = ni1;\n                    best_nj = nj1;\n                    best_is_inter = is_inter1;\n                }\n            }\n        }\n        \n        int chosen_i, chosen_j;\n        bool chosen_is_inter;\n        if (best_two_move_score != -1) {\n            chosen_i = best_ni;\n            chosen_j = best_nj;\n            chosen_is_inter = best_is_inter;\n        } else {\n            if (best_one_move_score == -1) break;\n            chosen_i = best_one_ni;\n            chosen_j = best_one_nj;\n            chosen_is_inter = best_one_is_inter;\n        }\n        \n        int di = chosen_i - i;\n        int dj = chosen_j - j;\n        if (di == -1) path += 'U';\n        else if (di == 1) path += 'D';\n        else if (dj == -1) path += 'L';\n        else if (dj == 1) path += 'R';\n        \n        visited[chosen_i][chosen_j] = true;\n        if (chosen_is_inter) {\n            leftTiles[currentTile] = true;\n            currentTile = t[chosen_i][chosen_j];\n        }\n        i = chosen_i;\n        j = chosen_j;\n    }\n    \n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <string>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nconst double alpha = 0.1;\nconst double low_bound = 1000.0;\nconst double high_bound = 9000.0;\n\ndouble H_est[30][29];\ndouble V_est[29][30];\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\ndouble get_edge_weight(int i, int j, int ni, int nj) {\n    if (ni == i-1 && nj == j) {\n        return V_est[i-1][j];\n    } else if (ni == i+1 && nj == j) {\n        return V_est[i][j];\n    } else if (ni == i && nj == j-1) {\n        return H_est[i][j-1];\n    } else if (ni == i && nj == j+1) {\n        return H_est[i][j];\n    }\n    return 1e18;\n}\n\nvoid update_edge(int i, int j, int ni, int nj, double delta) {\n    if (ni == i-1 && nj == j) {\n        V_est[i-1][j] += delta;\n        if (V_est[i-1][j] < low_bound) V_est[i-1][j] = low_bound;\n        if (V_est[i-1][j] > high_bound) V_est[i-1][j] = high_bound;\n    } else if (ni == i+1 && nj == j) {\n        V_est[i][j] += delta;\n        if (V_est[i][j] < low_bound) V_est[i][j] = low_bound;\n        if (V_est[i][j] > high_bound) V_est[i][j] = high_bound;\n    } else if (ni == i && nj == j-1) {\n        H_est[i][j-1] += delta;\n        if (H_est[i][j-1] < low_bound) H_est[i][j-1] = low_bound;\n        if (H_est[i][j-1] > high_bound) H_est[i][j-1] = high_bound;\n    } else if (ni == i && nj == j+1) {\n        H_est[i][j] += delta;\n        if (H_est[i][j] < low_bound) H_est[i][j] = low_bound;\n        if (H_est[i][j] > high_bound) H_est[i][j] = high_bound;\n    }\n}\n\nstring dijkstra(int si, int sj, int ti, int tj, double &est_length) {\n    vector<vector<double>> dist(30, vector<double>(30, 1e18));\n    vector<vector<pair<int, int>>> parent(30, vector<pair<int, int>>(30, {-1, -1}));\n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<tuple<double, int, int>>> pq;\n    dist[si][sj] = 0.0;\n    pq.push(make_tuple(0.0, si, sj));\n\n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        if (d != dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n            double w = get_edge_weight(i, j, ni, nj);\n            if (dist[ni][nj] > dist[i][j] + w) {\n                dist[ni][nj] = dist[i][j] + w;\n                parent[ni][nj] = make_pair(i, j);\n                pq.push(make_tuple(dist[ni][nj], ni, nj));\n            }\n        }\n    }\n\n    vector<pair<int, int>> path_nodes;\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        path_nodes.push_back({i, j});\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    path_nodes.push_back({si, sj});\n    reverse(path_nodes.begin(), path_nodes.end());\n\n    string path_str = \"\";\n    est_length = 0.0;\n    for (int idx = 0; idx < path_nodes.size()-1; idx++) {\n        int i1 = path_nodes[idx].first;\n        int j1 = path_nodes[idx].second;\n        int i2 = path_nodes[idx+1].first;\n        int j2 = path_nodes[idx+1].second;\n        char move;\n        if (i2 == i1-1) move = 'U';\n        else if (i2 == i1+1) move = 'D';\n        else if (j2 == j1-1) move = 'L';\n        else if (j2 == j1+1) move = 'R';\n        path_str += move;\n\n        double w = get_edge_weight(i1, j1, i2, j2);\n        est_length += w;\n    }\n\n    return path_str;\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 29; j++) {\n            H_est[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 30; j++) {\n            V_est[i][j] = 5000.0;\n        }\n    }\n\n    int si, sj, ti, tj;\n    for (int k = 0; k < 1000; k++) {\n        cin >> si >> sj >> ti >> tj;\n        double est_length;\n        string path = dijkstra(si, sj, ti, tj, est_length);\n        cout << path << endl;\n        cout.flush();\n\n        long long F;\n        cin >> F;\n\n        int n = path.size();\n        if (n == 0) continue;\n\n        double error = static_cast<double>(F) - est_length;\n        double delta = (error * alpha) / n;\n\n        int cur_i = si, cur_j = sj;\n        for (char move : path) {\n            int next_i = cur_i, next_j = cur_j;\n            if (move == 'U') next_i--;\n            else if (move == 'D') next_i++;\n            else if (move == 'L') next_j--;\n            else if (move == 'R') next_j++;\n\n            update_edge(cur_i, cur_j, next_i, next_j, delta);\n\n            cur_i = next_i;\n            cur_j = next_j;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <map>\n#include <set>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Global random generator\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct StringInfo {\n    string s;\n    int id;\n    int len;\n    map<char, int> char_count;\n    set<char> unique_chars;\n    double rarity_score;\n};\n\nbool try_place_horizontal(vector<string>& mat, const string& str, int N) {\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 < str.size(); p++) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < str.size(); p++) {\n                    int col = (j + p) % N;\n                    mat[i][col] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool try_place_vertical(vector<string>& mat, const string& str, int N) {\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            bool ok = true;\n            for (int p = 0; p < str.size(); p++) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < str.size(); p++) {\n                    int row = (i + p) % N;\n                    mat[row][j] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool try_place(vector<string>& mat, const string& str, int N) {\n    if (try_place_horizontal(mat, str, N)) return true;\n    if (try_place_vertical(mat, str, N)) return true;\n    return false;\n}\n\ntuple<int, int, vector<string>> solve_with_order(const vector<StringInfo>& strings, int N, const vector<int>& order) {\n    vector<string> mat(N, string(N, '.'));\n    vector<bool> covered(strings.size(), false);\n    int c = 0;\n    \n    // First pass: place strings in given order\n    for (int idx : order) {\n        if (covered[idx]) continue;\n        const string& str = strings[idx].s;\n        if (try_place(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        }\n    }\n    \n    // Second pass: try uncovered strings with different strategies\n    vector<int> uncovered;\n    for (int i = 0; i < strings.size(); i++) {\n        if (!covered[i]) uncovered.push_back(i);\n    }\n    \n    // Sort uncovered by length descending\n    sort(uncovered.begin(), uncovered.end(), [&](int a, int b) {\n        return strings[a].len > strings[b].len;\n    });\n    \n    for (int idx : uncovered) {\n        if (covered[idx]) continue;\n        const string& str = strings[idx].s;\n        if (try_place(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        }\n    }\n    \n    // Third pass: try with reversed horizontal/vertical order for remaining\n    for (int idx : uncovered) {\n        if (covered[idx]) continue;\n        const string& str = strings[idx].s;\n        // Try vertical first, then horizontal\n        if (try_place_vertical(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        } else if (try_place_horizontal(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        }\n    }\n    \n    // Count dots\n    int d = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (mat[i][j] == '.') d++;\n        }\n    }\n    \n    return make_tuple(c, d, mat);\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> raw_strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> raw_strings[i];\n    }\n    \n    // Analyze strings\n    vector<StringInfo> strings(M);\n    map<char, int> global_char_freq;\n    \n    for (int i = 0; i < M; i++) {\n        strings[i].s = raw_strings[i];\n        strings[i].id = i;\n        strings[i].len = raw_strings[i].size();\n        \n        for (char c : raw_strings[i]) {\n            strings[i].char_count[c]++;\n            strings[i].unique_chars.insert(c);\n            global_char_freq[c]++;\n        }\n    }\n    \n    // Calculate rarity scores (lower frequency = higher rarity score)\n    for (int i = 0; i < M; i++) {\n        double rarity = 0;\n        for (char c : strings[i].unique_chars) {\n            rarity += 1.0 / (global_char_freq[c] + 1);\n        }\n        strings[i].rarity_score = rarity;\n    }\n    \n    // Generate multiple order strategies\n    vector<vector<int>> orders;\n    \n    // Strategy 1: Length descending\n    vector<int> order1(M);\n    iota(order1.begin(), order1.end(), 0);\n    sort(order1.begin(), order1.end(), [&](int a, int b) {\n        return strings[a].len > strings[b].len;\n    });\n    orders.push_back(order1);\n    \n    // Strategy 2: Rarity descending\n    vector<int> order2(M);\n    iota(order2.begin(), order2.end(), 0);\n    sort(order2.begin(), order2.end(), [&](int a, int b) {\n        return strings[a].rarity_score > strings[b].rarity_score;\n    });\n    orders.push_back(order2);\n    \n    // Strategy 3: Length + rarity (combined score)\n    vector<int> order3(M);\n    iota(order3.begin(), order3.end(), 0);\n    sort(order3.begin(), order3.end(), [&](int a, int b) {\n        double score_a = strings[a].len * 10 + strings[a].rarity_score;\n        double score_b = strings[b].len * 10 + strings[b].rarity_score;\n        return score_a > score_b;\n    });\n    orders.push_back(order3);\n    \n    // Strategy 4: Random shuffle\n    vector<int> order4(M);\n    iota(order4.begin(), order4.end(), 0);\n    shuffle(order4.begin(), order4.end(), rng);\n    orders.push_back(order4);\n    \n    // Strategy 5: Reverse length (short first)\n    vector<int> order5(M);\n    iota(order5.begin(), order5.end(), 0);\n    sort(order5.begin(), order5.end(), [&](int a, int b) {\n        return strings[a].len < strings[b].len;\n    });\n    orders.push_back(order5);\n    \n    // Try each strategy and keep the best\n    int best_c = -1;\n    int best_d = -1;\n    vector<string> best_mat;\n    \n    for (const auto& order : orders) {\n        auto [c, d, mat] = solve_with_order(strings, N, order);\n        \n        bool update = false;\n        if (c > best_c) {\n            update = true;\n        } else if (c == best_c) {\n            if (c < M) {\n                // For incomplete coverage, prefer fewer dots (more filled)\n                if (d < best_d) update = true;\n            } else {\n                // For complete coverage, prefer more dots\n                if (d > best_d) update = true;\n            }\n        }\n        \n        if (update) {\n            best_c = c;\n            best_d = d;\n            best_mat = mat;\n        }\n    }\n    \n    // Final optimization: fill remaining dots with most frequent character\n    // But only if we haven't covered all strings (to preserve dots for scoring)\n    if (best_c < M) {\n        // Find most frequent character in current matrix\n        map<char, int> freq;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_mat[i][j] != '.') {\n                    freq[best_mat[i][j]]++;\n                }\n            }\n        }\n        \n        char best_char = 'A';\n        int best_count = -1;\n        for (auto [c, count] : freq) {\n            if (count > best_count) {\n                best_count = count;\n                best_char = c;\n            }\n        }\n        \n        // Fill dots with the most frequent character\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_mat[i][j] == '.') {\n                    best_mat[i][j] = best_char;\n                }\n            }\n        }\n    }\n    \n    // Output the best matrix\n    for (int i = 0; i < N; i++) {\n        cout << best_mat[i] << endl;\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ITER = 100000; // Safeguard against infinite loops\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    // Precompute horizontal and vertical segments\n    vector<vector<int>> hid(N, vector<int>(N, -1));\n    vector<vector<int>> vid(N, vector<int>(N, -1));\n    int totalH = 0, totalV = 0;\n\n    // Horizontal segments\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '#') continue;\n            if (j == 0 || grid[i][j-1] == '#') {\n                int k = j;\n                while (k < N && grid[i][k] != '#') {\n                    hid[i][k] = totalH;\n                    k++;\n                }\n                totalH++;\n            }\n        }\n    }\n\n    // Vertical segments\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][j] == '#') continue;\n            if (i == 0 || grid[i-1][j] == '#') {\n                int k = i;\n                while (k < N && grid[k][j] != '#') {\n                    vid[k][j] = totalV;\n                    k++;\n                }\n                totalV++;\n            }\n        }\n    }\n\n    vector<bool> uncoveredH(totalH, true);\n    vector<bool> uncoveredV(totalV, true);\n\n    // Cover start position's segments\n    int startH = hid[si][sj];\n    int startV = vid[si][sj];\n    if (startH != -1) uncoveredH[startH] = false;\n    if (startV != -1) uncoveredV[startV] = false;\n\n    int cur_i = si, cur_j = sj;\n    string route = \"\";\n\n    int iter = 0;\n    while (iter < MAX_ITER) {\n        // Check if all segments are covered\n        bool has_uncovered = false;\n        for (bool b : uncoveredH) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) for (bool b : uncoveredV) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) break;\n\n        // Run Dijkstra to find shortest paths\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1,-1}));\n        vector<vector<char>> move_dir(N, vector<char>(N, 0));\n        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;\n\n        dist[cur_i][cur_j] = 0;\n        pq.push({0, cur_i, cur_j});\n\n        while (!pq.empty()) {\n            auto [cost, i, j] = pq.top();\n            pq.pop();\n            if (cost != dist[i][j]) continue;\n            const int dx[4] = {-1, 1, 0, 0};\n            const int dy[4] = {0, 0, -1, 1};\n            const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n                if (grid[ni][nj] == '#') continue;\n                int ncost = cost + (grid[ni][nj] - '0');\n                if (ncost < dist[ni][nj]) {\n                    dist[ni][nj] = ncost;\n                    parent[ni][nj] = {i, j};\n                    move_dir[ni][nj] = dirs[d];\n                    pq.push({ncost, ni, nj});\n                }\n            }\n        }\n\n        // Select candidate: prioritize covering more uncovered segments\n        int best_i = -1, best_j = -1;\n        int best_gain = -1;\n        int best_cost = INF;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == '#' || dist[i][j] == INF) continue;\n                int gain = 0;\n                if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) gain++;\n                if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) gain++;\n                if (gain == 0) continue;\n                if (gain > best_gain || (gain == best_gain && dist[i][j] < best_cost)) {\n                    best_gain = gain;\n                    best_cost = dist[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n\n        // If no candidate found, break (shouldn't happen but safe)\n        if (best_i == -1) break;\n\n        // Build path and update coverage\n        string path_moves = \"\";\n        int i = best_i, j = best_j;\n        while (i != cur_i || j != cur_j) {\n            char m = move_dir[i][j];\n            path_moves = m + path_moves;\n            if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) uncoveredH[hid[i][j]] = false;\n            if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) uncoveredV[vid[i][j]] = false;\n            auto [pi, pj] = parent[i][j];\n            i = pi;\n            j = pj;\n        }\n\n        route += path_moves;\n        cur_i = best_i;\n        cur_j = best_j;\n        iter++;\n    }\n\n    // Return to start\n    vector<vector<int>> dist_ret(N, vector<int>(N, INF));\n    vector<vector<pair<int,int>>> parent_ret(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<char>> move_dir_ret(N, vector<char>(N, 0));\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq_ret;\n\n    dist_ret[cur_i][cur_j] = 0;\n    pq_ret.push({0, cur_i, cur_j});\n\n    while (!pq_ret.empty()) {\n        auto [cost, i, j] = pq_ret.top();\n        pq_ret.pop();\n        if (cost != dist_ret[i][j]) continue;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n            if (grid[ni][nj] == '#') continue;\n            int ncost = cost + (grid[ni][nj] - '0');\n            if (ncost < dist_ret[ni][nj]) {\n                dist_ret[ni][nj] = ncost;\n                parent_ret[ni][nj] = {i, j};\n                move_dir_ret[ni][nj] = dirs[d];\n                pq_ret.push({ncost, ni, nj});\n            }\n        }\n    }\n\n    if (dist_ret[si][sj] == INF) {\n        // Should not happen as the grid is connected, but just in case\n        cerr << \"No path back to start!\" << endl;\n    } else {\n        string return_path = \"\";\n        int i = si, j = sj;\n        while (i != cur_i || j != cur_j) {\n            auto [pi, pj] = parent_ret[i][j];\n            char m = move_dir_ret[i][j];\n            return_path = m + return_path;\n            i = pi;\n            j = pj;\n        }\n        route += return_path;\n    }\n\n    cout << route << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <map>\n#include <set>\n#include <cmath>\n#include <iomanip>\n#include <climits>\n\nusing namespace std;\n\nstruct Task {\n    int id;\n    vector<int> requirements;\n    vector<int> children;\n    int in_degree;\n    int depth_forward;\n    double criticality;\n};\n\nstruct TeamMember {\n    int id;\n    vector<int> skills; // estimated skills\n    int current_task; // -1 if free\n    int busy_until; // day when current task will complete (estimated)\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<Task> tasks(N);\n    for (int i = 0; i < N; i++) {\n        tasks[i].id = i;\n        tasks[i].requirements.resize(K);\n        for (int k = 0; k < K; k++) {\n            cin >> tasks[i].requirements[k];\n        }\n        tasks[i].in_degree = 0;\n    }\n    \n    // Read dependencies\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        tasks[u].children.push_back(v);\n        tasks[v].in_degree++;\n    }\n    \n    // Compute depth_forward (longest path to end)\n    for (int i = N-1; i >= 0; i--) {\n        if (tasks[i].children.empty()) {\n            tasks[i].depth_forward = 0;\n        } else {\n            int max_depth = 0;\n            for (int child : tasks[i].children) {\n                max_depth = max(max_depth, tasks[child].depth_forward);\n            }\n            tasks[i].depth_forward = 1 + max_depth;\n        }\n    }\n    \n    // Initialize team members\n    vector<TeamMember> members(M);\n    for (int i = 0; i < M; i++) {\n        members[i].id = i;\n        members[i].skills.assign(K, 0); // Start with 0 skills\n        members[i].current_task = -1;\n        members[i].busy_until = 0;\n    }\n    \n    // State tracking\n    vector<int> task_status(N, -1); // -1: not started, 0: assigned, 1: completed\n    vector<int> start_day(N, -1);\n    vector<int> current_in_degree = [&]() {\n        vector<int> deg(N);\n        for (int i = 0; i < N; i++) deg[i] = tasks[i].in_degree;\n        return deg;\n    }();\n    \n    // Learning parameters\n    const double LEARNING_RATE = 0.2;\n    const int MAX_DAYS = 2000;\n    \n    for (int day = 1; day <= MAX_DAYS; day++) {\n        // Read feedback from previous day\n        if (day > 1) {\n            int n_completed;\n            cin >> n_completed;\n            \n            if (n_completed == -1) {\n                break; // All tasks completed or day limit reached\n            }\n            \n            vector<int> completed_members(n_completed);\n            for (int i = 0; i < n_completed; i++) {\n                cin >> completed_members[i];\n                completed_members[i]--; // Convert to 0-indexed\n            }\n            \n            // Update skills based on completed tasks\n            for (int member_idx : completed_members) {\n                int task_idx = members[member_idx].current_task;\n                if (task_idx == -1) continue;\n                \n                // Calculate actual time taken\n                int time_taken = day - start_day[task_idx];\n                \n                // Update skill estimates\n                if (time_taken > 1) {\n                    int current_gap = 0;\n                    vector<int> gaps(K, 0);\n                    \n                    for (int k = 0; k < K; k++) {\n                        if (tasks[task_idx].requirements[k] > members[member_idx].skills[k]) {\n                            gaps[k] = tasks[task_idx].requirements[k] - members[member_idx].skills[k];\n                            current_gap += gaps[k];\n                        }\n                    }\n                    \n                    if (current_gap > 0) {\n                        double extra_time = time_taken - 1;\n                        for (int k = 0; k < K; k++) {\n                            if (gaps[k] > 0) {\n                                double increase = extra_time * LEARNING_RATE * (gaps[k] / (double)current_gap);\n                                int new_skill = members[member_idx].skills[k] + (int)round(increase);\n                                // Cap at requirement to avoid overestimation\n                                new_skill = min(new_skill, tasks[task_idx].requirements[k]);\n                                members[member_idx].skills[k] = new_skill;\n                            }\n                        }\n                    }\n                }\n                \n                // Mark task as completed\n                task_status[task_idx] = 1;\n                members[member_idx].current_task = -1;\n                members[member_idx].busy_until = 0;\n                \n                // Update dependencies for children\n                for (int child : tasks[task_idx].children) {\n                    current_in_degree[child]--;\n                }\n            }\n        }\n        \n        // Find available tasks (all dependencies completed, not started)\n        vector<int> available_tasks;\n        for (int i = 0; i < N; i++) {\n            if (current_in_degree[i] == 0 && task_status[i] == -1) {\n                available_tasks.push_back(i);\n            }\n        }\n        \n        // Find free team members\n        vector<int> free_members;\n        for (int i = 0; i < M; i++) {\n            if (members[i].current_task == -1) {\n                free_members.push_back(i);\n            }\n        }\n        \n        // If no work to do, output 0 and continue\n        if (available_tasks.empty() || free_members.empty()) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n        \n        // Assign tasks using greedy heuristic\n        vector<pair<int, int>> assignments;\n        \n        // Calculate estimated time for each (member, task) pair\n        auto estimate_time = [&](int member_idx, int task_idx) -> double {\n            int gap = 0;\n            for (int k = 0; k < K; k++) {\n                if (tasks[task_idx].requirements[k] > members[member_idx].skills[k]) {\n                    gap += tasks[task_idx].requirements[k] - members[member_idx].skills[k];\n                }\n            }\n            if (gap == 0) return 1.0;\n            // Expected time: max(1, gap + average_offset) \u2248 gap + 1 (since average offset is 0)\n            return gap + 1.0;\n        };\n        \n        // Greedy assignment: prioritize critical tasks and assign to best member\n        while (!free_members.empty() && !available_tasks.empty()) {\n            // Find the most critical available task\n            int best_task = -1;\n            double best_priority = -1;\n            int best_task_idx = -1;\n            \n            for (int i = 0; i < available_tasks.size(); i++) {\n                int task_idx = available_tasks[i];\n                // Priority: criticality (depth) - we could also consider task requirements\n                double priority = tasks[task_idx].depth_forward;\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_task = task_idx;\n                    best_task_idx = i;\n                }\n            }\n            \n            // Find the best member for this task\n            int best_member = -1;\n            double best_time = 1e9;\n            int best_member_idx = -1;\n            \n            for (int i = 0; i < free_members.size(); i++) {\n                int member_idx = free_members[i];\n                double est_time = estimate_time(member_idx, best_task);\n                if (est_time < best_time) {\n                    best_time = est_time;\n                    best_member = member_idx;\n                    best_member_idx = i;\n                }\n            }\n            \n            // Make assignment\n            assignments.push_back({best_member, best_task});\n            task_status[best_task] = 0;\n            members[best_member].current_task = best_task;\n            start_day[best_task] = day;\n            members[best_member].busy_until = day + (int)ceil(best_time) - 1;\n            \n            // Remove from available lists\n            available_tasks.erase(available_tasks.begin() + best_task_idx);\n            free_members.erase(free_members.begin() + best_member_idx);\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& assignment : assignments) {\n            cout << \" \" << assignment.first + 1 << \" \" << assignment.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Order {\n    int a, b, c, d;\n    int index;\n};\n\nint manhattan(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\n// Calculate cost if we serve order alone (office -> pickup -> delivery -> office)\nint individualCost(const Order& order) {\n    Point office(400, 400);\n    Point pickup(order.a, order.b);\n    Point delivery(order.c, order.d);\n    return manhattan(office, pickup) + manhattan(pickup, delivery) + manhattan(delivery, office);\n}\n\n// Select 50 orders using greedy approach with clustering\nvector<Order> selectOrders(const vector<Order>& allOrders) {\n    vector<Order> selected;\n    \n    // Create a copy to work with\n    vector<Order> remaining = allOrders;\n    \n    // Start with the order closest to office\n    Point office(400, 400);\n    int bestIdx = -1;\n    int bestDist = 1e9;\n    for (int i = 0; i < remaining.size(); i++) {\n        int dist = manhattan(office, Point(remaining[i].a, remaining[i].b));\n        if (dist < bestDist) {\n            bestDist = dist;\n            bestIdx = i;\n        }\n    }\n    selected.push_back(remaining[bestIdx]);\n    remaining.erase(remaining.begin() + bestIdx);\n    \n    // Greedily add orders that are close to already selected ones\n    while (selected.size() < 50 && !remaining.empty()) {\n        int bestRemaining = -1;\n        int bestIncrease = 1e9;\n        \n        for (int i = 0; i < remaining.size(); i++) {\n            // Estimate cost increase by adding this order\n            int minIncrease = 1e9;\n            \n            // Check distance from all selected orders' endpoints\n            for (const Order& sel : selected) {\n                Point selEnd(sel.c, sel.d);\n                Point newPickup(remaining[i].a, remaining[i].b);\n                int inc = manhattan(selEnd, newPickup);\n                minIncrease = min(minIncrease, inc);\n            }\n            \n            // Also consider distance from office\n            int officeInc = manhattan(office, Point(remaining[i].a, remaining[i].b));\n            minIncrease = min(minIncrease, officeInc);\n            \n            if (minIncrease < bestIncrease) {\n                bestIncrease = minIncrease;\n                bestRemaining = i;\n            }\n        }\n        \n        if (bestRemaining != -1) {\n            selected.push_back(remaining[bestRemaining]);\n            remaining.erase(remaining.begin() + bestRemaining);\n        }\n    }\n    \n    // If we still need more orders, fill with those having smallest individual cost\n    while (selected.size() < 50 && !remaining.empty()) {\n        int bestIdx = -1;\n        int bestCost = 1e9;\n        for (int i = 0; i < remaining.size(); i++) {\n            int cost = individualCost(remaining[i]);\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestIdx = i;\n            }\n        }\n        selected.push_back(remaining[bestIdx]);\n        remaining.erase(remaining.begin() + bestIdx);\n    }\n    \n    return selected;\n}\n\n// Build route using greedy approach with precedence constraints\nvector<Point> buildRoute(const vector<Order>& selected) {\n    vector<Point> route;\n    Point office(400, 400);\n    route.push_back(office);\n    \n    // Track which orders have been picked up but not delivered\n    set<int> pickedUp;\n    set<int> delivered;\n    \n    // All orders start as not picked up\n    vector<int> remaining;\n    for (int i = 0; i < selected.size(); i++) {\n        remaining.push_back(i);\n    }\n    \n    Point current = office;\n    \n    while (!remaining.empty() || !pickedUp.empty()) {\n        int bestChoice = -1; // 0-49 for pickup, 50-99 for delivery\n        int bestDist = 1e9;\n        bool isDelivery = false;\n        \n        // Check available pickups\n        for (int idx : remaining) {\n            Point pickup(selected[idx].a, selected[idx].b);\n            int dist = manhattan(current, pickup);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestChoice = idx;\n                isDelivery = false;\n            }\n        }\n        \n        // Check available deliveries\n        for (int idx : pickedUp) {\n            Point delivery(selected[idx].c, selected[idx].d);\n            int dist = manhattan(current, delivery);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestChoice = idx;\n                isDelivery = true;\n            }\n        }\n        \n        if (bestChoice == -1) break;\n        \n        if (isDelivery) {\n            route.push_back(Point(selected[bestChoice].c, selected[bestChoice].d));\n            pickedUp.erase(bestChoice);\n            delivered.insert(bestChoice);\n        } else {\n            route.push_back(Point(selected[bestChoice].a, selected[bestChoice].b));\n            pickedUp.insert(bestChoice);\n            // Remove from remaining\n            for (int i = 0; i < remaining.size(); i++) {\n                if (remaining[i] == bestChoice) {\n                    remaining.erase(remaining.begin() + i);\n                    break;\n                }\n            }\n        }\n        \n        current = route.back();\n    }\n    \n    // Return to office\n    route.push_back(office);\n    \n    return route;\n}\n\n// Improve route using 2-opt like moves respecting precedence\nvector<Point> improveRoute(const vector<Point>& route, const vector<Order>& selected) {\n    vector<Point> improved = route;\n    bool improved_flag = true;\n    \n    // Create mapping from points to orders for precedence checking\n    // For each order, we need to know if pickup has been visited before delivery\n    vector<int> orderPickupIndex(selected.size(), -1);\n    vector<int> orderDeliveryIndex(selected.size(), -1);\n    \n    for (int i = 0; i < improved.size(); i++) {\n        for (int j = 0; j < selected.size(); j++) {\n            if (improved[i].x == selected[j].a && improved[i].y == selected[j].b) {\n                orderPickupIndex[j] = i;\n            }\n            if (improved[i].x == selected[j].c && improved[i].y == selected[j].d) {\n                orderDeliveryIndex[j] = i;\n            }\n        }\n    }\n    \n    // Check if swapping two points maintains precedence\n    auto canSwap = [&](int i, int j) {\n        // If both are from same order, check if swap would violate precedence\n        for (int k = 0; k < selected.size(); k++) {\n            bool iIsPickup = (improved[i].x == selected[k].a && improved[i].y == selected[k].b);\n            bool iIsDelivery = (improved[i].x == selected[k].c && improved[i].y == selected[k].d);\n            bool jIsPickup = (improved[j].x == selected[k].a && improved[j].y == selected[k].b);\n            bool jIsDelivery = (improved[j].x == selected[k].c && improved[j].y == selected[k].d);\n            \n            if (iIsPickup && jIsDelivery) {\n                return false; // Would put delivery before pickup\n            }\n            if (jIsPickup && iIsDelivery) {\n                return false; // Would put delivery before pickup\n            }\n        }\n        return true;\n    };\n    \n    int n = improved.size();\n    while (improved_flag) {\n        improved_flag = false;\n        for (int i = 1; i < n - 2; i++) {\n            for (int j = i + 1; j < n - 1; j++) {\n                if (!canSwap(i, j)) continue;\n                \n                // Calculate cost difference\n                int currentCost = manhattan(improved[i-1], improved[i]) + \n                                 manhattan(improved[i], improved[i+1]) + \n                                 manhattan(improved[j-1], improved[j]) + \n                                 manhattan(improved[j], improved[j+1]);\n                \n                if (i+1 == j) {\n                    // Adjacent swap\n                    int newCost = manhattan(improved[i-1], improved[j]) + \n                                 manhattan(improved[j], improved[i]) + \n                                 manhattan(improved[i], improved[j+1]);\n                    if (newCost < currentCost) {\n                        swap(improved[i], improved[j]);\n                        improved_flag = true;\n                    }\n                } else {\n                    int newCost = manhattan(improved[i-1], improved[j]) + \n                                 manhattan(improved[j], improved[i+1]) + \n                                 manhattan(improved[j-1], improved[i]) + \n                                 manhattan(improved[i], improved[j+1]);\n                    if (newCost < currentCost) {\n                        swap(improved[i], improved[j]);\n                        improved_flag = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    return improved;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read all orders\n    vector<Order> allOrders;\n    for (int i = 0; i < 1000; i++) {\n        Order order;\n        cin >> order.a >> order.b >> order.c >> order.d;\n        order.index = i + 1;\n        allOrders.push_back(order);\n    }\n    \n    // Select 50 orders\n    vector<Order> selected = selectOrders(allOrders);\n    \n    // Build initial route\n    vector<Point> route = buildRoute(selected);\n    \n    // Improve the route\n    route = improveRoute(route, selected);\n    \n    // Output selected orders\n    cout << selected.size();\n    for (const Order& order : selected) {\n        cout << \" \" << order.index;\n    }\n    cout << \"\\n\";\n    \n    // Output route\n    cout << route.size();\n    for (const Point& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int INF = 1000000000;\n\nvector<int> parent;\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<pair<int, int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n    }\n\n    vector<int> d(M);\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        long long dx = x[u] - x[v];\n        long long dy = y[u] - y[v];\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = (int)round(dist);\n    }\n\n    parent.resize(N);\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n\n    vector<vector<int>> count_between(N, vector<int>(N, 0));\n    vector<vector<int>> min_baseline_between(N, vector<int>(N, INF));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        count_between[u][v] = 1;\n        count_between[v][u] = 1;\n        min_baseline_between[u][v] = d[i];\n        min_baseline_between[v][u] = d[i];\n    }\n\n    vector<bool> is_rep(N, true);\n    int adopted_count = 0;\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n\n        int rep_u = find(u);\n        int rep_v = find(v);\n\n        if (rep_u == rep_v) {\n            cout << 0 << endl;\n        } else {\n            int current_count = count_between[rep_u][rep_v];\n            bool adopt = false;\n\n            if (current_count == 1) {\n                adopt = true;\n            } else {\n                if (l_i <= 2 * d[i]) {\n                    adopt = true;\n                } else {\n                    adopt = false;\n                }\n            }\n\n            count_between[rep_u][rep_v] = current_count - 1;\n            count_between[rep_v][rep_u] = current_count - 1;\n\n            if (adopt) {\n                cout << 1 << endl;\n                adopted_count++;\n\n                int new_rep = min(rep_u, rep_v);\n                int old_rep = max(rep_u, rep_v);\n\n                parent[old_rep] = new_rep;\n\n                for (int j = 0; j < N; j++) {\n                    if (is_rep[j] && j != new_rep && j != old_rep) {\n                        count_between[new_rep][j] += count_between[old_rep][j];\n                        if (min_baseline_between[new_rep][j] > min_baseline_between[old_rep][j]) {\n                            min_baseline_between[new_rep][j] = min_baseline_between[old_rep][j];\n                        }\n                        count_between[j][new_rep] = count_between[new_rep][j];\n                        min_baseline_between[j][new_rep] = min_baseline_between[new_rep][j];\n                    }\n                }\n\n                is_rep[old_rep] = false;\n\n                for (int j = 0; j < N; j++) {\n                    count_between[old_rep][j] = 0;\n                    count_between[j][old_rep] = 0;\n                    min_baseline_between[old_rep][j] = INF;\n                    min_baseline_between[j][old_rep] = INF;\n                }\n            } else {\n                cout << 0 << endl;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\nusing namespace std;\n\nconst int dx4[4] = {-1, 1, 0, 0};\nconst int dy4[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int N;\n    cin >> N;\n    vector<int> pet_x(N), pet_y(N), pet_type(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n        pet_x[i]--; \n        pet_y[i]--;\n    }\n\n    int M;\n    cin >> M;\n    vector<int> human_x(M), human_y(M);\n    for (int i = 0; i < M; i++) {\n        cin >> human_x[i] >> human_y[i];\n        human_x[i]--;\n        human_y[i]--;\n    }\n\n    bool blocked[30][30] = {false};\n\n    for (int turn = 0; turn < 300; turn++) {\n        string action_string = \"\";\n        vector<char> actions(M, '.');\n\n        for (int i = 0; i < M; i++) {\n            int hx = human_x[i], hy = human_y[i];\n            int best_dist = 1000;\n            int best_pet = -1;\n            for (int j = 0; j < N; j++) {\n                int dist = abs(hx - pet_x[j]) + abs(hy - pet_y[j]);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pet = j;\n                }\n            }\n\n            if (best_dist <= 3 && best_pet != -1) {\n                int px = pet_x[best_pet], py = pet_y[best_pet];\n                int dx = px - hx;\n                int dy = py - hy;\n                int block_x = hx, block_y = hy;\n                if (abs(dx) > abs(dy)) {\n                    block_x += (dx > 0 ? 1 : -1);\n                } else {\n                    block_y += (dy > 0 ? 1 : -1);\n                }\n                if (block_x >= 0 && block_x < 30 && block_y >= 0 && block_y < 30) {\n                    bool occupied = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == block_x && pet_y[j] == block_y) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    if (!occupied) {\n                        for (int j = 0; j < M; j++) {\n                            if (human_x[j] == block_x && human_y[j] == block_y) {\n                                occupied = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (!occupied) {\n                        bool adjacent_pet = false;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = block_x + dx4[d];\n                            int ny = block_y + dy4[d];\n                            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                            for (int j = 0; j < N; j++) {\n                                if (pet_x[j] == nx && pet_y[j] == ny) {\n                                    adjacent_pet = true;\n                                    break;\n                                }\n                            }\n                            if (adjacent_pet) break;\n                        }\n                        if (!adjacent_pet) {\n                            if (block_x == hx - 1) actions[i] = 'u';\n                            else if (block_x == hx + 1) actions[i] = 'd';\n                            else if (block_y == hy - 1) actions[i] = 'l';\n                            else if (block_y == hy + 1) actions[i] = 'r';\n                        }\n                    }\n                }\n                if (actions[i] == '.') {\n                    if (abs(dx) > abs(dy)) {\n                        if (dx > 0) actions[i] = 'U';\n                        else actions[i] = 'D';\n                    } else {\n                        if (dy > 0) actions[i] = 'L';\n                        else actions[i] = 'R';\n                    }\n                    int nx = hx, ny = hy;\n                    if (actions[i] == 'U') nx--;\n                    else if (actions[i] == 'D') nx++;\n                    else if (actions[i] == 'L') ny--;\n                    else if (actions[i] == 'R') ny++;\n                    if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30 || blocked[nx][ny]) {\n                        actions[i] = '.';\n                    } else {\n                        bool has_pet = false;\n                        for (int j = 0; j < N; j++) {\n                            if (pet_x[j] == nx && pet_y[j] == ny) {\n                                has_pet = true;\n                                break;\n                            }\n                        }\n                        if (has_pet) {\n                            actions[i] = '.';\n                        }\n                    }\n                }\n            } else {\n                int target_x = 14, target_y = 14;\n                int dx = target_x - hx;\n                int dy = target_y - hy;\n                if (abs(dx) > abs(dy)) {\n                    if (dx > 0) actions[i] = 'D';\n                    else actions[i] = 'U';\n                } else {\n                    if (dy > 0) actions[i] = 'R';\n                    else actions[i] = 'L';\n                }\n                int nx = hx, ny = hy;\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30 || blocked[nx][ny]) {\n                    actions[i] = '.';\n                } else {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (has_pet) {\n                        actions[i] = '.';\n                    }\n                }\n            }\n            action_string += actions[i];\n        }\n\n        cout << action_string << endl;\n        cout.flush();\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u' || actions[i] == 'd' || actions[i] == 'l' || actions[i] == 'r') {\n                int bx = human_x[i];\n                int by = human_y[i];\n                if (actions[i] == 'u') bx--;\n                else if (actions[i] == 'd') bx++;\n                else if (actions[i] == 'l') by--;\n                else if (actions[i] == 'r') by++;\n                if (bx >= 0 && bx < 30 && by >= 0 && by < 30) {\n                    blocked[bx][by] = true;\n                }\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U' || actions[i] == 'D' || actions[i] == 'L' || actions[i] == 'R') {\n                int nx = human_x[i];\n                int ny = human_y[i];\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx >= 0 && nx < 30 && ny >= 0 && ny < 30 && !blocked[nx][ny]) {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (!has_pet) {\n                        human_x[i] = nx;\n                        human_y[i] = ny;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            string move_str;\n            cin >> move_str;\n            if (move_str == \".\") continue;\n            for (char c : move_str) {\n                if (c == 'U') pet_x[i]--;\n                else if (c == 'D') pet_x[i]++;\n                else if (c == 'L') pet_y[i]--;\n                else if (c == 'R') pet_y[i]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <tuple>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int s_i, s_j, t_i, t_j;\n    double p;\n    cin >> s_i >> s_j >> t_i >> t_j >> p;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n\n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n\n    vector<vector<int>> dist(20, vector<int>(20, INT_MAX));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move_char(20, vector<char>(20, ' '));\n\n    queue<pair<int, int>> q;\n    dist[s_i][s_j] = 0;\n    q.push({s_i, s_j});\n\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (i == t_i && j == t_j) break;\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 >= 20 || nj < 0 || nj >= 20) continue;\n\n            bool canMove = true;\n            if (d == 0) {\n                if (i == 0) canMove = false;\n                else if (v[i-1][j] == '1') canMove = false;\n            } else if (d == 1) {\n                if (i == 19) canMove = false;\n                else if (v[i][j] == '1') canMove = false;\n            } else if (d == 2) {\n                if (j == 0) canMove = false;\n                else if (h[i][j-1] == '1') canMove = false;\n            } else if (d == 3) {\n                if (j == 19) canMove = false;\n                else if (h[i][j] == '1') canMove = false;\n            }\n\n            if (canMove && dist[ni][nj] == INT_MAX) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent[ni][nj] = {i, j};\n                move_char[ni][nj] = dir_char[d];\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    string path = \"\";\n    int i = t_i, j = t_j;\n    while (i != s_i || j != s_j) {\n        path += move_char[i][j];\n        auto [pi, pj] = parent[i][j];\n        i = pi;\n        j = pj;\n    }\n    reverse(path.begin(), path.end());\n\n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n\n    int L0 = path.size();\n    int r = 200 / L0;\n    if (r < 1) r = 1;\n\n    string result = \"\";\n    for (char c : path) {\n        for (int i = 0; i < r; i++) {\n            result += c;\n        }\n    }\n\n    if (result.size() > 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 di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nconst int base_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 to_table[8][4][4];\n\nvoid precompute_to_table() {\n    for (int t = 0; t < 8; t++) {\n        for (int r = 0; r < 4; r++) {\n            for (int d = 0; d < 4; d++) {\n                int s_in_orig = (d + r) % 4;\n                int s_out_orig = base_to[t][s_in_orig];\n                if (s_out_orig == -1) {\n                    to_table[t][r][d] = -1;\n                } else {\n                    to_table[t][r][d] = (s_out_orig - r + 4) % 4;\n                }\n            }\n        }\n    }\n}\n\nlong long compute_score(const vector<vector<int>>& grid, const vector<vector<int>>& rotations) {\n    bool visited[30][30][4] = {};\n    vector<long long> cycles;\n\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int si = i, sj = j, sd = d;\n                    int ci = i, cj = j, cd = d;\n                    long long steps = 0;\n                    bool is_cycle = false;\n                    while (true) {\n                        if (visited[ci][cj][cd]) {\n                            break;\n                        }\n                        visited[ci][cj][cd] = true;\n                        int t = grid[ci][cj];\n                        int r = rotations[ci][cj];\n                        int d2 = to_table[t][r][cd];\n                        if (d2 == -1) {\n                            break;\n                        }\n                        int ni = ci + di[d2];\n                        int nj = cj + dj[d2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            break;\n                        }\n                        int nd = (d2 + 2) % 4;\n                        ci = ni;\n                        cj = nj;\n                        cd = nd;\n                        steps++;\n                        if (ci == si && cj == sj && cd == sd) {\n                            is_cycle = true;\n                            break;\n                        }\n                    }\n                    if (is_cycle) {\n                        cycles.push_back(steps);\n                    }\n                }\n            }\n        }\n    }\n\n    if (cycles.size() < 2) {\n        return 0;\n    }\n    sort(cycles.rbegin(), cycles.rend());\n    return cycles[0] * cycles[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    precompute_to_table();\n    const int num_test_cases = 100;\n\n    random_device rd;\n    mt19937 base_rng(rd());\n\n    for (int tc = 0; tc < num_test_cases; tc++) {\n        vector<vector<int>> grid(30, vector<int>(30));\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                cin >> grid[i][j];\n            }\n        }\n\n        mt19937 rng(base_rng());\n        vector<vector<int>> rotations(30, vector<int>(30));\n        uniform_int_distribution<int> dist(0, 3);\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                rotations[i][j] = dist(rng);\n            }\n        }\n\n        long long current_score = compute_score(grid, rotations);\n\n        int num_passes = 1;\n        for (int pass = 0; pass < num_passes; pass++) {\n            vector<pair<int, int>> tiles;\n            for (int i = 0; i < 30; i++) {\n                for (int j = 0; j < 30; j++) {\n                    tiles.push_back({i, j});\n                }\n            }\n            shuffle(tiles.begin(), tiles.end(), rng);\n\n            for (auto [i, j] : tiles) {\n                int best_rot = rotations[i][j];\n                long long best_score = current_score;\n                int orig_rot = rotations[i][j];\n\n                for (int r = 0; r < 4; r++) {\n                    if (r == orig_rot) continue;\n                    rotations[i][j] = r;\n                    long long score = compute_score(grid, rotations);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_rot = r;\n                    }\n                }\n\n                if (best_rot != orig_rot) {\n                    rotations[i][j] = best_rot;\n                    current_score = best_score;\n                } else {\n                    rotations[i][j] = orig_rot;\n                }\n            }\n        }\n\n        string output;\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                output += ('0' + rotations[i][j]);\n            }\n        }\n        cout << output << endl;\n    }\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <unordered_set>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nconst int MAX_N = 10;\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\n// Directions: U, D, L, R\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Cache for component computations\nvector<vector<int>> comp_id;\nvector<int> comp_size;\nint comp_counter = 0;\n\n// Hash function for board state\nstruct BoardHash {\n    size_t operator()(const vector<vector<int>>& b) const {\n        size_t h = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                h = h * 131 + b[i][j];\n            }\n        }\n        return h;\n    }\n};\n\n// Compute connected components with cycle detection\nvoid compute_components() {\n    comp_id.assign(N, vector<int>(N, -1));\n    comp_size.clear();\n    comp_counter = 0;\n    \n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            // BFS to find component\n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            comp_id[i][j] = comp_counter;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                size++;\n                \n                // Check all four directions\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    if (visited[nx][ny]) continue;\n                    \n                    // Check if there's a connection\n                    bool connected = false;\n                    if (d == 0 && (board[x][y] & 2) && (board[nx][ny] & 8)) connected = true; // U\n                    else if (d == 1 && (board[x][y] & 8) && (board[nx][ny] & 2)) connected = true; // D\n                    else if (d == 2 && (board[x][y] & 1) && (board[nx][ny] & 4)) connected = true; // L\n                    else if (d == 3 && (board[x][y] & 4) && (board[nx][ny] & 1)) connected = true; // R\n                    \n                    if (connected) {\n                        visited[nx][ny] = true;\n                        comp_id[nx][ny] = comp_counter;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            comp_size.push_back(size);\n            comp_counter++;\n        }\n    }\n}\n\n// Get the size of the largest tree (connected component without cycles)\nint get_largest_tree_size() {\n    compute_components();\n    \n    // For each component, check if it's a tree (connected, no cycles)\n    // A connected component with V vertices is a tree if it has exactly V-1 edges\n    vector<int> comp_edges(comp_counter, 0);\n    vector<bool> is_tree(comp_counter, true);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            int cid = comp_id[i][j];\n            \n            // Count edges from this tile\n            int edges = 0;\n            if (i > 0 && board[i-1][j] != 0 && (board[i][j] & 2) && (board[i-1][j] & 8)) edges++;\n            if (i < N-1 && board[i+1][j] != 0 && (board[i][j] & 8) && (board[i+1][j] & 2)) edges++;\n            if (j > 0 && board[i][j-1] != 0 && (board[i][j] & 1) && (board[i][j-1] & 4)) edges++;\n            if (j < N-1 && board[i][j+1] != 0 && (board[i][j] & 4) && (board[i][j+1] & 1)) edges++;\n            \n            comp_edges[cid] += edges;\n        }\n    }\n    \n    // Check if each component is a tree: edges = vertices - 1\n    int max_tree = 0;\n    for (int cid = 0; cid < comp_counter; cid++) {\n        if (comp_size[cid] == 0) continue;\n        if (comp_edges[cid] / 2 == comp_size[cid] - 1) { // Each edge counted twice\n            max_tree = max(max_tree, comp_size[cid]);\n        }\n    }\n    \n    return max_tree;\n}\n\n// Evaluate a move and return the resulting tree size\nint evaluate_move(int move, vector<vector<int>>& current_board, int ei, int ej) {\n    int ni = ei + di[move];\n    int nj = ej + dj[move];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return -1;\n    \n    swap(current_board[ei][ej], current_board[ni][nj]);\n    int score = get_largest_tree_size();\n    swap(current_board[ei][ej], current_board[ni][nj]); // backtrack\n    \n    return score;\n}\n\n// Lookahead search with limited depth\nint lookahead_search(int depth, vector<vector<int>>& current_board, int ei, int ej, string& best_seq, int current_best) {\n    if (depth == 0) {\n        int score = get_largest_tree_size();\n        if (score > current_best) {\n            current_best = score;\n        }\n        return current_best;\n    }\n    \n    for (int d = 0; d < 4; d++) {\n        int ni = ei + di[d];\n        int nj = ej + dj[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        \n        swap(current_board[ei][ej], current_board[ni][nj]);\n        int score = lookahead_search(depth-1, current_board, ni, nj, best_seq, current_best);\n        if (score > current_best) {\n            current_best = score;\n            best_seq = dir_char[d] + best_seq; // Note: this builds sequence in reverse\n        }\n        swap(current_board[ei][ej], current_board[ni][nj]);\n    }\n    \n    return current_best;\n}\n\nint main() {\n    auto start_time = high_resolution_clock::now();\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(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            char c = s[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = 10 + c - 'a';\n            }\n            if (board[i][j] == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int current_tree_size = get_largest_tree_size();\n    int target_size = N * N - 1;\n    \n    // If already optimal\n    if (current_tree_size == target_size) {\n        cout << result << endl;\n        return 0;\n    }\n    \n    // Main loop with time management\n    for (int step = 0; step < T; step++) {\n        auto current_time = high_resolution_clock::now();\n        auto elapsed = duration_cast<milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break; // Leave margin for time limit\n        \n        // Try to find best move with lookahead\n        int best_score = -1;\n        int best_move = -1;\n        \n        // First, try immediate moves\n        for (int d = 0; d < 4; d++) {\n            int score = evaluate_move(d, board, empty_i, empty_j);\n            if (score > best_score) {\n                best_score = score;\n                best_move = d;\n            }\n        }\n        \n        // If we have time, try 2-step lookahead for promising moves\n        if (step < T - 2 && elapsed < 2500) {\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                swap(board[empty_i][empty_j], board[ni][nj]);\n                \n                // Try second moves\n                for (int d2 = 0; d2 < 4; d2++) {\n                    if (d2 == d) continue; // Don't immediately undo\n                    int score2 = evaluate_move(d2, board, ni, nj);\n                    if (score2 > best_score) {\n                        best_score = score2;\n                        best_move = d;\n                    }\n                }\n                \n                swap(board[empty_i][empty_j], board[ni][nj]);\n            }\n        }\n        \n        // If no improvement, try random moves to escape local optima\n        if (best_score <= current_tree_size && step > T/2) {\n            vector<int> valid_moves;\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    valid_moves.push_back(d);\n                }\n            }\n            if (!valid_moves.empty()) {\n                best_move = valid_moves[rand() % valid_moves.size()];\n                best_score = evaluate_move(best_move, board, empty_i, empty_j);\n            }\n        }\n        \n        // If still no good move, break\n        if (best_move == -1) break;\n        \n        // Execute the best move\n        int ni = empty_i + di[best_move];\n        int nj = empty_j + dj[best_move];\n        swap(board[empty_i][empty_j], board[ni][nj]);\n        empty_i = ni;\n        empty_j = nj;\n        result += dir_char[best_move];\n        \n        current_tree_size = best_score;\n        \n        // If we achieved full tree, we can break early\n        if (current_tree_size == target_size) {\n            // We'll continue to try to reduce moves, but break if time is short\n            if (duration_cast<milliseconds>(high_resolution_clock::now() - start_time).count() > 2500) {\n                break;\n            }\n        }\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Line {\n    Point p1, p2;\n};\n\nbool passes_through(const Line& l, const Point& s) {\n    ll dx = l.p2.x - l.p1.x;\n    ll dy = l.p2.y - l.p1.y;\n    ll cross = dx * (s.y - l.p1.y) - dy * (s.x - l.p1.x);\n    return cross == 0;\n}\n\nbool parallel(const Line& l1, const Line& l2) {\n    ll dx1 = l1.p2.x - l1.p1.x;\n    ll dy1 = l1.p2.y - l1.p1.y;\n    ll dx2 = l2.p2.x - l2.p1.x;\n    ll dy2 = l2.p2.y - l2.p1.y;\n    return dx1 * dy2 == dx2 * dy1;\n}\n\nbool concurrent(const Line& l1, const Line& l2, const Line& l3) {\n    ll dx1 = l1.p2.x - l1.p1.x;\n    ll dy1 = l1.p2.y - l1.p1.y;\n    ll a1 = dy1;\n    ll b1 = -dx1;\n    ll c1 = dy1 * l1.p1.x - dx1 * l1.p1.y;\n\n    ll dx2 = l2.p2.x - l2.p1.x;\n    ll dy2 = l2.p2.y - l2.p1.y;\n    ll a2 = dy2;\n    ll b2 = -dx2;\n    ll c2 = dy2 * l2.p1.x - dx2 * l2.p1.y;\n\n    ll dx3 = l3.p2.x - l3.p1.x;\n    ll dy3 = l3.p2.y - l3.p1.y;\n    ll a3 = dy3;\n    ll b3 = -dx3;\n    ll c3 = dy3 * l3.p1.x - dx3 * l3.p1.y;\n\n    __int128 det = (__int128)a1 * b2 - (__int128)a2 * b1;\n    if (det == 0) return false;\n\n    __int128 left = (__int128)a3 * ((__int128)c1 * b2 - (__int128)c2 * b1) + (__int128)b3 * ((__int128)a1 * c2 - (__int128)a2 * c1);\n    __int128 right = (__int128)c3 * det;\n\n    return left == right;\n}\n\nLine generate_line() {\n    Line l;\n    l.p1.x = rand() % 2000000001 - 1000000000;\n    l.p1.y = rand() % 2000000001 - 1000000000;\n    l.p2.x = rand() % 2000000001 - 1000000000;\n    l.p2.y = rand() % 2000000001 - 1000000000;\n    while (l.p1.x == l.p2.x && l.p1.y == l.p2.y) {\n        l.p2.x = rand() % 2000000001 - 1000000000;\n        l.p2.y = rand() % 2000000001 - 1000000000;\n    }\n    return l;\n}\n\nint main() {\n    srand(time(0));\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    vector<Line> lines;\n    for (int i = 0; i < 100; i++) {\n        Line l;\n        bool valid = false;\n        while (!valid) {\n            l = generate_line();\n            bool through = false;\n            for (const Point& s : strawberries) {\n                if (passes_through(l, s)) {\n                    through = true;\n                    break;\n                }\n            }\n            if (through) continue;\n\n            bool is_parallel = false;\n            for (const Line& existing : lines) {\n                if (parallel(existing, l)) {\n                    is_parallel = true;\n                    break;\n                }\n            }\n            if (is_parallel) continue;\n\n            bool is_concurrent = false;\n            for (int j = 0; j < (int)lines.size(); j++) {\n                for (int k = j + 1; k < (int)lines.size(); k++) {\n                    if (concurrent(lines[j], lines[k], l)) {\n                        is_concurrent = true;\n                        break;\n                    }\n                }\n                if (is_concurrent) break;\n            }\n            if (is_concurrent) continue;\n            valid = true;\n        }\n        lines.push_back(l);\n    }\n\n    map<string, int> piece_count;\n    for (const Point& s : strawberries) {\n        string key;\n        for (const Line& l : lines) {\n            ll dx = l.p2.x - l.p1.x;\n            ll dy = l.p2.y - l.p1.y;\n            ll cross = dx * (s.y - l.p1.y) - dy * (s.x - l.p1.x);\n            key += (cross > 0) ? '1' : '0';\n        }\n        piece_count[key]++;\n    }\n\n    vector<int> b(11, 0);\n    for (const auto& p : piece_count) {\n        int size = p.second;\n        if (size >= 1 && size <= 10) {\n            b[size]++;\n        }\n    }\n\n    cout << lines.size() << endl;\n    for (const Line& l : lines) {\n        cout << l.p1.x << \" \" << l.p1.y << \" \" << l.p2.x << \" \" << l.p2.y << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <unordered_set>\n#include <queue>\nusing namespace std;\n\nusing Point = pair<int, int>;\nusing Segment = pair<Point, Point>;\n\nstruct Candidate {\n    Point new_dot;\n    vector<Point> existing;\n    int type; // 0: axis-aligned, 1: 45-degree square\n    int weight;\n};\n\nSegment make_segment(Point a, Point b) {\n    if (a < b) {\n        return {a, b};\n    } else {\n        return {b, a};\n    }\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<Point> initial_dots;\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> row_set(N);\n    vector<set<int>> col_set(N);\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initial_dots.push_back({x, y});\n        grid[x][y] = true;\n        row_set[y].insert(x);\n        col_set[x].insert(y);\n    }\n\n    int c = (N-1)/2;\n    auto weight_func = [c](int x, int y) {\n        int dx = x - c;\n        int dy = y - c;\n        return dx*dx + dy*dy + 1;\n    };\n\n    set<Segment> drawn_segments;\n    vector<vector<int>> operations;\n\n    int max_operations = 10000;\n    int K_top = 1000;\n\n    for (int iter = 0; iter < max_operations; iter++) {\n        vector<Candidate> candidates;\n\n        for (int y = 0; y < N; y++) {\n            if (row_set[y].size() < 2) continue;\n            vector<int> xs(row_set[y].begin(), row_set[y].end());\n            sort(xs.begin(), xs.end());\n            for (int i = 0; i < xs.size(); i++) {\n                for (int j = i+1; j < xs.size(); j++) {\n                    int x1 = xs[i], x2 = xs[j];\n                    for (int y1 : col_set[x1]) {\n                        if (y1 == y) continue;\n                        if (!grid[x2][y1]) {\n                            Point new_dot = {x2, y1};\n                            vector<Point> existing = {{x1,y}, {x2,y}, {x1,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                    for (int y1 : col_set[x2]) {\n                        if (y1 == y) continue;\n                        if (!grid[x1][y1]) {\n                            Point new_dot = {x1, y1};\n                            vector<Point> existing = {{x1,y}, {x2,y}, {x2,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            if (col_set[x].size() < 2) continue;\n            vector<int> ys(col_set[x].begin(), col_set[x].end());\n            sort(ys.begin(), ys.end());\n            for (int i = 0; i < ys.size(); i++) {\n                for (int j = i+1; j < ys.size(); j++) {\n                    int y1 = ys[i], y2 = ys[j];\n                    for (int x1 : row_set[y1]) {\n                        if (x1 == x) continue;\n                        if (!grid[x1][y2]) {\n                            Point new_dot = {x1, y2};\n                            vector<Point> existing = {{x,y1}, {x,y2}, {x1,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                    for (int x1 : row_set[y2]) {\n                        if (x1 == x) continue;\n                        if (!grid[x1][y1]) {\n                            Point new_dot = {x1, y1};\n                            vector<Point> existing = {{x,y1}, {x,y2}, {x1,y2}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y]) continue;\n                int w = weight_func(x, y);\n                for (int type = 0; type < 4; type++) {\n                    if (type == 0) {\n                        int a_max = min({x, N-1-x, y/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x+a, y-a};\n                            Point C = {x, y-2*a};\n                            Point D = {x-a, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 1) {\n                        int a_max = min({y, N-1-y, (N-1-x)/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x, y+a};\n                            Point C = {x+2*a, y};\n                            Point D = {x, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 2) {\n                        int a_max = min({N-1-x, N-1-y, (N-1-y)/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x+a, y+a};\n                            Point C = {x, y+2*a};\n                            Point D = {x-a, y+a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 3) {\n                        int a_max = min({y, N-1-y, x/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x, y+a};\n                            Point C = {x-2*a, y};\n                            Point D = {x, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (candidates.empty()) {\n            break;\n        }\n\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            return a.weight > b.weight;\n        });\n\n        if (candidates.size() > K_top) {\n            candidates.resize(K_top);\n        }\n\n        bool found_valid = false;\n        for (const Candidate& cand : candidates) {\n            Point new_dot = cand.new_dot;\n            vector<Point> existing = cand.existing;\n            int type = cand.type;\n\n            set<Point> corners = {new_dot, existing[0], existing[1], existing[2]};\n\n            bool condition2_ok = true;\n            vector<Point> perimeter_points;\n\n            if (type == 0) {\n                int x_min = new_dot.first;\n                int x_max = new_dot.first;\n                int y_min = new_dot.second;\n                int y_max = new_dot.second;\n                for (const Point& p : existing) {\n                    x_min = min(x_min, p.first);\n                    x_max = max(x_max, p.first);\n                    y_min = min(y_min, p.second);\n                    y_max = max(y_max, p.second);\n                }\n                for (int x = x_min; x <= x_max; x++) {\n                    perimeter_points.push_back({x, y_min});\n                    perimeter_points.push_back({x, y_max});\n                }\n                for (int y = y_min+1; y < y_max; y++) {\n                    perimeter_points.push_back({x_min, y});\n                    perimeter_points.push_back({x_max, y});\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = abs(dx);\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k <= steps; k++) {\n                        perimeter_points.push_back(current);\n                        if (k < steps) {\n                            current.first += sx;\n                            current.second += sy;\n                        }\n                    }\n                }\n            }\n\n            for (const Point& p : perimeter_points) {\n                if (corners.find(p) == corners.end() && grid[p.first][p.second]) {\n                    condition2_ok = false;\n                    break;\n                }\n            }\n            if (!condition2_ok) continue;\n\n            bool condition3_ok = true;\n            vector<Segment> new_segments;\n\n            if (type == 0) {\n                int x_min = new_dot.first;\n                int x_max = new_dot.first;\n                int y_min = new_dot.second;\n                int y_max = new_dot.second;\n                for (const Point& p : existing) {\n                    x_min = min(x_min, p.first);\n                    x_max = max(x_max, p.first);\n                    y_min = min(y_min, p.second);\n                    y_max = max(y_max, p.second);\n                }\n                for (int x = x_min; x < x_max; x++) {\n                    Segment seg = make_segment({x, y_min}, {x+1, y_min});\n                    new_segments.push_back(seg);\n                }\n                for (int x = x_min; x < x_max; x++) {\n                    Segment seg = make_segment({x, y_max}, {x+1, y_max});\n                    new_segments.push_back(seg);\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    Segment seg = make_segment({x_min, y}, {x_min, y+1});\n                    new_segments.push_back(seg);\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    Segment seg = make_segment({x_max, y}, {x_max, y+1});\n                    new_segments.push_back(seg);\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = abs(dx);\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k < steps; k++) {\n                        Point next = {current.first + sx, current.second + sy};\n                        Segment seg = make_segment(current, next);\n                        new_segments.push_back(seg);\n                        current = next;\n                    }\n                }\n            }\n\n            for (const Segment& seg : new_segments) {\n                if (drawn_segments.find(seg) != drawn_segments.end()) {\n                    condition3_ok = false;\n                    break;\n                }\n            }\n            if (!condition3_ok) continue;\n\n            for (const Segment& seg : new_segments) {\n                drawn_segments.insert(seg);\n            }\n            grid[new_dot.first][new_dot.second] = true;\n            row_set[new_dot.second].insert(new_dot.first);\n            col_set[new_dot.first].insert(new_dot.second);\n\n            vector<int> op;\n            op.push_back(new_dot.first);\n            op.push_back(new_dot.second);\n            for (const Point& p : existing) {\n                op.push_back(p.first);\n                op.push_back(p.second);\n            }\n            operations.push_back(op);\n\n            found_valid = true;\n            break;\n        }\n\n        if (!found_valid) {\n            break;\n        }\n    }\n\n    cout << operations.size() << endl;\n    for (const vector<int>& op : operations) {\n        for (int i = 0; i < op.size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nvector<vector<int>> tilt_grid(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> new_grid(10, vector<int>(10, 0));\n    if (dir == 'F') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 9;\n            for (int k = candies.size() - 1; k >= 0; k--) {\n                new_grid[idx][j] = candies[k];\n                idx--;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 0;\n            for (int k = 0; k < candies.size(); k++) {\n                new_grid[idx][j] = candies[k];\n                idx++;\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 0;\n            for (int k = 0; k < candies.size(); k++) {\n                new_grid[i][idx] = candies[k];\n                idx++;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) {\n                    candies.push_back(grid[i][j]);\n                }\n            }\n            int idx = 9;\n            for (int k = candies.size() - 1; k >= 0; k--) {\n                new_grid[i][idx] = candies[k];\n                idx--;\n            }\n        }\n    }\n    return new_grid;\n}\n\nint compute_components(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dx[4] = {1, -1, 0, 0};\n    int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0 && !visited[i][j]) {\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int flavor = grid[i][j];\n                int size = 0;\n\n                while (!q.empty()) {\n                    int x = q.front().first;\n                    int y = q.front().second;\n                    q.pop();\n                    size++;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x + dx[d];\n                        int ny = y + dy[d];\n                        if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n\n        int count = 0;\n        int i0 = -1, j0 = -1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == 0) {\n                    count++;\n                    if (count == p) {\n                        i0 = i;\n                        j0 = j;\n                        break;\n                    }\n                }\n            }\n            if (i0 != -1) break;\n        }\n\n        grid[i0][j0] = flavors[t];\n\n        int best_score = -1;\n        char best_dir = 'F';\n        string dirs = \"FBLR\";\n        for (char d : dirs) {\n            vector<vector<int>> temp_grid = grid;\n            vector<vector<int>> tilted = tilt_grid(temp_grid, d);\n            int score = compute_components(tilted);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        cout << best_dir << endl;\n\n        grid = tilt_grid(grid, best_dir);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\nusing namespace std;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    const int N = 100;\n    const int T = N * (N - 1) / 2;\n    int g = T / (M - 1);\n\n    vector<vector<int>> proto_degrees(M, vector<int>(N, 0));\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        vector<int> deg(N, 0);\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (count < edge_count) {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                count++;\n            }\n        }\n        sort(deg.begin(), deg.end());\n        proto_degrees[k] = deg;\n    }\n\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        string s = \"\";\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (count < edge_count) {\n                    s += '1';\n                } else {\n                    s += '0';\n                }\n                count++;\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        vector<int> obs_deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (s[idx] == '1') {\n                    obs_deg[i]++;\n                    obs_deg[j]++;\n                }\n                idx++;\n            }\n        }\n        sort(obs_deg.begin(), obs_deg.end());\n        double best_dist = 1e18;\n        int best_k = 0;\n        for (int k = 0; k < M; k++) {\n            double dist = 0.0;\n            for (int i = 0; i < N; i++) {\n                double diff = obs_deg[i] - proto_degrees[k][i];\n                dist += diff * diff;\n            }\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_k = k;\n            }\n        }\n        cout << best_k << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long LL;\ntypedef long double LD;\n\nstruct Edge {\n    int to;\n    LL w;\n    int id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<tuple<int, int, LL>> edges;\n    vector<vector<Edge>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        LL w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges.push_back({u, v, w});\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<LD> betweenness(M, 0.0);\n\n    for (int s = 0; s < N; s++) {\n        vector<LL> dist(N, LLONG_MAX);\n        vector<LD> sigma(N, 0.0);\n        vector<vector<pair<int, int>>> pred(N);\n\n        priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<pair<LL, int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1;\n        pq.push({0, s});\n\n        while (!pq.empty()) {\n            LL d = pq.top().first;\n            int u = pq.top().second;\n            pq.pop();\n            if (d != dist[u]) continue;\n            for (const Edge &e : adj[u]) {\n                int v = e.to;\n                LL w = e.w;\n                LL nd = dist[u] + w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    sigma[v] = sigma[u];\n                    pred[v].clear();\n                    pred[v].push_back({u, e.id});\n                    pq.push({nd, v});\n                } else if (nd == dist[v]) {\n                    sigma[v] += sigma[u];\n                    pred[v].push_back({u, e.id});\n                }\n            }\n        }\n\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            if (dist[a] != dist[b])\n                return dist[a] > dist[b];\n            return a > b;\n        });\n\n        vector<LD> delta(N, 0.0);\n        for (int i = 0; i < N; i++) {\n            int v = order[i];\n            if (dist[v] == LLONG_MAX) continue;\n            if (v == s) continue;\n            for (auto &p : pred[v]) {\n                int u = p.first;\n                int eid = p.second;\n                if (sigma[v] == 0) continue;\n                LD contrib = (sigma[u] / sigma[v]) * (1.0 + delta[v]);\n                delta[u] += contrib;\n                betweenness[eid] += contrib;\n            }\n        }\n    }\n\n    vector<LD> cost(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, w] = edges[i];\n        cost[i] = betweenness[i] * (LD)w;\n    }\n\n    vector<pair<LD, int>> sorted_edges;\n    for (int i = 0; i < M; i++) {\n        sorted_edges.push_back({cost[i], i});\n    }\n    sort(sorted_edges.rbegin(), sorted_edges.rend());\n\n    vector<LD> total_cost(D, 0.0);\n    vector<int> count(D, 0);\n    vector<int> ans(M, -1);\n\n    for (auto &p : sorted_edges) {\n        LD c = p.first;\n        int eid = p.second;\n        int best_day = -1;\n        LD min_cost = 1e30;\n        for (int d = 0; d < D; d++) {\n            if (count[d] < K) {\n                if (total_cost[d] < min_cost) {\n                    min_cost = total_cost[d];\n                    best_day = d;\n                }\n            }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if (count[d] < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n            if (best_day == -1) {\n                best_day = 0;\n            }\n        }\n        ans[eid] = best_day;\n        total_cost[best_day] += c;\n        count[best_day]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << \" \";\n        cout << ans[i] + 1;\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> is_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\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                bool in1 = (f1[z][x] == '1' && r1[z][y] == '1');\n                bool in2 = (f2[z][x] == '1' && r2[z][y] == '1');\n                if (in1 && in2) {\n                    is_common[x][y][z] = true;\n                } else if (in1) {\n                    is_only1[x][y][z] = true;\n                } else if (in2) {\n                    is_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<int>>> block1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> block2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    int next_block_id = 1;\n    vector<int> dx = {1, -1, 0, 0, 0, 0};\n    vector<int> dy = {0, 0, 1, -1, 0, 0};\n    vector<int> dz = {0, 0, 0, 0, 1, -1};\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 (is_common[x][y][z] && !visited[x][y][z]) {\n                    queue<tuple<int, int, int>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    block1[x][y][z] = next_block_id;\n                    block2[x][y][z] = next_block_id;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D) {\n                                if (is_common[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                    visited[nx][ny][nz] = true;\n                                    block1[nx][ny][nz] = next_block_id;\n                                    block2[nx][ny][nz] = next_block_id;\n                                    q.push({nx, ny, nz});\n                                }\n                            }\n                        }\n                    }\n                    next_block_id++;\n                }\n            }\n        }\n    }\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 (is_only1[x][y][z]) {\n                    block1[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n                if (is_only2[x][y][z]) {\n                    block2[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n            }\n        }\n    }\n\n    cout << next_block_id - 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 << block1[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 << block2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstring>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nconst double INF = 1e18;\nconst int MAXN = 100;\nconst int MAXM = 300;\nconst int MAXK = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nvector<pii> edges;\nint w[MAXM];\ndouble resident_x[MAXK], resident_y[MAXK];\n\nvector<pair<int, int>> adj[MAXN];\ndouble dist_2d[MAXN][MAXN];\nint parent_2d[MAXN][MAXN];\n\nint best_node[MAXK];\ndouble min_dist[MAXK];\n\nvector<int> T_list;\ndouble d_T[MAXK];\nbool inT[MAXN];\n\nvector<pii> MST_edges;\n\nmap<pii, int> edge_index_map;\n\ndouble euclid(double x1, double y1, double x2, double y2) {\n    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));\n}\n\nvoid dijkstra(int src) {\n    for (int i = 0; i < N; i++) {\n        dist_2d[src][i] = INF;\n        parent_2d[src][i] = -1;\n    }\n    dist_2d[src][src] = 0;\n    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n    pq.push({0, src});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n        if (d != dist_2d[src][u]) continue;\n        for (auto &edge : adj[u]) {\n            int v = edge.first;\n            int weight = edge.second;\n            double new_d = d + weight;\n            if (new_d < dist_2d[src][v]) {\n                dist_2d[src][v] = new_d;\n                parent_2d[src][v] = u;\n                pq.push({new_d, v});\n            }\n        }\n    }\n}\n\nvector<int> get_path(int src, int dest) {\n    vector<int> path;\n    if (dist_2d[src][dest] >= INF) return path;\n    int cur = dest;\n    while (cur != src) {\n        path.push_back(cur);\n        cur = parent_2d[src][cur];\n    }\n    path.push_back(src);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstruct Edge {\n    int u, v;\n    double weight;\n    bool operator<(const Edge& other) const {\n        return weight < other.weight;\n    }\n};\n\nvector<int> parent_kruskal;\n\nint find_set(int v) {\n    if (v == parent_kruskal[v]) return v;\n    return parent_kruskal[v] = find_set(parent_kruskal[v]);\n}\n\nbool union_sets(int a, int b) {\n    a = find_set(a);\n    b = find_set(b);\n    if (a == b) return false;\n    parent_kruskal[b] = a;\n    return true;\n}\n\nvoid build_MST_on_T() {\n    int t_size = T_list.size();\n    map<int, int> comp;\n    for (int i = 0; i < t_size; i++) {\n        comp[T_list[i]] = i;\n    }\n\n    vector<Edge> edges_complete;\n    for (int i = 0; i < t_size; i++) {\n        for (int j = i+1; j < t_size; j++) {\n            int u = T_list[i];\n            int v = T_list[j];\n            double d = dist_2d[u][v];\n            edges_complete.push_back({u, v, d});\n        }\n    }\n\n    sort(edges_complete.begin(), edges_complete.end());\n\n    parent_kruskal.resize(t_size);\n    for (int i = 0; i < t_size; i++) parent_kruskal[i] = i;\n\n    MST_edges.clear();\n    for (const Edge& e : edges_complete) {\n        int u_comp = comp[e.u];\n        int v_comp = comp[e.v];\n        if (union_sets(u_comp, v_comp)) {\n            MST_edges.push_back({e.u, e.v});\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> K;\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    for (int j = 0; j < M; j++) {\n        int u, v, weight;\n        cin >> u >> v >> weight;\n        u--; v--;\n        edges.push_back({u, v});\n        w[j] = weight;\n        adj[u].push_back({v, weight});\n        adj[v].push_back({u, weight});\n        int a = min(u, v);\n        int b = max(u, v);\n        edge_index_map[{a, b}] = j;\n    }\n    for (int k = 0; k < K; k++) {\n        cin >> resident_x[k] >> resident_y[k];\n    }\n\n    for (int i = 0; i < N; i++) {\n        dijkstra(i);\n    }\n\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best = -1;\n        for (int i = 0; i < N; i++) {\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d < min_d) {\n                min_d = d;\n                best = i;\n            }\n        }\n        best_node[k] = best;\n        min_dist[k] = min_d;\n    }\n\n    memset(inT, 0, sizeof(inT));\n    T_list.clear();\n    T_list.push_back(0);\n    inT[0] = true;\n\n    for (int k = 0; k < K; k++) {\n        d_T[k] = euclid(resident_x[k], resident_y[k], x[0], y[0]);\n    }\n\n    set<int> uncovered;\n    for (int k = 0; k < K; k++) {\n        uncovered.insert(k);\n    }\n\n    while (!uncovered.empty()) {\n        int k0 = -1;\n        double max_d = -1;\n        for (int k : uncovered) {\n            if (d_T[k] > max_d) {\n                max_d = d_T[k];\n                k0 = k;\n            }\n        }\n        if (d_T[k0] <= 5000) {\n            uncovered.erase(k0);\n            continue;\n        }\n        int i = best_node[k0];\n        if (!inT[i]) {\n            T_list.push_back(i);\n            inT[i] = true;\n            for (int k = 0; k < K; k++) {\n                double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n                if (d < d_T[k]) {\n                    d_T[k] = d;\n                }\n            }\n        }\n        vector<int> to_remove;\n        for (int k : uncovered) {\n            if (d_T[k] <= 5000) {\n                to_remove.push_back(k);\n            }\n        }\n        for (int k : to_remove) {\n            uncovered.erase(k);\n        }\n    }\n\n    if (T_list.size() > 1) {\n        build_MST_on_T();\n    } else {\n        MST_edges.clear();\n    }\n\n    set<int> activated_edges;\n\n    for (auto &e : MST_edges) {\n        int u = e.first;\n        int v = e.second;\n        vector<int> path = get_path(u, v);\n        for (int idx = 0; idx < (int)path.size()-1; idx++) {\n            int a = path[idx];\n            int b = path[idx+1];\n            int aa = min(a, b);\n            int bb = max(a, b);\n            auto key = make_pair(aa, bb);\n            if (edge_index_map.find(key) != edge_index_map.end()) {\n                int j = edge_index_map[key];\n                activated_edges.insert(j);\n            }\n        }\n    }\n\n    vector<bool> inV_prime(N, false);\n    vector<vector<int>> adj_steiner(N);\n    for (int j : activated_edges) {\n        int u = edges[j].first;\n        int v = edges[j].second;\n        adj_steiner[u].push_back(v);\n        adj_steiner[v].push_back(u);\n    }\n    queue<int> q;\n    q.push(0);\n    inV_prime[0] = true;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj_steiner[u]) {\n            if (!inV_prime[v]) {\n                inV_prime[v] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    vector<int> V_prime;\n    for (int i = 0; i < N; i++) {\n        if (inV_prime[i]) {\n            V_prime.push_back(i);\n        }\n    }\n\n    // Precompute distances from residents to nodes in V_prime\n    vector<vector<double>> dist_res_node(K, vector<double>(N, 0.0));\n    for (int k = 0; k < K; k++) {\n        for (int i : V_prime) {\n            dist_res_node[k][i] = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n        }\n    }\n\n    // Initial assignment: assign each resident to the closest node in V_prime\n    vector<int> assign(K, -1);\n    vector<vector<int>> residents(N); // residents[i] = list of resident indices assigned to node i\n\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best_i = -1;\n        for (int i : V_prime) {\n            double d = dist_res_node[k][i];\n            if (d < min_d) {\n                min_d = d;\n                best_i = i;\n            }\n        }\n        assign[k] = best_i;\n        residents[best_i].push_back(k);\n    }\n\n    // For each node in V_prime, compute max1, count_max1, max2\n    vector<double> max1(N, 0.0); // current maximum for node i\n    vector<int> count_max1(N, 0); // count of residents with distance = max1[i]\n    vector<double> max2(N, 0.0); // second maximum for node i\n\n    for (int i : V_prime) {\n        if (residents[i].empty()) {\n            max1[i] = 0;\n            count_max1[i] = 0;\n            max2[i] = 0;\n            continue;\n        }\n        double m1 = 0, m2 = 0;\n        int cnt = 0;\n        for (int k : residents[i]) {\n            double d = dist_res_node[k][i];\n            if (d > m1) {\n                m2 = m1;\n                m1 = d;\n                cnt = 1;\n            } else if (d == m1) {\n                cnt++;\n            } else if (d > m2) {\n                m2 = d;\n            }\n        }\n        max1[i] = m1;\n        count_max1[i] = cnt;\n        max2[i] = m2;\n    }\n\n    // Compute initial cost\n    double current_cost = 0;\n    for (int i : V_prime) {\n        current_cost += max1[i] * max1[i];\n    }\n\n    // Reassignment: try to move residents to reduce the sum of squares\n    int iter = 0;\n    bool improved = true;\n    while (improved && iter < 10) {\n        improved = false;\n        double best_reduction = 0;\n        int best_k = -1, best_j = -1, best_i = -1;\n\n        for (int k = 0; k < K; k++) {\n            int i = assign[k];\n            for (int j : V_prime) {\n                if (j == i) continue;\n                // Compute new_max_i if we remove k from i\n                double new_max_i;\n                double d_i = dist_res_node[k][i];\n                if (d_i == max1[i]) {\n                    if (count_max1[i] > 1) {\n                        new_max_i = max1[i];\n                    } else {\n                        new_max_i = max2[i];\n                    }\n                } else {\n                    new_max_i = max1[i];\n                }\n                double new_max_j = max(max1[j], dist_res_node[k][j]);\n                double reduction = max1[i]*max1[i] + max1[j]*max1[j] - (new_max_i*new_max_i + new_max_j*new_max_j);\n                if (reduction > best_reduction) {\n                    best_reduction = reduction;\n                    best_k = k;\n                    best_j = j;\n                    best_i = i;\n                }\n            }\n        }\n\n        if (best_reduction > 1e-9) {\n            // Remove best_k from best_i\n            vector<int>& list_i = residents[best_i];\n            list_i.erase(remove(list_i.begin(), list_i.end(), best_k), list_i.end());\n            // Add best_k to best_j\n            residents[best_j].push_back(best_k);\n            assign[best_k] = best_j;\n\n            // Recompute statistics for best_i\n            if (list_i.empty()) {\n                max1[best_i] = 0;\n                count_max1[best_i] = 0;\n                max2[best_i] = 0;\n            } else {\n                double m1 = 0, m2 = 0;\n                int cnt = 0;\n                for (int k : list_i) {\n                    double d = dist_res_node[k][best_i];\n                    if (d > m1) {\n                        m2 = m1;\n                        m1 = d;\n                        cnt = 1;\n                    } else if (d == m1) {\n                        cnt++;\n                    } else if (d > m2) {\n                        m2 = d;\n                    }\n                }\n                max1[best_i] = m1;\n                count_max1[best_i] = cnt;\n                max2[best_i] = m2;\n            }\n\n            // Recompute statistics for best_j\n            vector<int>& list_j = residents[best_j];\n            double m1 = 0, m2 = 0;\n            int cnt = 0;\n            for (int k : list_j) {\n                double d = dist_res_node[k][best_j];\n                if (d > m1) {\n                    m2 = m1;\n                    m1 = d;\n                    cnt = 1;\n                } else if (d == m1) {\n                    cnt++;\n                } else if (d > m2) {\n                    m2 = d;\n                }\n            }\n            max1[best_j] = m1;\n            count_max1[best_j] = cnt;\n            max2[best_j] = m2;\n\n            current_cost -= best_reduction;\n            improved = true;\n            iter++;\n        }\n    }\n\n    // Set output strengths\n    vector<int> P(N, 0);\n    for (int i : V_prime) {\n        if (max1[i] > 0) {\n            P[i] = ceil(max1[i]);\n            if (P[i] > 5000) P[i] = 5000;\n        } else {\n            P[i] = 0;\n        }\n    }\n\n    // Output P_i\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << endl;\n\n    // Output B_j\n    vector<int> B(M, 0);\n    for (int j = 0; j < M; j++) {\n        if (activated_edges.find(j) != activated_edges.end()) {\n            B[j] = 1;\n        }\n        if (j > 0) cout << \" \";\n        cout << B[j];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N = 30;\n    vector<vector<int>> grid(N);\n    for (int i = 0; i < N; i++) {\n        grid[i].resize(i+1);\n        for (int j = 0; j <= i; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n\n    for (int x = N-2; x >= 0 && swaps.size() < 10000; x--) {\n        for (int y = 0; y <= x && swaps.size() < 10000; y++) {\n            int cur_x = x, cur_y = y;\n            while (swaps.size() < 10000) {\n                int left_x = cur_x+1, left_y = cur_y;\n                int right_x = cur_x+1, right_y = cur_y+1;\n                if (left_x >= N) break;\n\n                int min_x = left_x, min_y = left_y;\n                int min_val = grid[left_x][left_y];\n                if (grid[right_x][right_y] < min_val) {\n                    min_x = right_x;\n                    min_y = right_y;\n                    min_val = grid[right_x][right_y];\n                }\n\n                if (grid[cur_x][cur_y] > min_val) {\n                    swap(grid[cur_x][cur_y], grid[min_x][min_y]);\n                    swaps.push_back(make_tuple(cur_x, cur_y, min_x, min_y));\n                    cur_x = min_x;\n                    cur_y = min_y;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <utility>\nusing namespace std;\n\nconst int MAX_D = 9;\nconst int entrance_i = 0;\nconst int entrance_j = 4;\nint dx[4] = {1, -1, 0, 0};\nint dy[4] = {0, 0, 1, -1};\n\nint main() {\n    int D, N;\n    cin >> D >> N;\n    bool obstacle[MAX_D][MAX_D] = {false};\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N;\n    bool occupied[MAX_D][MAX_D] = {false};\n    int container_number[MAX_D][MAX_D];\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            container_number[i][j] = -1;\n        }\n    }\n\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n\n        vector<vector<int>> dist(MAX_D, vector<int>(MAX_D, -1));\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                        dist[ni][nj] = dist[i][j] + 1;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> available;\n        for (int i = 0; i < MAX_D; i++) {\n            for (int j = 0; j < MAX_D; j++) {\n                if (dist[i][j] != -1 && !(i == entrance_i && j == entrance_j)) {\n                    available.push_back({i, j});\n                }\n            }\n        }\n\n        sort(available.begin(), available.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            if (dist[a.first][a.second] != dist[b.first][b.second]) {\n                return dist[a.first][a.second] < dist[b.first][b.second];\n            }\n            if (a.first != b.first) {\n                return a.first < b.first;\n            }\n            return a.second < b.second;\n        });\n\n        if (available.empty()) {\n            continue;\n        }\n\n        int k = (t * available.size()) / M;\n        auto chosen = available[k];\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n\n        occupied[chosen.first][chosen.second] = true;\n        container_number[chosen.first][chosen.second] = t;\n    }\n\n    vector<vector<bool>> empty(MAX_D, vector<bool>(MAX_D, false));\n    empty[entrance_i][entrance_j] = true;\n\n    vector<pair<int, int>> containers;\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            if (occupied[i][j]) {\n                containers.push_back({i, j});\n            }\n        }\n    }\n\n    vector<pair<int, int>> removal_order;\n\n    while (!containers.empty()) {\n        vector<vector<bool>> visited(MAX_D, vector<bool>(MAX_D, false));\n        queue<pair<int, int>> q;\n        q.push({entrance_i, entrance_j});\n        visited[entrance_i][entrance_j] = true;\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && empty[ni][nj] && !visited[ni][nj]) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<int> removable_indices;\n        for (int idx = 0; idx < containers.size(); idx++) {\n            auto [i, j] = containers[idx];\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (visited[ni][nj]) {\n                        removable_indices.push_back(idx);\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (removable_indices.empty()) {\n            break;\n        }\n\n        int min_num = 1000000;\n        int best_idx = -1;\n        for (int idx : removable_indices) {\n            auto [i, j] = containers[idx];\n            int num = container_number[i][j];\n            if (num < min_num) {\n                min_num = num;\n                best_idx = idx;\n            }\n        }\n\n        auto coord = containers[best_idx];\n        removal_order.push_back(coord);\n        empty[coord.first][coord.second] = true;\n        swap(containers[best_idx], containers.back());\n        containers.pop_back();\n    }\n\n    for (auto [i, j] : removal_order) {\n        cout << i << \" \" << j << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c;\n            cin >> c;\n            cout << c;\n            if (j < n-1) cout << \" \";\n        }\n        cout << endl;\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n#include <cmath>\n#include <iomanip>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Use a more sophisticated weight estimation\n    vector<double> weights(N, 0.0);\n    vector<vector<int>> comparisons(N, vector<int>(N, 0));\n    \n    // We'll use a strategy that focuses on comparing items that are likely to be close in weight\n    // First, do an initial round of comparisons to get a rough order\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    \n    // Use a bubble-sort like approach but with limited comparisons\n    int queries_used = 0;\n    bool improved = true;\n    while (queries_used < Q && improved) {\n        improved = false;\n        for (int i = 0; i < N - 1 && queries_used < Q; i++) {\n            for (int j = i + 1; j < N && queries_used < Q; j++) {\n                if (comparisons[order[i]][order[j]] == 0) {\n                    cout << \"1 1 \" << order[i] << \" \" << order[j] << endl;\n                    cout.flush();\n                    string res;\n                    cin >> res;\n                    comparisons[order[i]][order[j]] = 1;\n                    comparisons[order[j]][order[i]] = 1;\n                    queries_used++;\n                    \n                    if (res == \">\") {\n                        // order[i] is heavier than order[j], so swap if needed\n                        if (order[i] > order[j]) {\n                            swap(order[i], order[j]);\n                            improved = true;\n                        }\n                    } else if (res == \"<\") {\n                        // order[i] is lighter than order[j], so keep order\n                        if (order[i] < order[j]) {\n                            swap(order[i], order[j]);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Use remaining queries to refine the order\n    while (queries_used < Q) {\n        // Compare random pairs that haven't been compared yet\n        bool found = false;\n        for (int i = 0; i < N && !found; i++) {\n            for (int j = i + 1; j < N && !found; j++) {\n                if (comparisons[i][j] == 0) {\n                    cout << \"1 1 \" << i << \" \" << j << endl;\n                    cout.flush();\n                    string res;\n                    cin >> res;\n                    comparisons[i][j] = 1;\n                    comparisons[j][i] = 1;\n                    queries_used++;\n                    found = true;\n                    \n                    // Update order if needed\n                    if (res == \">\") {\n                        // i is heavier than j\n                        auto it_i = find(order.begin(), order.end(), i);\n                        auto it_j = find(order.begin(), order.end(), j);\n                        if (it_i < it_j) {\n                            swap(*it_i, *it_j);\n                        }\n                    } else if (res == \"<\") {\n                        // i is lighter than j\n                        auto it_i = find(order.begin(), order.end(), i);\n                        auto it_j = find(order.begin(), order.end(), j);\n                        if (it_i > it_j) {\n                            swap(*it_i, *it_j);\n                        }\n                    }\n                }\n            }\n        }\n        if (!found) break;\n    }\n    \n    // Assign items to sets using a greedy algorithm that considers the sorted order\n    // We'll use the position in the order as a weight estimate\n    vector<double> set_totals(D, 0.0);\n    vector<int> assignment(N);\n    \n    // Assign from heaviest to lightest to the smallest set\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        double weight_estimate = N - i; // Heavier items have lower index in order\n        \n        int min_set = 0;\n        for (int d = 1; d < D; d++) {\n            if (set_totals[d] < set_totals[min_set]) {\n                min_set = d;\n            }\n        }\n        \n        assignment[item] = min_set;\n        set_totals[min_set] += weight_estimate;\n    }\n    \n    // Output the assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cout.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    int per_stack = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < per_stack; ++j) {\n            int x;\n            cin >> x;\n            stacks[i].push_back(x);   // bottom to top\n        }\n    }\n\n    // arrays to store position of each box\n    vector<int> stack_of(n + 1, -1);\n    vector<int> idx_in_stack(n + 1, -1);\n\n    // function to recompute positions\n    auto recompute = [&]() {\n        fill(stack_of.begin(), stack_of.end(), -1);\n        fill(idx_in_stack.begin(), idx_in_stack.end(), -1);\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                int box = stacks[i][j];\n                stack_of[box] = i;\n                idx_in_stack[box] = j;\n            }\n        }\n    };\n\n    vector<pair<int, int>> ops;\n    int op_count = 0;\n\n    for (int v = 1; v <= n; ++v) {\n        recompute();\n        int s = stack_of[v];\n        int i = idx_in_stack[v];\n\n        // if v is already on top, carry out\n        if (i == (int)stacks[s].size() - 1) {\n            ops.emplace_back(v, 0);\n            ++op_count;\n            stacks[s].pop_back();\n            continue;\n        }\n\n        // otherwise, move boxes above v one by one\n        while (true) {\n            recompute();\n            s = stack_of[v];\n            i = idx_in_stack[v];\n            if (i == (int)stacks[s].size() - 1) break;   // v is now top\n\n            int w = stacks[s].back();   // current top box\n\n            // choose destination stack t (0\u2011based)\n            int t = -1;\n            vector<int> empty, good, other;\n            for (int idx = 0; idx < m; ++idx) {\n                if (idx == s) continue;\n                if (stacks[idx].empty()) {\n                    empty.push_back(idx);\n                } else if (stacks[idx].back() > w) {\n                    good.push_back(idx);\n                } else {\n                    other.push_back(idx);\n                }\n            }\n\n            if (!empty.empty()) {\n                t = empty[0];   // prefer empty stack\n            } else if (!good.empty()) {\n                // choose stack with smallest top > w\n                int best_top = 1e9;\n                for (int idx : good) {\n                    int top = stacks[idx].back();\n                    if (top < best_top) {\n                        best_top = top;\n                        t = idx;\n                    }\n                }\n            } else if (!other.empty()) {\n                // fallback: choose stack with largest top (< w)\n                int best_top = -1;\n                for (int idx : other) {\n                    int top = stacks[idx].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        t = idx;\n                    }\n                }\n            } else {\n                // should not happen (m>=2), but fallback\n                t = (s + 1) % m;\n            }\n\n            // output move operation (convert to 1\u2011based stack index)\n            ops.emplace_back(w, t + 1);\n            ++op_count;\n\n            // perform the move\n            stacks[s].pop_back();\n            stacks[t].push_back(w);\n        }\n\n        // v is now on top, carry out\n        ops.emplace_back(v, 0);\n        ++op_count;\n        stacks[s].pop_back();   // remove v\n    }\n\n    // output all operations\n    for (auto &p : ops) {\n        cout << p.first << \" \" << p.second << \"\\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;\nvector<vector<bool>> visited;\nstring moves = \"\";\n\n// Direction vectors: right, down, left, up\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'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    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check walls based on direction\n    if (dir == 0) { // right\n        return v[i][j] == '0';\n    } else if (dir == 1) { // down\n        return h[i][j] == '0';\n    } else if (dir == 2) { // left\n        return j > 0 && v[i][j-1] == '0';\n    } else { // up\n        return i > 0 && h[i-1][j] == '0';\n    }\n}\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    \n    // Collect all possible moves to unvisited squares\n    vector<tuple<int, int, int>> candidates; // (d_value, new_i, new_j)\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n            !visited[ni][nj] && can_move(i, j, dir)) {\n            candidates.emplace_back(d[ni][nj], ni, nj);\n        }\n    }\n    \n    // Sort by susceptibility in descending order - visit high-susceptibility squares first\n    sort(candidates.begin(), candidates.end(), [](const tuple<int,int,int>& a, const tuple<int,int,int>& b) {\n        return get<0>(a) > get<0>(b);\n    });\n    \n    for (auto& candidate : candidates) {\n        int new_d = get<0>(candidate);\n        int ni = get<1>(candidate);\n        int nj = get<2>(candidate);\n        \n        // Determine direction\n        int dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (i + di[d] == ni && j + dj[d] == nj) {\n                dir = d;\n                break;\n            }\n        }\n        \n        // Move to the new square\n        moves += dir_char[dir];\n        dfs(ni, nj);\n        \n        // Move back\n        moves += dir_char[(dir + 2) % 4];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    visited.assign(N, vector<bool>(N, false));\n    \n    dfs(0, 0);\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 15;\nconst int NN = GRID_SIZE * GRID_SIZE;\nconst int INF = 1e9;\n\nvector<int> pos[26];  // positions (linear index) for each letter\n\ninline int row(int idx) { return idx / GRID_SIZE; }\ninline int col(int idx) { return idx % GRID_SIZE; }\n\n// Manhattan distance transform: out[v] = min_u (cur[u] + dist(u, v))\nvoid dist_transform(const vector<int>& cur, vector<int>& out) {\n    int val[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j)\n            val[i][j] = cur[i * GRID_SIZE + j];\n\n    int tmp[GRID_SIZE][GRID_SIZE];\n    // horizontal pass\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        // left to right\n        tmp[i][0] = val[i][0];\n        for (int j = 1; j < GRID_SIZE; ++j) {\n            int a = val[i][j];\n            int b = tmp[i][j-1] + 1;\n            tmp[i][j] = a < b ? a : b;\n        }\n        // right to left\n        for (int j = GRID_SIZE - 2; j >= 0; --j) {\n            int b = tmp[i][j+1] + 1;\n            if (b < tmp[i][j]) tmp[i][j] = b;\n        }\n    }\n\n    // vertical pass\n    for (int j = 0; j < GRID_SIZE; ++j) {\n        // top to bottom\n        out[0 * GRID_SIZE + j] = tmp[0][j];\n        for (int i = 1; i < GRID_SIZE; ++i) {\n            int a = tmp[i][j];\n            int b = out[(i-1) * GRID_SIZE + j] + 1;\n            out[i * GRID_SIZE + j] = a < b ? a : b;\n        }\n        // bottom to top\n        for (int i = GRID_SIZE - 2; i >= 0; --i) {\n            int b = out[(i+1) * GRID_SIZE + j] + 1;\n            if (b < out[i * GRID_SIZE + j]) out[i * GRID_SIZE + j] = b;\n        }\n    }\n}\n\n// Compute minimal additional cost to type X from current distribution dp\nint compute_cost(const vector<int>& dp, const string& X,\n                 vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    int ans = INF;\n    for (int v : pos[X.back() - 'A'])\n        if (cur[v] < ans) ans = cur[v];\n    return ans;\n}\n\n// Extend dp by typing X, returning the new distribution\nvector<int> extend_dp(const vector<int>& dp, const string& X,\n                      vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    return cur;\n}\n\n// Reconstruct the optimal sequence of squares for typing X\nvector<int> reconstruct_path(const vector<int>& dp, const string& X) {\n    int L = X.size();\n    vector<vector<int>> cost(L + 1, vector<int>(NN, INF));\n    vector<vector<int>> prev(L + 1, vector<int>(NN, -1));\n\n    // pos 0\n    for (int u = 0; u < NN; ++u) cost[0][u] = dp[u];\n\n    for (int p = 0; p < L; ++p) {\n        char c = X[p];\n        for (int v : pos[c - 'A']) {\n            for (int u = 0; u < NN; ++u) {\n                if (cost[p][u] == INF) continue;\n                int d = abs(row(u) - row(v)) + abs(col(u) - col(v));\n                int new_cost = cost[p][u] + d + 1;\n                if (new_cost < cost[p+1][v]) {\n                    cost[p+1][v] = new_cost;\n                    prev[p+1][v] = u;\n                }\n            }\n        }\n    }\n\n    // find best end\n    int best_v = -1, best_cost = INF;\n    for (int v : pos[X.back() - 'A']) {\n        if (cost[L][v] < best_cost) {\n            best_cost = cost[L][v];\n            best_v = v;\n        }\n    }\n\n    // backtrack\n    vector<int> path(L);\n    int cur_v = best_v;\n    for (int p = L; p >= 1; --p) {\n        path[p-1] = cur_v;\n        cur_v = prev[p][cur_v];\n    }\n    return path;\n}\n\n// Compute maximum overlap (0..4) between suffix of S and prefix of tk\nint compute_overlap(const string& S, const string& tk) {\n    int slen = S.size();\n    int max_possible = min(4, slen);\n    for (int l = max_possible; l >= 1; --l) {\n        if (S.compare(slen - l, l, tk, 0, l) == 0)\n            return l;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_input, M;\n    cin >> N_input >> M;\n    int si, sj;\n    cin >> si >> sj;\n\n    // read grid\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            char c = row[j];\n            pos[c - 'A'].push_back(i * GRID_SIZE + j);\n        }\n    }\n\n    // read target strings\n    vector<string> t(M);\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    // initial state\n    vector<int> dp(NN, INF);\n    int start_idx = si * GRID_SIZE + sj;\n    dp[start_idx] = 0;\n\n    string S = \"\";\n    vector<pair<int, int>> ops;\n    vector<bool> covered(M, false);\n\n    // buffers for DP\n    vector<int> cur_buf(NN), minDist_buf(NN), next_buf(NN);\n\n    while (true) {\n        // check if all covered\n        bool all_covered = true;\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k]) {\n                all_covered = false;\n                break;\n            }\n        }\n        if (all_covered) break;\n\n        int best_k = -1;\n        int best_cost_val = INF;\n        string best_X;\n\n        // evaluate all uncovered t_k\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n            const string& tk = t[k];\n            int overlap = compute_overlap(S, tk);\n            string X = tk.substr(overlap);\n            if (X.empty()) {   // already covered\n                covered[k] = true;\n                continue;\n            }\n            int cost = compute_cost(dp, X, cur_buf, minDist_buf, next_buf);\n            if (cost < best_cost_val) {\n                best_cost_val = cost;\n                best_k = k;\n                best_X = X;\n            }\n        }\n\n        if (best_k == -1) break;  // nothing left to type\n\n        // reconstruct the optimal path for best_X\n        vector<int> path = reconstruct_path(dp, best_X);\n        for (int idx : path) {\n            ops.push_back({row(idx), col(idx)});\n        }\n\n        // update dp and S\n        dp = extend_dp(dp, best_X, cur_buf, minDist_buf, next_buf);\n        S += best_X;\n\n        // update covered set\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k] && S.find(t[k]) != string::npos)\n                covered[k] = true;\n        }\n    }\n\n    // output operations\n    for (auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    vector<vector<pair<int, int>>> polyominoes(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        vector<pair<int, int>> poly(d);\n        for (int i = 0; i < d; i++) {\n            cin >> poly[i].first >> poly[i].second;\n        }\n        polyominoes[k] = poly;\n    }\n\n    vector<pair<int, int>> has_oil;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int val;\n            cin >> val;\n            if (val > 0) {\n                has_oil.push_back({i, j});\n            }\n        }\n    }\n\n    cout << \"a \" << has_oil.size();\n    for (auto &p : has_oil) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl;\n    cout.flush();\n\n    int result;\n    cin >> result;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> A(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < N; i++) {\n            cin >> A[d][i];\n        }\n    }\n\n    vector<int> H(D);\n\n    for (int d = 0; d < D; d++) {\n        if (d == 0) {\n            int best_H = 1;\n            int best_value = 1e9;\n            for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                int total_width = 0;\n                for (int i = 0; i < N; i++) {\n                    total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                }\n                if (total_width <= W) {\n                    int value = total_width + N * H_candidate;\n                    if (value < best_value) {\n                        best_value = value;\n                        best_H = H_candidate;\n                    }\n                }\n            }\n            H[d] = best_H;\n        } else {\n            int H_prev = H[d-1];\n            int total_width = 0;\n            for (int i = 0; i < N; i++) {\n                total_width += (A[d][i] + H_prev - 1) / H_prev;\n            }\n            if (total_width <= W) {\n                H[d] = H_prev;\n            } else {\n                int best_H = 1;\n                int best_value = 1e9;\n                for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                    int total_width = 0;\n                    for (int i = 0; i < N; i++) {\n                        total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                    }\n                    if (total_width <= W) {\n                        int value = total_width + N * H_candidate;\n                        if (value < best_value) {\n                            best_value = value;\n                            best_H = H_candidate;\n                        }\n                    }\n                }\n                H[d] = best_H;\n            }\n        }\n    }\n\n    for (int d = 0; d < D; d++) {\n        int top, bottom;\n        if (d == 0) {\n            top = 0;\n            bottom = H[d];\n        } else {\n            if (H[d] <= H[d-1]) {\n                top = H[d-1] - H[d];\n                bottom = H[d-1];\n            } else {\n                top = 0;\n                bottom = H[d];\n            }\n        }\n        int left = 0;\n        for (int i = 0; i < N; i++) {\n            int width = (A[d][i] + H[d] - 1) / H[d];\n            int right = left + width;\n            cout << top << \" \" << left << \" \" << bottom << \" \" << right << endl;\n            left = right;\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <climits>\n\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    int rem[9][9];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> rem[i][j];\n            rem[i][j] %= MOD;\n        }\n    }\n\n    int s[20][3][3];\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n\n    for (int step = 0; step < K; step++) {\n        long long best_change = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= 6; p++) {\n                for (int q = 0; q <= 6; q++) {\n                    long long change = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int r = rem[p+i][q+j];\n                            int s_val = s[m][i][j];\n                            if (r + s_val < MOD) {\n                                change += s_val;\n                            } else {\n                                change += s_val - MOD;\n                            }\n                        }\n                    }\n                    if (change > best_change) {\n                        best_change = change;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_change <= 0) {\n            break;\n        }\n\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int &r = rem[best_p+i][best_q+j];\n                int s_val = s[best_m][i][j];\n                if (r + s_val < MOD) {\n                    r += s_val;\n                } else {\n                    r = r + s_val - MOD;\n                }\n            }\n        }\n\n        ops.push_back(make_tuple(best_m, best_p, best_q));\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto op : ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <cstring>\n#include <set>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\n\nstruct Crane {\n    int x, y;\n    int carrying; // -1 if not carrying, else container number\n};\n\nint grid[MAX_N][MAX_N]; // -1: empty, else container number\nCrane cranes[MAX_N];\nint next_arrival[MAX_N]; // next index to arrive for each row\nvector<int> dispatched[MAX_N]; // dispatched containers per gate\n\nint next_required[MAX_N]; // next required container for each gate\n\nvoid init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        cranes[i] = {i, 0, -1};\n        next_arrival[i] = 0;\n        next_required[i] = i * N; // smallest in the set\n    }\n}\n\nbool is_next_to_dispatch(int container, int gate) {\n    if (container < gate * N || container >= (gate + 1) * N) {\n        return false;\n    }\n    return container == next_required[gate];\n}\n\nvoid update_next_required(int gate) {\n    set<int> desired;\n    for (int i = 0; i < N; i++) {\n        desired.insert(gate * N + i);\n    }\n    for (int d : dispatched[gate]) {\n        desired.erase(d);\n    }\n    if (!desired.empty()) {\n        next_required[gate] = *desired.begin();\n    } else {\n        next_required[gate] = -1;\n    }\n}\n\nint main() {\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    init();\n\n    vector<string> actions_per_crane(N, \"\");\n    int total_containers = N * N;\n    int dispatched_count = 0;\n    int turn = 0;\n\n    while (turn < MAX_TURNS && dispatched_count < total_containers) {\n        // Step 1: New container arrival\n        for (int i = 0; i < N; i++) {\n            if (next_arrival[i] < N) {\n                bool gate_occupied = false;\n                if (grid[i][0] != -1) {\n                    gate_occupied = true;\n                }\n                for (int k = 0; k < N; k++) {\n                    if (cranes[k].x == i && cranes[k].y == 0) {\n                        gate_occupied = true;\n                        break;\n                    }\n                }\n                if (!gate_occupied) {\n                    grid[i][0] = A[i][next_arrival[i]];\n                    next_arrival[i]++;\n                }\n            }\n        }\n\n        // Prepare for crane actions\n        Crane next_cranes[MAX_N];\n        for (int i = 0; i < N; i++) {\n            next_cranes[i] = cranes[i];\n        }\n        int next_grid[MAX_N][MAX_N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                next_grid[i][j] = grid[i][j];\n            }\n        }\n\n        // For collision detection: record intended next positions\n        int intended_x[MAX_N], intended_y[MAX_N];\n        for (int i = 0; i < N; i++) {\n            intended_x[i] = cranes[i].x;\n            intended_y[i] = cranes[i].y;\n        }\n\n        // Process each crane in order (large crane first, then small cranes)\n        for (int idx = 0; idx < N; idx++) {\n            char action = '.';\n            Crane& crane = cranes[idx];\n            int x = crane.x;\n            int y = crane.y;\n            int carrying = crane.carrying;\n\n            if (carrying != -1) {\n                int target_gate = carrying / N;\n                int target_x = target_gate;\n                int target_y = N-1;\n\n                if (x == target_x && y == target_y) {\n                    if (is_next_to_dispatch(carrying, target_gate)) {\n                        action = 'Q';\n                    } else {\n                        if (x+1 < N && next_grid[x+1][y] == -1) {\n                            action = 'D';\n                        } else if (x-1 >=0 && next_grid[x-1][y] == -1) {\n                            action = 'U';\n                        } else if (y-1 >=0 && next_grid[x][y-1] == -1) {\n                            action = 'L';\n                        } else {\n                            action = '.';\n                        }\n                    }\n                } else {\n                    if (y < target_y) {\n                        action = 'R';\n                    } else if (x < target_x) {\n                        action = 'D';\n                    } else if (x > target_x) {\n                        action = 'U';\n                    } else {\n                        action = '.';\n                    }\n                }\n            } else {\n                if (grid[x][y] != -1) {\n                    action = 'P';\n                } else {\n                    if (y < N-1) {\n                        action = 'R';\n                    } else {\n                        action = '.';\n                    }\n                }\n            }\n\n            // Validate action and update intended position\n            int nx = x, ny = y;\n            bool valid = true;\n            if (action == 'U') nx--;\n            else if (action == 'D') nx++;\n            else if (action == 'L') ny--;\n            else if (action == 'R') ny++;\n\n            if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) valid = false;\n                else {\n                    if (carrying != -1 && idx >= 1) {\n                        if (next_grid[nx][ny] != -1) valid = false;\n                    }\n                    for (int i = 0; i < N; i++) {\n                        if (i != idx) {\n                            if (intended_x[i] == nx && intended_y[i] == ny) {\n                                valid = false;\n                                break;\n                            }\n                            if (intended_x[i] == x && intended_y[i] == y && \n                                intended_x[idx] == nx && intended_y[idx] == ny) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                    }\n                }\n            } else if (action == 'P') {\n                if (carrying != -1 || next_grid[x][y] == -1) valid = false;\n            } else if (action == 'Q') {\n                if (carrying == -1 || next_grid[x][y] != -1) valid = false;\n            }\n\n            if (!valid) {\n                action = '.';\n                nx = x;\n                ny = y;\n            }\n\n            // Apply action\n            if (action == 'P') {\n                next_cranes[idx].carrying = next_grid[x][y];\n                next_grid[x][y] = -1;\n            } else if (action == 'Q') {\n                next_grid[x][y] = carrying;\n                next_cranes[idx].carrying = -1;\n            } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                next_cranes[idx].x = nx;\n                next_cranes[idx].y = ny;\n                intended_x[idx] = nx;\n                intended_y[idx] = ny;\n            }\n\n            actions_per_crane[idx] += action;\n        }\n\n        // Update global state\n        for (int i = 0; i < N; i++) {\n            cranes[i] = next_cranes[i];\n            for (int j = 0; j < N; j++) {\n                grid[i][j] = next_grid[i][j];\n            }\n        }\n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container = grid[i][N-1];\n                grid[i][N-1] = -1;\n                dispatched[i].push_back(container);\n                dispatched_count++;\n                update_next_required(i);\n            }\n        }\n\n        turn++;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << actions_per_crane[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(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    vector<tuple<int, int, int>> surp;\n    vector<tuple<int, int, int>> def;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                surp.push_back(make_tuple(i, j, grid[i][j]));\n            } else if (grid[i][j] < 0) {\n                def.push_back(make_tuple(i, j, -grid[i][j]));\n            }\n        }\n    }\n\n    int cur_i = 0, cur_j = 0;\n    vector<string> ops;\n\n    auto move_to = [&](int target_i, int target_j) {\n        while (cur_i < target_i) {\n            ops.push_back(\"D\");\n            cur_i++;\n        }\n        while (cur_i > target_i) {\n            ops.push_back(\"U\");\n            cur_i--;\n        }\n        while (cur_j < target_j) {\n            ops.push_back(\"R\");\n            cur_j++;\n        }\n        while (cur_j > target_j) {\n            ops.push_back(\"L\");\n            cur_j--;\n        }\n    };\n\n    while (!surp.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < surp.size(); idx++) {\n            auto [i, j, amt] = surp[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = surp[best_idx];\n        move_to(i, j);\n        ops.push_back(\"+\" + to_string(amt));\n        surp.erase(surp.begin() + best_idx);\n    }\n\n    while (!def.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < def.size(); idx++) {\n            auto [i, j, amt] = def[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = def[best_idx];\n        move_to(i, j);\n        ops.push_back(\"-\" + to_string(amt));\n        def.erase(def.begin() + best_idx);\n    }\n\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n    int grid_size = N * N;\n\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n\n    // Initialize random number generator\n    mt19937 rng(12345);\n    \n    // Precompute maximum values for each criterion\n    vector<int> max_vals(M, 0);\n    for (int l = 0; l < M; l++) {\n        for (int i = 0; i < seed_count; i++) {\n            max_vals[l] = max(max_vals[l], seeds[i][l]);\n        }\n    }\n    \n    // Target sum to aim for\n    long long target_sum = 0;\n    for (int l = 0; l < M; l++) {\n        target_sum += max_vals[l];\n    }\n\n    // Grid directions\n    vector<int> di = {-1, 1, 0, 0};\n    vector<int> dj = {0, 0, -1, 1};\n\n    for (int t = 0; t < T; t++) {\n        // 1. SEED SELECTION STRATEGY\n        // Calculate total values for all seeds\n        vector<int> total(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            for (int l = 0; l < M; l++) {\n                total[i] += seeds[i][l];\n            }\n        }\n\n        // Select seeds using multiple criteria:\n        // - Top by total value\n        // - Diversity in criteria strengths\n        vector<int> indices(seed_count);\n        iota(indices.begin(), indices.end(), 0);\n        \n        // Sort by total value (descending)\n        sort(indices.begin(), indices.end(), [&](int i, int j) { \n            if (total[i] != total[j]) return total[i] > total[j];\n            return i < j;\n        });\n\n        // Use a combination of top seeds and some diversity\n        vector<int> selected_indices;\n        int take_top = min(28, grid_size); // Take top seeds\n        for (int i = 0; i < take_top; i++) {\n            selected_indices.push_back(indices[i]);\n        }\n        \n        // Add some seeds that are strong in specific criteria\n        set<int> added(selected_indices.begin(), selected_indices.end());\n        for (int l = 0; l < M && selected_indices.size() < grid_size; l++) {\n            int best_seed = -1;\n            int best_val = -1;\n            for (int i = 0; i < seed_count; i++) {\n                if (added.count(i)) continue;\n                if (seeds[i][l] > best_val) {\n                    best_val = seeds[i][l];\n                    best_seed = i;\n                }\n            }\n            if (best_seed != -1 && added.count(best_seed) == 0) {\n                selected_indices.push_back(best_seed);\n                added.insert(best_seed);\n            }\n        }\n        \n        // Fill remaining slots with next best seeds\n        for (int i = take_top; i < seed_count && selected_indices.size() < grid_size; i++) {\n            if (added.count(indices[i]) == 0) {\n                selected_indices.push_back(indices[i]);\n                added.insert(indices[i]);\n            }\n        }\n\n        // 2. GRID ASSIGNMENT STRATEGY\n        // We want to maximize the potential of offspring seeds\n        // This means pairing seeds that complement each other\n        \n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Compute potential values for each pair\n        auto compute_pair_potential = [&](int a, int b) {\n            long long potential = 0;\n            for (int l = 0; l < M; l++) {\n                // Potential is the maximum possible value for each criterion\n                potential += max(seeds[a][l], seeds[b][l]);\n            }\n            return potential;\n        };\n        \n        // Greedy assignment with look-ahead\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cells.push_back({i, j});\n            }\n        }\n        \n        // Sort cells by number of neighbors (center first)\n        sort(cells.begin(), cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            int na = 0, nb = 0;\n            for (int d = 0; d < 4; d++) {\n                int ai = a.first + di[d], aj = a.second + dj[d];\n                if (ai >= 0 && ai < N && aj >= 0 && aj < N) na++;\n                int bi = b.first + di[d], bj = b.second + dj[d];\n                if (bi >= 0 && bi < N && bj >= 0 && bj < N) nb++;\n            }\n            if (na != nb) return na > nb;\n            return a < b;\n        });\n        \n        // Assign seeds to cells\n        for (auto [i, j] : cells) {\n            int best_seed = -1;\n            double best_score = -1e18;\n            \n            // Try each unused seed\n            for (int s_idx = 0; s_idx < selected_indices.size(); s_idx++) {\n                int seed_idx = selected_indices[s_idx];\n                if (used[seed_idx]) continue;\n                \n                // Calculate score for placing this seed here\n                double score = 0;\n                int assigned_neighbors = 0;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor_seed = grid[ni][nj];\n                        // Score based on complementarity and potential\n                        double pair_score = compute_pair_potential(seed_idx, neighbor_seed);\n                        // Add some weight to the seed's own total value\n                        pair_score += 0.1 * total[seed_idx];\n                        score += pair_score;\n                        assigned_neighbors++;\n                    }\n                }\n                \n                // If no neighbors, use the seed's total value\n                if (assigned_neighbors == 0) {\n                    score = total[seed_idx];\n                }\n                \n                // Add a small random factor for exploration (decreases over time)\n                double exploration = (1.0 - (double)t / T) * 10.0;\n                score += exploration * (rng() % 100);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_seed = seed_idx;\n                }\n            }\n            \n            if (best_seed != -1) {\n                grid[i][j] = best_seed;\n                used[best_seed] = true;\n            }\n        }\n        \n        // Output the grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // 3. LEARN FROM NEW SEEDS\n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n        \n        // Optional: Add some adaptive behavior based on progress\n        // If we're getting close to target, be more aggressive in selection\n        int current_max = 0;\n        for (int i = 0; i < seed_count; i++) {\n            int sum = 0;\n            for (int l = 0; l < M; l++) sum += seeds[i][l];\n            current_max = max(current_max, sum);\n        }\n        \n        // If we're close to target, we can try more aggressive strategies in future iterations\n        // This is implicitly handled by the changing weights in assignment\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <queue>\n#include <map>\n#include <set>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nPoint get_grab_pos(Point s, char dir, int d) {\n    if (dir == 'R') return Point(s.x - d, s.y);\n    if (dir == 'L') return Point(s.x + d, s.y);\n    if (dir == 'D') return Point(s.x, s.y - d);\n    if (dir == 'U') return Point(s.x, s.y + d);\n    return Point();\n}\n\nPoint get_release_pos(Point t, char dir, int d) {\n    if (dir == 'R') return Point(t.x - d, t.y);\n    if (dir == 'L') return Point(t.x + d, t.y);\n    if (dir == 'D') return Point(t.x, t.y - d);\n    if (dir == 'U') return Point(t.x, t.y + d);\n    return Point();\n}\n\nbool is_valid(Point p, int N) {\n    return p.x >= 0 && p.x < N && p.y >= 0 && p.y < N;\n}\n\nvector<char> get_path(Point from, Point to) {\n    vector<char> path;\n    int x = from.x;\n    int y = from.y;\n    while (x != to.x) {\n        if (x < to.x) {\n            path.push_back('R');\n            x++;\n        } else {\n            path.push_back('L');\n            x--;\n        }\n    }\n    while (y != to.y) {\n        if (y < to.y) {\n            path.push_back('D');\n            y++;\n        } else {\n            path.push_back('U');\n            y--;\n        }\n    }\n    return path;\n}\n\nstring create_turn(char movement, int leaf_index, char direction, bool grab, int V) {\n    string s(2 * V, '.');\n    s[0] = movement;\n    if (leaf_index != -1) {\n        s[leaf_index] = direction;\n        if (grab) {\n            s[V + leaf_index] = 'P';\n        }\n    }\n    return s;\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\n    vector<string> S(N), T(N);\n    for (int i = 0; i < N; i++) cin >> S[i];\n    for (int i = 0; i < N; i++) cin >> T[i];\n\n    vector<Point> initial_positions;\n    vector<Point> target_positions;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (S[i][j] == '1') initial_positions.push_back(Point(i, j));\n            if (T[i][j] == '1') target_positions.push_back(Point(i, j));\n        }\n    }\n\n    vector<pair<Point, Point>> pairs;\n    vector<bool> assigned(M, false);\n\n    for (int i = 0; i < M; i++) {\n        Point s = initial_positions[i];\n        int best_j = -1;\n        int best_dist = 1e9;\n        for (int j = 0; j < M; j++) {\n            if (assigned[j]) continue;\n            int dist = manhattan(s, target_positions[j]);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_j = j;\n            }\n        }\n        assigned[best_j] = true;\n        pairs.push_back({s, target_positions[best_j]});\n    }\n\n    Point current_root(N / 2, N / 2);\n    vector<string> turns;\n\n    vector<pair<Point, Point>> remaining = pairs;\n\n    while (!remaining.empty()) {\n        int best_cost = 1e9;\n        int best_index = -1;\n        int best_leaf = -1;\n        char best_grab_dir = ' ';\n        char best_release_dir = ' ';\n        Point best_grab_pos, best_release_pos;\n\n        for (int i = 0; i < remaining.size(); i++) {\n            Point s = remaining[i].first;\n            Point t = remaining[i].second;\n            for (int leaf = 1; leaf < V; leaf++) {\n                int d = leaf;\n                for (char grab_dir : {'L', 'R', 'U', 'D'}) {\n                    Point grab_pos = get_grab_pos(s, grab_dir, d);\n                    if (!is_valid(grab_pos, N)) continue;\n                    for (char release_dir : {'L', 'R', 'U', 'D'}) {\n                        Point release_pos = get_release_pos(t, release_dir, d);\n                        if (!is_valid(release_pos, N)) continue;\n                        int cost = manhattan(current_root, grab_pos) + manhattan(grab_pos, release_pos);\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_index = i;\n                            best_leaf = leaf;\n                            best_grab_dir = grab_dir;\n                            best_release_dir = release_dir;\n                            best_grab_pos = grab_pos;\n                            best_release_pos = release_pos;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_index == -1) {\n            break;\n        }\n\n        vector<char> path1 = get_path(current_root, best_grab_pos);\n        if (path1.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_grab_dir, true, V));\n        } else {\n            for (int j = 0; j < path1.size(); j++) {\n                bool grab = (j == path1.size() - 1);\n                turns.push_back(create_turn(path1[j], best_leaf, best_grab_dir, grab, V));\n            }\n        }\n        current_root = best_grab_pos;\n\n        vector<char> path2 = get_path(best_grab_pos, best_release_pos);\n        if (path2.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_release_dir, true, V));\n        } else {\n            for (int j = 0; j < path2.size(); j++) {\n                bool release = (j == path2.size() - 1);\n                turns.push_back(create_turn(path2[j], best_leaf, best_release_dir, release, V));\n            }\n        }\n        current_root = best_release_pos;\n\n        remaining.erase(remaining.begin() + best_index);\n    }\n\n    cout << V << endl;\n    for (int i = 1; i < V; i++) {\n        cout << 0 << \" \" << i << endl;\n    }\n    cout << N/2 << \" \" << N/2 << endl;\n\n    for (const string& turn : turns) {\n        cout << turn << endl;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct Point {\n    int x, y, weight;\n};\n\nstruct Node {\n    int sum;\n    int max_prefix;\n    int max_suffix;\n    int max_sum;\n};\n\nNode merge(Node L, Node R) {\n    Node node;\n    node.sum = L.sum + R.sum;\n    node.max_prefix = max(L.max_prefix, L.sum + R.max_prefix);\n    node.max_suffix = max(R.max_suffix, R.sum + L.max_suffix);\n    node.max_sum = max({L.max_sum, R.max_sum, L.max_suffix + R.max_prefix});\n    return node;\n}\n\nclass SegmentTree {\npublic:\n    int n;\n    vector<int> arr;\n    vector<Node> seg;\n\n    SegmentTree(int size) {\n        n = size;\n        arr.assign(n, 0);\n        seg.resize(4 * n);\n        build(1, 0, n-1);\n    }\n\n    void build(int node, int left, int right) {\n        if (left == right) {\n            seg[node].sum = 0;\n            seg[node].max_prefix = 0;\n            seg[node].max_suffix = 0;\n            seg[node].max_sum = 0;\n            return;\n        }\n        int mid = (left + right) / 2;\n        build(2 * node, left, mid);\n        build(2 * node + 1, mid + 1, right);\n        seg[node] = merge(seg[2 * node], seg[2 * node + 1]);\n    }\n\n    void update(int idx, int val, int node = 1, int left = 0, int right = -1) {\n        if (right == -1) right = n - 1;\n        if (left == right) {\n            arr[idx] += val;\n            seg[node].sum = arr[idx];\n            seg[node].max_prefix = arr[idx];\n            seg[node].max_suffix = arr[idx];\n            seg[node].max_sum = arr[idx];\n            return;\n        }\n        int mid = (left + right) / 2;\n        if (idx <= mid) {\n            update(idx, val, 2 * node, left, mid);\n        } else {\n            update(idx, val, 2 * node + 1, mid + 1, right);\n        }\n        seg[node] = merge(seg[2 * node], seg[2 * node + 1]);\n    }\n\n    int query() {\n        return seg[1].max_sum;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    srand(time(0));\n\n    int N;\n    cin >> N;\n    vector<Point> points;\n    set<pair<int, int>> point_set;\n    \n    for (int i = 0; i < 2 * N; i++) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 0});\n        point_set.insert({x, y});\n    }\n\n    for (int i = 0; i < N; i++) {\n        points[i].weight = 1;\n    }\n    for (int i = N; i < 2 * N; i++) {\n        points[i].weight = -1;\n    }\n\n    sort(points.begin(), points.end(), [](const Point& a, const Point& b) {\n        return a.x < b.x;\n    });\n\n    vector<int> y_coords;\n    for (auto& p : points) {\n        y_coords.push_back(p.y);\n    }\n    sort(y_coords.begin(), y_coords.end());\n    y_coords.erase(unique(y_coords.begin(), y_coords.end()), y_coords.end());\n    int m = y_coords.size();\n    map<int, int> y_to_idx;\n    for (int i = 0; i < m; i++) {\n        y_to_idx[y_coords[i]] = i;\n    }\n\n    vector<int> candidate_x1;\n    int n_points = points.size();\n    \n    for (int i = 0; i < 50 && i < n_points; i++) {\n        candidate_x1.push_back(points[i].x);\n    }\n    for (int i = n_points - 50; i < n_points; i++) {\n        if (i >= 0) candidate_x1.push_back(points[i].x);\n    }\n    for (int i = 1; i <= 8; i++) {\n        int idx = (n_points * i) / 9;\n        if (idx < n_points) candidate_x1.push_back(points[idx].x);\n    }\n    \n    sort(candidate_x1.begin(), candidate_x1.end());\n    candidate_x1.erase(unique(candidate_x1.begin(), candidate_x1.end()), candidate_x1.end());\n\n    int best_score = -1e9;\n    int best_x1 = 0, best_x2 = 0;\n\n    for (int x1 : candidate_x1) {\n        int left_index = lower_bound(points.begin(), points.end(), x1, \n            [](const Point& p, int x) { return p.x < x; }) - points.begin();\n        \n        SegmentTree seg_tree(m);\n        \n        for (int right_index = left_index; right_index < n_points; right_index++) {\n            Point p = points[right_index];\n            int y_idx = y_to_idx[p.y];\n            seg_tree.update(y_idx, p.weight);\n            \n            if (p.x > x1) {\n                int current_max = seg_tree.query();\n                if (current_max > best_score) {\n                    best_score = current_max;\n                    best_x1 = x1;\n                    best_x2 = p.x;\n                }\n            }\n        }\n    }\n\n    if (best_score >= 0) {\n        vector<Point> points_in_rect;\n        for (auto p : points) {\n            if (p.x >= best_x1 && p.x <= best_x2) {\n                points_in_rect.push_back(p);\n            }\n        }\n        \n        map<int, int> y_weight;\n        for (auto p : points_in_rect) {\n            y_weight[p.y] += p.weight;\n        }\n        \n        vector<pair<int, int>> y_weights;\n        for (auto it : y_weight) {\n            y_weights.push_back(it);\n        }\n        sort(y_weights.begin(), y_weights.end());\n        \n        int cur_sum = 0;\n        int best_sum = 0;\n        int cur_start = 0;\n        int best_start = 0, best_end = 0;\n        \n        for (int i = 0; i < y_weights.size(); i++) {\n            cur_sum += y_weights[i].second;\n            if (cur_sum > best_sum) {\n                best_sum = cur_sum;\n                best_start = cur_start;\n                best_end = i;\n            }\n            if (cur_sum < 0) {\n                cur_sum = 0;\n                cur_start = i + 1;\n            }\n        }\n        \n        int y1 = y_weights[best_start].first;\n        int y2 = y_weights[best_end].first;\n        \n        cout << 4 << endl;\n        cout << best_x1 << \" \" << y1 << endl;\n        cout << best_x1 << \" \" << y2 << endl;\n        cout << best_x2 << \" \" << y2 << endl;\n        cout << best_x2 << \" \" << y1 << endl;\n    } else {\n        while (true) {\n            int x = rand() % 100000;\n            int y = rand() % 100000;\n            if (point_set.find({x, y}) == point_set.end() &&\n                point_set.find({x, y+1}) == point_set.end() &&\n                point_set.find({x+1, y}) == point_set.end() &&\n                point_set.find({x+1, y+1}) == point_set.end()) {\n                cout << 4 << endl;\n                cout << x << \" \" << y << endl;\n                cout << x << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y << endl;\n                break;\n            }\n        }\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int id;\n    double w_est, h_est;  // Estimated dimensions\n    double w_var, h_var;  // Variance estimates\n    double w_obs, h_obs;  // Observed values\n};\n\nstruct Placement {\n    int id;\n    int rotated;\n    char direction;\n    int reference;\n};\n\nclass Packer {\nprivate:\n    vector<Rectangle> rects;\n    double sigma;\n    int N, T;\n    \n    // Random number generator\n    mt19937 rng;\n    \n    // Update estimates using Bayesian approach\n    void updateEstimates(int turn, double W_meas, double H_meas, const vector<Placement>& placement) {\n        // For each placed rectangle, adjust estimates based on bounding box measurement\n        for (const auto& p : placement) {\n            Rectangle& rect = rects[p.id];\n            double expected_W = rect.w_est;\n            double expected_H = rect.h_est;\n            \n            // Simple adjustment: if measured box is larger than expected, increase estimates\n            double adjustment_factor = 1.0;\n            if (W_meas > 0 && H_meas > 0) {\n                // Use harmonic mean of ratios to avoid extreme adjustments\n                double w_ratio = W_meas / (expected_W + 1e-9);\n                double h_ratio = H_meas / (expected_H + 1e-9);\n                adjustment_factor = 2.0 / (1.0/w_ratio + 1.0/h_ratio);\n            }\n            \n            // Adjust with damping to prevent overcorrection\n            double damping = 0.1;\n            rect.w_est = rect.w_est * (1 - damping) + rect.w_est * adjustment_factor * damping;\n            rect.h_est = rect.h_est * (1 - damping) + rect.h_est * adjustment_factor * damping;\n            \n            // Update variance estimates (simplified)\n            rect.w_var = rect.w_var * 0.95 + (W_meas - rect.w_est) * (W_meas - rect.w_est) * 0.05;\n            rect.h_var = rect.h_var * 0.95 + (H_meas - rect.h_est) * (H_meas - rect.h_est) * 0.05;\n            \n            // Clamp values\n            rect.w_est = max(1.0, min(1e9, rect.w_est));\n            rect.h_est = max(1.0, min(1e9, rect.h_est));\n        }\n    }\n    \n    // Simulated annealing for packing optimization\n    vector<Placement> optimizePacking(int turn, int num_rects) {\n        vector<Placement> best_solution;\n        double best_score = 1e18;\n        \n        int iterations = 200 + turn * 10;  // More iterations in later turns\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            vector<Placement> candidate;\n            vector<bool> used(N, false);\n            \n            // Randomly select subset of rectangles (in increasing order)\n            vector<int> selected;\n            for (int i = 0; i < N; i++) {\n                if (rng() % 2) {\n                    selected.push_back(i);\n                }\n            }\n            sort(selected.begin(), selected.end());\n            \n            // Greedy packing with randomization\n            for (int id : selected) {\n                Placement p;\n                p.id = id;\n                p.rotated = rng() % 2;\n                p.direction = (rng() % 2) ? 'U' : 'L';\n                \n                // For reference, try existing placed rectangles or -1\n                if (candidate.empty()) {\n                    p.reference = -1;\n                } else {\n                    p.reference = candidate[rng() % candidate.size()].id;\n                }\n                \n                candidate.push_back(p);\n            }\n            \n            // Evaluate score\n            double score = evaluateScore(candidate, turn);\n            \n            // Simulated annealing acceptance\n            double temperature = 100.0 / (1 + turn);\n            if (score < best_score || \n                (exp((best_score - score) / temperature) > (double)(rng() % 10000) / 10000.0)) {\n                best_solution = candidate;\n                best_score = score;\n            }\n        }\n        \n        return best_solution;\n    }\n    \n    // Evaluate score for a packing\n    double evaluateScore(const vector<Placement>& placement, int turn) {\n        if (placement.empty()) {\n            // If no rectangles placed, all contribute to penalty\n            double penalty = 0;\n            for (const auto& rect : rects) {\n                penalty += rect.w_est + rect.h_est;\n            }\n            return penalty;\n        }\n        \n        // Simulate packing to get bounding box\n        // This is a simplified simulation - in practice, we'd need to track positions\n        double total_width = 0;\n        double total_height = 0;\n        \n        // Simple heuristic: sum of widths if placed horizontally, heights if vertically\n        // More sophisticated simulation would be better but is complex\n        double sum_w = 0, sum_h = 0;\n        for (const auto& p : placement) {\n            const Rectangle& rect = rects[p.id];\n            if (p.rotated) {\n                sum_w += rect.h_est;\n                sum_h += rect.w_est;\n            } else {\n                sum_w += rect.w_est;\n                sum_h += rect.h_est;\n            }\n        }\n        \n        // Use more compact dimension\n        total_width = min(sum_w, sum_h * 1.5);\n        total_height = min(sum_h, sum_w * 1.5);\n        \n        // Add penalty for unused rectangles\n        double penalty = 0;\n        vector<bool> used(N, false);\n        for (const auto& p : placement) {\n            used[p.id] = true;\n        }\n        for (int i = 0; i < N; i++) {\n            if (!used[i]) {\n                penalty += rects[i].w_est + rects[i].h_est;\n            }\n        }\n        \n        return total_width + total_height + penalty;\n    }\n    \n    // Select which rectangles to pack based on value vs size\n    vector<int> selectRectangles(int turn) {\n        vector<int> selected;\n        \n        // Calculate \"value\" of each rectangle (high penalty if not packed)\n        vector<pair<double, int>> values;\n        for (int i = 0; i < N; i++) {\n            double value = rects[i].w_est + rects[i].h_est;\n            values.push_back({value, i});\n        }\n        \n        // Sort by value (descending)\n        sort(values.begin(), values.end(), greater<pair<double, int>>());\n        \n        // Select top K rectangles, where K increases with turn\n        int k = min(N, max(5, (int)(N * (0.3 + turn * 0.02))));\n        for (int i = 0; i < k; i++) {\n            selected.push_back(values[i].second);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n\npublic:\n    Packer(int n, int t, double s, const vector<pair<double, double>>& observed) : N(n), T(t), sigma(s), rng(12345 + n) {\n        rects.resize(N);\n        for (int i = 0; i < N; i++) {\n            rects[i].id = i;\n            rects[i].w_obs = observed[i].first;\n            rects[i].h_obs = observed[i].second;\n            // Initialize estimates with observed values plus some random noise\n            normal_distribution<double> dist(0, sigma * 0.1);\n            rects[i].w_est = observed[i].first + dist(rng);\n            rects[i].h_est = observed[i].second + dist(rng);\n            rects[i].w_var = sigma * sigma;\n            rects[i].h_var = sigma * sigma;\n            \n            // Clamp\n            rects[i].w_est = max(1.0, min(1e9, rects[i].w_est));\n            rects[i].h_est = max(1.0, min(1e9, rects[i].h_est));\n        }\n    }\n    \n    vector<Placement> solve(int turn, double W_meas, double H_meas, const vector<Placement>& last_placement) {\n        // Update estimates based on previous measurement\n        if (turn > 0) {\n            updateEstimates(turn, W_meas, H_meas, last_placement);\n        }\n        \n        // Select which rectangles to pack\n        vector<int> selected = selectRectangles(turn);\n        \n        // If we haven't packed many rectangles yet, try to pack more\n        if (turn < T / 4 && selected.size() < N) {\n            // Add some more rectangles in later turns\n            int additional = min(N - (int)selected.size(), (turn + 1) * 2);\n            for (int i = 0; i < additional; i++) {\n                selected.push_back((selected.size() + i) % N);\n            }\n            sort(selected.begin(), selected.end());\n            selected.erase(unique(selected.begin(), selected.end()), selected.end());\n        }\n        \n        // Optimize packing\n        vector<Placement> placement = optimizePacking(turn, selected.size());\n        \n        return placement;\n    }\n};\n\nint main() {\n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<double, double>> observed(N);\n    for (int i = 0; i < N; i++) {\n        cin >> observed[i].first >> observed[i].second;\n    }\n    \n    Packer packer(N, T, sigma, observed);\n    \n    vector<Placement> last_placement;\n    \n    for (int turn = 0; turn < T; turn++) {\n        double W_meas = 0, H_meas = 0;\n        \n        // Get measurement from previous turn (except first turn)\n        if (turn > 0) {\n            cin >> W_meas >> H_meas;\n        }\n        \n        // Solve for current turn\n        vector<Placement> placement = packer.solve(turn, W_meas, H_meas, last_placement);\n        \n        // Output\n        cout << placement.size() << endl;\n        for (const auto& p : placement) {\n            cout << p.id << \" \" << p.rotated << \" \" << p.direction << \" \" << p.reference << endl;\n        }\n        cout.flush();\n        \n        last_placement = placement;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<int> order_asc, order_desc;\n\n    // State for current forest\n    vector<bool> covered;\n    vector<int> parent, depth;\n    vector<vector<int>> children;\n    vector<int> subtree_sum, max_depth_subtree;\n\n    void read_input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; ++i) cin >> A[i];\n        adj.assign(N, {});\n        for (int i = 0; i < M; ++i) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // read coordinates (unused)\n        for (int i = 0; i < N; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n\n        // prepare vertex orders\n        order_asc.resize(N);\n        iota(order_asc.begin(), order_asc.end(), 0);\n        sort(order_asc.begin(), order_asc.end(), [&](int i, int j) { return A[i] < A[j]; });\n        order_desc = order_asc;\n        reverse(order_desc.begin(), order_desc.end());\n    }\n\n    void build_initial_forest(const vector<int>& order) {\n        covered.assign(N, false);\n        parent.assign(N, -1);\n        depth.assign(N, 0);\n        for (int v : order) {\n            if (covered[v]) continue;\n            // BFS from v, depth limit H, only through uncovered vertices\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            covered[v] = true;\n            parent[v] = -1;\n            depth[v] = 0;\n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d == H) continue;          // cannot go deeper\n                for (int w : adj[u]) {\n                    if (!covered[w]) {\n                        covered[w] = true;\n                        parent[w] = u;\n                        depth[w] = d + 1;\n                        if (d + 1 < H) q.push({w, d + 1}); // push only if can be expanded later\n                    }\n                }\n            }\n        }\n        // build children lists\n        children.assign(N, {});\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] != -1) {\n                children[parent[v]].push_back(v);\n            }\n        }\n    }\n\n    void compute_subtree_info() {\n        subtree_sum.assign(N, 0);\n        max_depth_subtree.assign(N, 0);\n        function<void(int)> dfs = [&](int v) {\n            subtree_sum[v] = A[v];\n            max_depth_subtree[v] = 0;\n            for (int c : children[v]) {\n                dfs(c);\n                subtree_sum[v] += subtree_sum[c];\n                max_depth_subtree[v] = max(max_depth_subtree[v], max_depth_subtree[c] + 1);\n            }\n        };\n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                dfs(v);\n            }\n        }\n    }\n\n    int get_root(int v) {\n        while (parent[v] != -1) v = parent[v];\n        return v;\n    }\n\n    void update_depths(int v, int delta) {\n        depth[v] += delta;\n        for (int c : children[v]) {\n            update_depths(c, delta);\n        }\n    }\n\n    void improve_forest() {\n        const int MAX_PASS = 20;\n        bool changed = true;\n        int pass = 0;\n        while (changed && pass < MAX_PASS) {\n            changed = false;\n            ++pass;\n            compute_subtree_info();\n            for (int v : order_desc) {\n                int best_u = -1;\n                long long best_gain = -1;\n                int root_v = get_root(v);\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;           // same edge, no gain\n                    int root_u = get_root(u);\n                    if (root_v == root_u) continue;         // same tree -> would create cycle\n                    int new_depth_v = depth[u] + 1;\n                    if (new_depth_v > H) continue;\n                    if (new_depth_v + max_depth_subtree[v] > H) continue;\n                    int delta = new_depth_v - depth[v];\n                    if (delta <= 0) continue;\n                    long long gain = (long long)delta * subtree_sum[v];\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_u = u;\n                    }\n                }\n                if (best_u != -1) {\n                    // perform the move\n                    int old_parent = parent[v];\n                    if (old_parent != -1) {\n                        auto& vec = children[old_parent];\n                        vec.erase(remove(vec.begin(), vec.end(), v), vec.end());\n                    }\n                    children[best_u].push_back(v);\n                    parent[v] = best_u;\n                    int delta = (depth[best_u] + 1) - depth[v];\n                    update_depths(v, delta);\n                    changed = true;\n                    break;   // restart the while loop\n                }\n            }\n        }\n    }\n\n    long long compute_score() {\n        long long score = 0;\n        for (int v = 0; v < N; ++v) {\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    }\n\n    vector<int> solve_one(bool ascending) {\n        const vector<int>& order = ascending ? order_asc : order_desc;\n        build_initial_forest(order);\n        improve_forest();\n        return parent;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver solver;\n    solver.read_input();\n\n    long long best_score = -1;\n    vector<int> best_parent;\n\n    for (bool asc : {true, false}) {\n        vector<int> parent = solver.solve_one(asc);\n        long long score = solver.compute_score();\n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n\n    for (int i = 0; i < (int)best_parent.size(); ++i) {\n        if (i > 0) cout << ' ';\n        cout << best_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>> operations;\n    const int MAX_OPERATIONS = 4 * N * N;\n\n    while (operations.size() < MAX_OPERATIONS) {\n        bool hasOni = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    hasOni = true;\n                    break;\n                }\n            }\n            if (hasOni) break;\n        }\n        if (!hasOni) break;\n\n        bool removed = false;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == 'x') {\n                operations.push_back({'L', i});\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[i][N-1] == 'x') {\n                operations.push_back({'R', i});\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == 'x') {\n                operations.push_back({'U', j});\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[N-1][j] == 'x') {\n                operations.push_back({'D', j});\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        int best_dist = 1000000;\n        char best_dir = 0;\n        int best_index = -1;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == '.') {\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        if (j < best_dist) {\n                            best_dist = j;\n                            best_dir = 'L';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][N-1] == '.') {\n                for (int j = N-1; j >= 0; j--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - j;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'R';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == '.') {\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        if (i < best_dist) {\n                            best_dist = i;\n                            best_dir = 'U';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[N-1][j] == '.') {\n                for (int i = N-1; i >= 0; i--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - i;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'D';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (best_index != -1) {\n            operations.push_back({best_dir, best_index});\n            if (best_dir == 'L') {\n                int i = best_index;\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n            } else if (best_dir == 'R') {\n                int i = best_index;\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n            } else if (best_dir == 'U') {\n                int j = best_index;\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n            } else if (best_dir == 'D') {\n                int j = best_index;\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n            }\n        } else {\n            break;\n        }\n    }\n\n    for (auto op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int N, L;\n    cin >> N >> L;\n    int T[100];\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    for (int i = 0; i < N; i++) {\n        int a = (i + 1) % N;\n        int b = (i + 2) % N;\n        cout << a << \" \" << b << endl;\n    }\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\n// Global variables for input and query counting\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> cx, cy;   // center coordinates\nint queries_used = 0;\n\n// Perform a query on a set of cities and return the MST edges\nvector<pair<int, int>> do_query(vector<int> cities) {\n    sort(cities.begin(), cities.end());\n    cout << \"? \" << cities.size();\n    for (int c : cities) {\n        cout << \" \" << c;\n    }\n    cout << endl;\n    vector<pair<int, int>> edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.push_back(make_pair(a, b));\n    }\n    queries_used++;\n    return edges;\n}\n\n// Recursively build a spanning tree for a set of cities (already sorted by center)\nvector<pair<int, int>> build_tree(vector<int> cities) {\n    int n = cities.size();\n    if (n == 1) {\n        return {};\n    }\n    if (n == 2) {\n        return {make_pair(cities[0], cities[1])};\n    }\n    if (n <= L) {\n        if (n >= 3 && queries_used < Q) {\n            return do_query(cities);\n        } else {\n            // Fallback: connect in a chain\n            vector<pair<int, int>> edges;\n            for (int i = 0; i < n - 1; i++) {\n                edges.push_back(make_pair(cities[i], cities[i + 1]));\n            }\n            return edges;\n        }\n    } else {\n        // Split into two halves\n        int mid = n / 2;\n        vector<int> A(cities.begin(), cities.begin() + mid);\n        vector<int> B(cities.begin() + mid, cities.end());\n\n        // Ensure both halves have at least 2 cities\n        if (A.size() < 2) {\n            A.push_back(B[0]);\n            B.erase(B.begin());\n        }\n        if (B.size() < 2) {\n            B.push_back(A.back());\n            A.pop_back();\n        }\n\n        // Build trees for both halves\n        vector<pair<int, int>> treeA = build_tree(A);\n        vector<pair<int, int>> treeB = build_tree(B);\n\n        // Connect the two halves\n        vector<pair<int, int>> edges_connect;\n        if (queries_used < Q) {\n            // Choose a set S of size L from the boundary\n            int k = min((int)A.size(), L / 2);\n            int l = L - k;\n            if (l > (int)B.size()) {\n                l = B.size();\n                k = L - l;\n            }\n            vector<int> S;\n            // Add last k cities from A\n            for (int i = A.size() - k; i < A.size(); i++) {\n                S.push_back(A[i]);\n            }\n            // Add first l cities from B\n            for (int i = 0; i < l; i++) {\n                S.push_back(B[i]);\n            }\n            vector<pair<int, int>> edges_S = do_query(S);\n            // Find the first edge that connects A and B\n            set<int> setA(A.begin(), A.end());\n            set<int> setB(B.begin(), B.end());\n            pair<int, int> connect_edge = make_pair(-1, -1);\n            for (auto& e : edges_S) {\n                int u = e.first, v = e.second;\n                if ((setA.count(u) && setB.count(v)) || (setA.count(v) && setB.count(u))) {\n                    connect_edge = e;\n                    break;\n                }\n            }\n            if (connect_edge.first == -1) {\n                // Fallback: connect the last of A and first of B\n                connect_edge = make_pair(A.back(), B[0]);\n            }\n            edges_connect.push_back(connect_edge);\n        } else {\n            // No queries left: use a direct edge between the two halves\n            edges_connect.push_back(make_pair(A.back(), B[0]));\n        }\n\n        // Combine all edges\n        vector<pair<int, int>> result;\n        result.reserve(treeA.size() + treeB.size() + edges_connect.size());\n        result.insert(result.end(), treeA.begin(), treeA.end());\n        result.insert(result.end(), treeB.begin(), treeB.end());\n        result.insert(result.end(), edges_connect.begin(), edges_connect.end());\n        return result;\n    }\n}\n\nint main() {\n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> G[i];\n    }\n    cx.resize(N);\n    cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cx[i] = (lx + rx) / 2;\n        cy[i] = (ly + ry) / 2;\n    }\n\n    // Sort cities by center\n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        if (cx[i] != cx[j]) return cx[i] < cx[j];\n        return cy[i] < cy[j];\n    });\n\n    // Split into groups according to G\n    vector<vector<int>> groups(M);\n    int start = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i] = vector<int>(indices.begin() + start, indices.begin() + start + G[i]);\n        start += G[i];\n    }\n\n    // Build spanning trees for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    for (int i = 0; i < M; i++) {\n        group_edges[i] = build_tree(groups[i]);\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        // Output cities of the group\n        for (int j = 0; j < groups[i].size(); j++) {\n            if (j) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // Output edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nbool can_slide(int r, int c, int tr, int tc, const vector<vector<bool>>& block, int N) {\n    if (r == tr) {\n        if (c < tc) {\n            for (int j = c+1; j <= tc; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc+1 < N) {\n                if (!block[r][tc+1]) return false;\n            }\n            return true;\n        } else if (c > tc) {\n            for (int j = tc; j < c; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc-1 >= 0) {\n                if (!block[r][tc-1]) return false;\n            }\n            return true;\n        }\n    } else if (c == tc) {\n        if (r < tr) {\n            for (int i = r+1; i <= tr; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr+1 < N) {\n                if (!block[tr+1][c]) return false;\n            }\n            return true;\n        } else if (r > tr) {\n            for (int i = tr; i < r; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr-1 >= 0) {\n                if (!block[tr-1][c]) return false;\n            }\n            return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.push_back({r, c});\n    }\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    int r = r0, c = c0;\n    vector<string> actions;\n\n    for (int idx = 0; idx < M; idx++) {\n        int tr = targets[idx].first;\n        int tc = targets[idx].second;\n\n        while (r != tr || c != tc) {\n            if (can_slide(r, c, tr, tc, block, N)) {\n                if (r == tr) {\n                    if (c < tc) {\n                        actions.push_back(\"S R\");\n                        c = tc;\n                    } else {\n                        actions.push_back(\"S L\");\n                        c = tc;\n                    }\n                } else if (c == tc) {\n                    if (r < tr) {\n                        actions.push_back(\"S D\");\n                        r = tr;\n                    } else {\n                        actions.push_back(\"S U\");\n                        r = tr;\n                    }\n                }\n                continue;\n            }\n\n            int dr = tr - r;\n            int dc = tc - c;\n            int adr = abs(dr);\n            int adc = abs(dc);\n\n            if (adr > adc) {\n                if (dr > 0) {\n                    actions.push_back(\"M D\");\n                    r++;\n                } else {\n                    actions.push_back(\"M U\");\n                    r--;\n                }\n            } else if (adc > adr) {\n                if (dc > 0) {\n                    actions.push_back(\"M R\");\n                    c++;\n                } else {\n                    actions.push_back(\"M L\");\n                    c--;\n                }\n            } else {\n                if (tr == N-1 || tr == 0) {\n                    if (dr > 0) {\n                        actions.push_back(\"M D\");\n                        r++;\n                    } else if (dr < 0) {\n                        actions.push_back(\"M U\");\n                        r--;\n                    } else {\n                        if (dc > 0) {\n                            actions.push_back(\"M R\");\n                            c++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            c--;\n                        }\n                    }\n                } else if (tc == N-1 || tc == 0) {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else if (dc < 0) {\n                        actions.push_back(\"M L\");\n                        c--;\n                    } else {\n                        if (dr > 0) {\n                            actions.push_back(\"M D\");\n                            r++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            r--;\n                        }\n                    }\n                } else {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        c--;\n                    }\n                }\n            }\n        }\n    }\n\n    for (const string& action : actions) {\n        cout << action << endl;\n    }\n\n    return 0;\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n;\n    cin >> n;\n\n    vector<Company> companies(n);\n    for (int i = 0; i < n; i++) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n\n    // Sort by desired area descending\n    sort(companies.begin(), companies.end(), [](const Company& a, const Company& b) {\n        return a.r > b.r;\n    });\n\n    vector<Rect> assigned_rects;\n\n    for (int i = 0; i < n; i++) {\n        int L = companies[i].x;\n        int R = companies[i].x + 1;\n        int T = companies[i].y;\n        int B = companies[i].y + 1;\n\n        bool expanded = true;\n        while (expanded) {\n            expanded = false;\n            // try left\n            if (L > 0) {\n                int new_L = L - 1;\n                bool valid = true;\n                // Check centers\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (new_L <= xj && xj < R && T <= yj && yj < B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (new_L < rect.c && rect.a < R && T < rect.d && rect.b < B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    L = new_L;\n                    expanded = true;\n                    continue;\n                }\n            }\n            // try right\n            if (R < 10000) {\n                int new_R = R + 1;\n                bool valid = true;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (L <= xj && xj < new_R && T <= yj && yj < B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (L < rect.c && rect.a < new_R && T < rect.d && rect.b < B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    R = new_R;\n                    expanded = true;\n                    continue;\n                }\n            }\n            // try top\n            if (T > 0) {\n                int new_T = T - 1;\n                bool valid = true;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (L <= xj && xj < R && new_T <= yj && yj < B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (L < rect.c && rect.a < R && new_T < rect.d && rect.b < B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    T = new_T;\n                    expanded = true;\n                    continue;\n                }\n            }\n            // try bottom\n            if (B < 10000) {\n                int new_B = B + 1;\n                bool valid = true;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    int xj = companies[j].x;\n                    int yj = companies[j].y;\n                    if (L <= xj && xj < R && T <= yj && yj < new_B) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (valid) {\n                    for (const auto& rect : assigned_rects) {\n                        if (L < rect.c && rect.a < R && T < rect.d && rect.b < new_B) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                }\n                if (valid) {\n                    B = new_B;\n                    expanded = true;\n                    continue;\n                }\n            }\n        }\n\n        // Find best sub-rectangle\n        int max_w = R - L;\n        int max_h = B - T;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - companies[i].r);\n\n        for (int w = 1; w <= max_w; w++) {\n            int left_min = max(L, companies[i].x - w + 1);\n            int left_max = min(companies[i].x, R - w);\n            if (left_min > left_max) continue;\n\n            int h0 = companies[i].r / w;\n            int h1 = (companies[i].r + w - 1) / w;\n            vector<int> candidates = {h0-1, h0, h0+1, h1-1, h1, h1+1};\n            for (int h : candidates) {\n                if (h < 1 || h > max_h) continue;\n                int top_min = max(T, companies[i].y - h + 1);\n                int top_max = min(companies[i].y, B - h);\n                if (top_min > top_max) continue;\n\n                int area = w * h;\n                int diff = abs(area - companies[i].r);\n                if (diff < best_diff) {\n                    best_diff = diff;\n                    best_w = w;\n                    best_h = h;\n                }\n            }\n        }\n\n        int left = max(L, companies[i].x - best_w + 1);\n        int top = max(T, companies[i].y - best_h + 1);\n        cout << left << \" \" << top << \" \" << left + best_w << \" \" << top + best_h << \"\\n\";\n\n        assigned_rects.push_back({left, top, left+best_w, top+best_h});\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nstruct Candidate {\n    int score;\n    int ni;\n    int nj;\n};\n\nint main() {\n    int si, sj;\n    cin >> si >> sj;\n    vector<vector<int>> t(50, vector<int>(50));\n    vector<vector<int>> p(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[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        }\n    }\n    \n    set<int> visitedTiles;\n    visitedTiles.insert(t[si][sj]);\n    \n    int i = si, j = sj;\n    string path = \"\";\n    \n    while (true) {\n        vector<Candidate> candidates1;\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 >= 50 || nj < 0 || nj >= 50) continue;\n            int tid = t[ni][nj];\n            if (visitedTiles.find(tid) != visitedTiles.end()) continue;\n            candidates1.push_back({p[ni][nj], ni, nj});\n        }\n        \n        if (candidates1.empty()) break;\n        \n        int best_score = -1;\n        int best_ni = -1, best_nj = -1;\n        \n        for (auto &cand : candidates1) {\n            int score1 = cand.score;\n            int ni1 = cand.ni;\n            int nj1 = cand.nj;\n            int tid1 = t[ni1][nj1];\n            \n            set<int> temp_visited = visitedTiles;\n            temp_visited.insert(tid1);\n            \n            int best_score2 = -1;\n            for (int d2 = 0; d2 < 4; d2++) {\n                int ni2 = ni1 + dx[d2];\n                int nj2 = nj1 + dy[d2];\n                if (ni2 < 0 || ni2 >= 50 || nj2 < 0 || nj2 >= 50) continue;\n                if (ni2 == i && nj2 == j) continue;\n                int tid2 = t[ni2][nj2];\n                if (temp_visited.find(tid2) != temp_visited.end()) continue;\n                if (p[ni2][nj2] > best_score2) {\n                    best_score2 = p[ni2][nj2];\n                }\n            }\n            \n            int total_score = score1;\n            if (best_score2 != -1) {\n                total_score += best_score2;\n            }\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_ni = ni1;\n                best_nj = nj1;\n            }\n        }\n        \n        int di = best_ni - i;\n        int dj = best_nj - j;\n        if (di == -1) path += 'U';\n        else if (di == 1) path += 'D';\n        else if (dj == -1) path += 'L';\n        else if (dj == 1) path += 'R';\n        \n        visitedTiles.insert(t[best_ni][best_nj]);\n        i = best_ni;\n        j = best_nj;\n    }\n    \n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <string>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nconst double low_bound = 1000.0;\nconst double high_bound = 9000.0;\n\ndouble H_est[30][29];\ndouble V_est[29][30];\nint H_count[30][29];\nint V_count[29][30];\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\ndouble get_edge_weight(int i, int j, int ni, int nj) {\n    if (ni == i-1 && nj == j) {\n        return V_est[i-1][j];\n    } else if (ni == i+1 && nj == j) {\n        return V_est[i][j];\n    } else if (ni == i && nj == j-1) {\n        return H_est[i][j-1];\n    } else if (ni == i && nj == j+1) {\n        return H_est[i][j];\n    }\n    return 1e18;\n}\n\nvoid update_edge(int i, int j, int ni, int nj, double delta) {\n    if (ni == i-1 && nj == j) {\n        V_est[i-1][j] += delta;\n        if (V_est[i-1][j] < low_bound) V_est[i-1][j] = low_bound;\n        if (V_est[i-1][j] > high_bound) V_est[i-1][j] = high_bound;\n        V_count[i-1][j]++;\n    } else if (ni == i+1 && nj == j) {\n        V_est[i][j] += delta;\n        if (V_est[i][j] < low_bound) V_est[i][j] = low_bound;\n        if (V_est[i][j] > high_bound) V_est[i][j] = high_bound;\n        V_count[i][j]++;\n    } else if (ni == i && nj == j-1) {\n        H_est[i][j-1] += delta;\n        if (H_est[i][j-1] < low_bound) H_est[i][j-1] = low_bound;\n        if (H_est[i][j-1] > high_bound) H_est[i][j-1] = high_bound;\n        H_count[i][j-1]++;\n    } else if (ni == i && nj == j+1) {\n        H_est[i][j] += delta;\n        if (H_est[i][j] < low_bound) H_est[i][j] = low_bound;\n        if (H_est[i][j] > high_bound) H_est[i][j] = high_bound;\n        H_count[i][j]++;\n    }\n}\n\nstring dijkstra_with_heuristic(int si, int sj, int ti, int tj, double &est_length) {\n    vector<vector<double>> dist(30, vector<double>(30, 1e18));\n    vector<vector<pair<int, int>>> parent(30, vector<pair<int, int>>(30, {-1, -1}));\n    \n    // Priority queue with Manhattan distance tie-breaker\n    // Tuple: (distance, manhattan_distance, i, j)\n    priority_queue<tuple<double, double, int, int>, \n                   vector<tuple<double, double, int, int>>, \n                   greater<tuple<double, double, int, int>>> pq;\n    \n    auto manhattan = [](int i, int j, int ti, int tj) {\n        return abs(i - ti) + abs(j - tj);\n    };\n    \n    dist[si][sj] = 0.0;\n    pq.push(make_tuple(0.0, manhattan(si, sj, ti, tj), si, sj));\n\n    while (!pq.empty()) {\n        auto [d, h, i, j] = pq.top();\n        pq.pop();\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n            double w = get_edge_weight(i, j, ni, nj);\n            if (dist[ni][nj] > dist[i][j] + w) {\n                dist[ni][nj] = dist[i][j] + w;\n                parent[ni][nj] = make_pair(i, j);\n                pq.push(make_tuple(dist[ni][nj], manhattan(ni, nj, ti, tj), ni, nj));\n            }\n        }\n    }\n\n    vector<pair<int, int>> path_nodes;\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        path_nodes.push_back({i, j});\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    path_nodes.push_back({si, sj});\n    reverse(path_nodes.begin(), path_nodes.end());\n\n    string path_str = \"\";\n    est_length = 0.0;\n    for (int idx = 0; idx < path_nodes.size()-1; idx++) {\n        int i1 = path_nodes[idx].first;\n        int j1 = path_nodes[idx].second;\n        int i2 = path_nodes[idx+1].first;\n        int j2 = path_nodes[idx+1].second;\n        char move;\n        if (i2 == i1-1) move = 'U';\n        else if (i2 == i1+1) move = 'D';\n        else if (j2 == j1-1) move = 'L';\n        else if (j2 == j1+1) move = 'R';\n        path_str += move;\n        est_length += get_edge_weight(i1, j1, i2, j2);\n    }\n\n    return path_str;\n}\n\nint main() {\n    // Initialize estimates and counters\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 29; j++) {\n            H_est[i][j] = 5000.0;\n            H_count[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 30; j++) {\n            V_est[i][j] = 5000.0;\n            V_count[i][j] = 0;\n        }\n    }\n\n    int si, sj, ti, tj;\n    for (int k = 0; k < 1000; k++) {\n        cin >> si >> sj >> ti >> tj;\n        \n        double est_length;\n        string path = dijkstra_with_heuristic(si, sj, ti, tj, est_length);\n        cout << path << endl;\n        cout.flush();\n\n        long long F;\n        cin >> F;\n\n        int n = path.size();\n        if (n == 0) continue;\n\n        double error = static_cast<double>(F) - est_length;\n        \n        // More aggressive early learning: start at 0.25, decay to 0.05\n        double alpha = 0.25 - 0.20 * (k / 1000.0);\n        \n        // Distribute error with improved edge-specific factors\n        int cur_i = si, cur_j = sj;\n        for (char move : path) {\n            int next_i = cur_i, next_j = cur_j;\n            if (move == 'U') next_i--;\n            else if (move == 'D') next_i++;\n            else if (move == 'L') next_j--;\n            else if (move == 'R') next_j++;\n\n            // Get current edge count\n            int count = 0;\n            if (next_i == cur_i-1) count = V_count[cur_i-1][cur_j];\n            else if (next_i == cur_i+1) count = V_count[cur_i][cur_j];\n            else if (next_j == cur_j-1) count = H_count[cur_i][cur_j-1];\n            else if (next_j == cur_j+1) count = H_count[cur_i][cur_j];\n            \n            // More aggressive decay for frequently traversed edges\n            double edge_alpha = alpha * exp(-0.5 * count);\n            double delta = (error / n) * edge_alpha;\n            \n            update_edge(cur_i, cur_j, next_i, next_j, delta);\n\n            cur_i = next_i;\n            cur_j = next_j;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <map>\n#include <set>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\n// Global random generator\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct StringInfo {\n    string s;\n    int id;\n    int len;\n    map<char, int> char_count;\n    set<char> unique_chars;\n    double rarity_score;\n};\n\nbool try_place_horizontal(vector<string>& mat, const string& str, int N) {\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 < str.size(); p++) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < str.size(); p++) {\n                    int col = (j + p) % N;\n                    mat[i][col] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool try_place_vertical(vector<string>& mat, const string& str, int N) {\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            bool ok = true;\n            for (int p = 0; p < str.size(); p++) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < str.size(); p++) {\n                    int row = (i + p) % N;\n                    mat[row][j] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool try_place(vector<string>& mat, const string& str, int N) {\n    if (try_place_horizontal(mat, str, N)) return true;\n    if (try_place_vertical(mat, str, N)) return true;\n    return false;\n}\n\ntuple<int, int, vector<string>> solve_with_order(const vector<StringInfo>& strings, int N, const vector<int>& order) {\n    vector<string> mat(N, string(N, '.'));\n    vector<bool> covered(strings.size(), false);\n    int c = 0;\n    \n    // First pass: place strings in given order\n    for (int idx : order) {\n        if (covered[idx]) continue;\n        const string& str = strings[idx].s;\n        if (try_place(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        }\n    }\n    \n    // Second pass: try uncovered strings with different strategies\n    vector<int> uncovered;\n    for (int i = 0; i < strings.size(); i++) {\n        if (!covered[i]) uncovered.push_back(i);\n    }\n    \n    // Sort uncovered by length descending\n    sort(uncovered.begin(), uncovered.end(), [&](int a, int b) {\n        return strings[a].len > strings[b].len;\n    });\n    \n    for (int idx : uncovered) {\n        if (covered[idx]) continue;\n        const string& str = strings[idx].s;\n        if (try_place(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        }\n    }\n    \n    // Third pass: try with reversed horizontal/vertical order for remaining\n    for (int idx : uncovered) {\n        if (covered[idx]) continue;\n        const string& str = strings[idx].s;\n        // Try vertical first, then horizontal\n        if (try_place_vertical(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        } else if (try_place_horizontal(mat, str, N)) {\n            covered[idx] = true;\n            c++;\n        }\n    }\n    \n    // Count dots\n    int d = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (mat[i][j] == '.') d++;\n        }\n    }\n    \n    return make_tuple(c, d, mat);\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> raw_strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> raw_strings[i];\n    }\n    \n    // Analyze strings\n    vector<StringInfo> strings(M);\n    map<char, int> global_char_freq;\n    \n    for (int i = 0; i < M; i++) {\n        strings[i].s = raw_strings[i];\n        strings[i].id = i;\n        strings[i].len = raw_strings[i].size();\n        \n        for (char c : raw_strings[i]) {\n            strings[i].char_count[c]++;\n            strings[i].unique_chars.insert(c);\n            global_char_freq[c]++;\n        }\n    }\n    \n    // Calculate rarity scores (lower frequency = higher rarity score)\n    for (int i = 0; i < M; i++) {\n        double rarity = 0;\n        for (char c : strings[i].unique_chars) {\n            rarity += 1.0 / (global_char_freq[c] + 1);\n        }\n        strings[i].rarity_score = rarity;\n    }\n    \n    // Generate multiple order strategies\n    vector<vector<int>> orders;\n    \n    // Strategy 1: Length descending\n    vector<int> order1(M);\n    iota(order1.begin(), order1.end(), 0);\n    sort(order1.begin(), order1.end(), [&](int a, int b) {\n        return strings[a].len > strings[b].len;\n    });\n    orders.push_back(order1);\n    \n    // Strategy 2: Rarity descending\n    vector<int> order2(M);\n    iota(order2.begin(), order2.end(), 0);\n    sort(order2.begin(), order2.end(), [&](int a, int b) {\n        return strings[a].rarity_score > strings[b].rarity_score;\n    });\n    orders.push_back(order2);\n    \n    // Strategy 3: Length + rarity (combined score)\n    vector<int> order3(M);\n    iota(order3.begin(), order3.end(), 0);\n    sort(order3.begin(), order3.end(), [&](int a, int b) {\n        double score_a = strings[a].len * 10 + strings[a].rarity_score;\n        double score_b = strings[b].len * 10 + strings[b].rarity_score;\n        return score_a > score_b;\n    });\n    orders.push_back(order3);\n    \n    // Strategy 4: Random shuffle\n    vector<int> order4(M);\n    iota(order4.begin(), order4.end(), 0);\n    shuffle(order4.begin(), order4.end(), rng);\n    orders.push_back(order4);\n    \n    // Strategy 5: Reverse length (short first)\n    vector<int> order5(M);\n    iota(order5.begin(), order5.end(), 0);\n    sort(order5.begin(), order5.end(), [&](int a, int b) {\n        return strings[a].len < strings[b].len;\n    });\n    orders.push_back(order5);\n    \n    // Try each strategy and keep the best\n    int best_c = -1;\n    int best_d = -1;\n    vector<string> best_mat;\n    \n    for (const auto& order : orders) {\n        auto [c, d, mat] = solve_with_order(strings, N, order);\n        \n        bool update = false;\n        if (c > best_c) {\n            update = true;\n        } else if (c == best_c) {\n            if (c < M) {\n                // For incomplete coverage, prefer fewer dots (more filled)\n                if (d < best_d) update = true;\n            } else {\n                // For complete coverage, prefer more dots\n                if (d > best_d) update = true;\n            }\n        }\n        \n        if (update) {\n            best_c = c;\n            best_d = d;\n            best_mat = mat;\n        }\n    }\n    \n    // Final optimization: fill remaining dots with most frequent character\n    // But only if we haven't covered all strings (to preserve dots for scoring)\n    if (best_c < M) {\n        // Find most frequent character in current matrix\n        map<char, int> freq;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_mat[i][j] != '.') {\n                    freq[best_mat[i][j]]++;\n                }\n            }\n        }\n        \n        char best_char = 'A';\n        int best_count = -1;\n        for (auto [c, count] : freq) {\n            if (count > best_count) {\n                best_count = count;\n                best_char = c;\n            }\n        }\n        \n        // Fill dots with the most frequent character\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_mat[i][j] == '.') {\n                    best_mat[i][j] = best_char;\n                }\n            }\n        }\n    }\n    \n    // Output the best matrix\n    for (int i = 0; i < N; i++) {\n        cout << best_mat[i] << endl;\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ITER = 100000; // Safeguard against infinite loops\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    // Precompute horizontal and vertical segments\n    vector<vector<int>> hid(N, vector<int>(N, -1));\n    vector<vector<int>> vid(N, vector<int>(N, -1));\n    int totalH = 0, totalV = 0;\n\n    // Horizontal segments\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '#') continue;\n            if (j == 0 || grid[i][j-1] == '#') {\n                int k = j;\n                while (k < N && grid[i][k] != '#') {\n                    hid[i][k] = totalH;\n                    k++;\n                }\n                totalH++;\n            }\n        }\n    }\n\n    // Vertical segments\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][j] == '#') continue;\n            if (i == 0 || grid[i-1][j] == '#') {\n                int k = i;\n                while (k < N && grid[k][j] != '#') {\n                    vid[k][j] = totalV;\n                    k++;\n                }\n                totalV++;\n            }\n        }\n    }\n\n    vector<bool> uncoveredH(totalH, true);\n    vector<bool> uncoveredV(totalV, true);\n\n    // Cover start position's segments\n    int startH = hid[si][sj];\n    int startV = vid[si][sj];\n    if (startH != -1) uncoveredH[startH] = false;\n    if (startV != -1) uncoveredV[startV] = false;\n\n    int cur_i = si, cur_j = sj;\n    string route = \"\";\n\n    int iter = 0;\n    while (iter < MAX_ITER) {\n        // Check if all segments are covered\n        bool has_uncovered = false;\n        for (bool b : uncoveredH) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) for (bool b : uncoveredV) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) break;\n\n        // Run Dijkstra to find shortest paths\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1,-1}));\n        vector<vector<char>> move_dir(N, vector<char>(N, 0));\n        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;\n\n        dist[cur_i][cur_j] = 0;\n        pq.push({0, cur_i, cur_j});\n\n        while (!pq.empty()) {\n            auto [cost, i, j] = pq.top();\n            pq.pop();\n            if (cost != dist[i][j]) continue;\n            const int dx[4] = {-1, 1, 0, 0};\n            const int dy[4] = {0, 0, -1, 1};\n            const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n                if (grid[ni][nj] == '#') continue;\n                int ncost = cost + (grid[ni][nj] - '0');\n                if (ncost < dist[ni][nj]) {\n                    dist[ni][nj] = ncost;\n                    parent[ni][nj] = {i, j};\n                    move_dir[ni][nj] = dirs[d];\n                    pq.push({ncost, ni, nj});\n                }\n            }\n        }\n\n        // Select candidate: prioritize covering more uncovered segments\n        int best_i = -1, best_j = -1;\n        int best_gain = -1;\n        int best_cost = INF;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == '#' || dist[i][j] == INF) continue;\n                int gain = 0;\n                if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) gain++;\n                if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) gain++;\n                if (gain == 0) continue;\n                if (gain > best_gain || (gain == best_gain && dist[i][j] < best_cost)) {\n                    best_gain = gain;\n                    best_cost = dist[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n\n        // If no candidate found, break (shouldn't happen but safe)\n        if (best_i == -1) break;\n\n        // Build path and update coverage\n        string path_moves = \"\";\n        int i = best_i, j = best_j;\n        while (i != cur_i || j != cur_j) {\n            char m = move_dir[i][j];\n            path_moves = m + path_moves;\n            if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) uncoveredH[hid[i][j]] = false;\n            if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) uncoveredV[vid[i][j]] = false;\n            auto [pi, pj] = parent[i][j];\n            i = pi;\n            j = pj;\n        }\n\n        route += path_moves;\n        cur_i = best_i;\n        cur_j = best_j;\n        iter++;\n    }\n\n    // Return to start\n    vector<vector<int>> dist_ret(N, vector<int>(N, INF));\n    vector<vector<pair<int,int>>> parent_ret(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<char>> move_dir_ret(N, vector<char>(N, 0));\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq_ret;\n\n    dist_ret[cur_i][cur_j] = 0;\n    pq_ret.push({0, cur_i, cur_j});\n\n    while (!pq_ret.empty()) {\n        auto [cost, i, j] = pq_ret.top();\n        pq_ret.pop();\n        if (cost != dist_ret[i][j]) continue;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n            if (grid[ni][nj] == '#') continue;\n            int ncost = cost + (grid[ni][nj] - '0');\n            if (ncost < dist_ret[ni][nj]) {\n                dist_ret[ni][nj] = ncost;\n                parent_ret[ni][nj] = {i, j};\n                move_dir_ret[ni][nj] = dirs[d];\n                pq_ret.push({ncost, ni, nj});\n            }\n        }\n    }\n\n    if (dist_ret[si][sj] == INF) {\n        // Should not happen as the grid is connected, but just in case\n        cerr << \"No path back to start!\" << endl;\n    } else {\n        string return_path = \"\";\n        int i = si, j = sj;\n        while (i != cur_i || j != cur_j) {\n            auto [pi, pj] = parent_ret[i][j];\n            char m = move_dir_ret[i][j];\n            return_path = m + return_path;\n            i = pi;\n            j = pj;\n        }\n        route += return_path;\n    }\n\n    cout << route << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <map>\n#include <set>\n#include <cmath>\n#include <iomanip>\n#include <climits>\n\nusing namespace std;\n\nstruct Task {\n    int id;\n    vector<int> requirements;\n    vector<int> children;\n    int in_degree;\n    int depth_forward;\n    double criticality;\n};\n\nstruct TeamMember {\n    int id;\n    vector<int> skills; // estimated skills\n    int current_task; // -1 if free\n    int busy_until; // day when current task will complete (estimated)\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<Task> tasks(N);\n    for (int i = 0; i < N; i++) {\n        tasks[i].id = i;\n        tasks[i].requirements.resize(K);\n        for (int k = 0; k < K; k++) {\n            cin >> tasks[i].requirements[k];\n        }\n        tasks[i].in_degree = 0;\n    }\n    \n    // Read dependencies\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        tasks[u].children.push_back(v);\n        tasks[v].in_degree++;\n    }\n    \n    // Compute depth_forward (longest path to end)\n    for (int i = N-1; i >= 0; i--) {\n        if (tasks[i].children.empty()) {\n            tasks[i].depth_forward = 0;\n        } else {\n            int max_depth = 0;\n            for (int child : tasks[i].children) {\n                max_depth = max(max_depth, tasks[child].depth_forward);\n            }\n            tasks[i].depth_forward = 1 + max_depth;\n        }\n    }\n    \n    // Initialize team members\n    vector<TeamMember> members(M);\n    for (int i = 0; i < M; i++) {\n        members[i].id = i;\n        members[i].skills.assign(K, 0); // Start with 0 skills\n        members[i].current_task = -1;\n        members[i].busy_until = 0;\n    }\n    \n    // State tracking\n    vector<int> task_status(N, -1); // -1: not started, 0: assigned, 1: completed\n    vector<int> start_day(N, -1);\n    vector<int> current_in_degree = [&]() {\n        vector<int> deg(N);\n        for (int i = 0; i < N; i++) deg[i] = tasks[i].in_degree;\n        return deg;\n    }();\n    \n    // Learning parameters\n    const double LEARNING_RATE = 0.2;\n    const int MAX_DAYS = 2000;\n    \n    for (int day = 1; day <= MAX_DAYS; day++) {\n        // Read feedback from previous day\n        if (day > 1) {\n            int n_completed;\n            cin >> n_completed;\n            \n            if (n_completed == -1) {\n                break; // All tasks completed or day limit reached\n            }\n            \n            vector<int> completed_members(n_completed);\n            for (int i = 0; i < n_completed; i++) {\n                cin >> completed_members[i];\n                completed_members[i]--; // Convert to 0-indexed\n            }\n            \n            // Update skills based on completed tasks\n            for (int member_idx : completed_members) {\n                int task_idx = members[member_idx].current_task;\n                if (task_idx == -1) continue;\n                \n                // Calculate actual time taken\n                int time_taken = day - start_day[task_idx];\n                \n                // Update skill estimates\n                if (time_taken > 1) {\n                    int current_gap = 0;\n                    vector<int> gaps(K, 0);\n                    \n                    for (int k = 0; k < K; k++) {\n                        if (tasks[task_idx].requirements[k] > members[member_idx].skills[k]) {\n                            gaps[k] = tasks[task_idx].requirements[k] - members[member_idx].skills[k];\n                            current_gap += gaps[k];\n                        }\n                    }\n                    \n                    if (current_gap > 0) {\n                        double extra_time = time_taken - 1;\n                        for (int k = 0; k < K; k++) {\n                            if (gaps[k] > 0) {\n                                double increase = extra_time * LEARNING_RATE * (gaps[k] / (double)current_gap);\n                                int new_skill = members[member_idx].skills[k] + (int)round(increase);\n                                // Cap at requirement to avoid overestimation\n                                new_skill = min(new_skill, tasks[task_idx].requirements[k]);\n                                members[member_idx].skills[k] = new_skill;\n                            }\n                        }\n                    }\n                }\n                \n                // Mark task as completed\n                task_status[task_idx] = 1;\n                members[member_idx].current_task = -1;\n                members[member_idx].busy_until = 0;\n                \n                // Update dependencies for children\n                for (int child : tasks[task_idx].children) {\n                    current_in_degree[child]--;\n                }\n            }\n        }\n        \n        // Find available tasks (all dependencies completed, not started)\n        vector<int> available_tasks;\n        for (int i = 0; i < N; i++) {\n            if (current_in_degree[i] == 0 && task_status[i] == -1) {\n                available_tasks.push_back(i);\n            }\n        }\n        \n        // Find free team members\n        vector<int> free_members;\n        for (int i = 0; i < M; i++) {\n            if (members[i].current_task == -1) {\n                free_members.push_back(i);\n            }\n        }\n        \n        // If no work to do, output 0 and continue\n        if (available_tasks.empty() || free_members.empty()) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n        \n        // Assign tasks using greedy heuristic\n        vector<pair<int, int>> assignments;\n        \n        // Calculate estimated time for each (member, task) pair\n        auto estimate_time = [&](int member_idx, int task_idx) -> double {\n            int gap = 0;\n            for (int k = 0; k < K; k++) {\n                if (tasks[task_idx].requirements[k] > members[member_idx].skills[k]) {\n                    gap += tasks[task_idx].requirements[k] - members[member_idx].skills[k];\n                }\n            }\n            if (gap == 0) return 1.0;\n            // Expected time: max(1, gap + average_offset) \u2248 gap + 1 (since average offset is 0)\n            return gap + 1.0;\n        };\n        \n        // Greedy assignment: prioritize critical tasks and assign to best member\n        while (!free_members.empty() && !available_tasks.empty()) {\n            // Find the most critical available task\n            int best_task = -1;\n            double best_priority = -1;\n            int best_task_idx = -1;\n            \n            for (int i = 0; i < available_tasks.size(); i++) {\n                int task_idx = available_tasks[i];\n                // Priority: criticality (depth) - we could also consider task requirements\n                double priority = tasks[task_idx].depth_forward;\n                if (priority > best_priority) {\n                    best_priority = priority;\n                    best_task = task_idx;\n                    best_task_idx = i;\n                }\n            }\n            \n            // Find the best member for this task\n            int best_member = -1;\n            double best_time = 1e9;\n            int best_member_idx = -1;\n            \n            for (int i = 0; i < free_members.size(); i++) {\n                int member_idx = free_members[i];\n                double est_time = estimate_time(member_idx, best_task);\n                if (est_time < best_time) {\n                    best_time = est_time;\n                    best_member = member_idx;\n                    best_member_idx = i;\n                }\n            }\n            \n            // Make assignment\n            assignments.push_back({best_member, best_task});\n            task_status[best_task] = 0;\n            members[best_member].current_task = best_task;\n            start_day[best_task] = day;\n            members[best_member].busy_until = day + (int)ceil(best_time) - 1;\n            \n            // Remove from available lists\n            available_tasks.erase(available_tasks.begin() + best_task_idx);\n            free_members.erase(free_members.begin() + best_member_idx);\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& assignment : assignments) {\n            cout << \" \" << assignment.first + 1 << \" \" << assignment.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Order {\n    int a, b, c, d;\n    int index;\n};\n\ninline int manhattan(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nvector<Order> selectOrders(const vector<Order>& allOrders) {\n    Point office(400, 400);\n    vector<pair<int, int>> orderCosts;\n    \n    for (int i = 0; i < (int)allOrders.size(); i++) {\n        Point pickup(allOrders[i].a, allOrders[i].b);\n        Point delivery(allOrders[i].c, allOrders[i].d);\n        int cost = manhattan(office, pickup) + manhattan(pickup, delivery) + manhattan(delivery, office);\n        orderCosts.push_back({cost, i});\n    }\n    \n    sort(orderCosts.begin(), orderCosts.end());\n    \n    vector<Order> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(allOrders[orderCosts[i].second]);\n    }\n    return selected;\n}\n\nvector<Point> buildRoute(const vector<Order>& selected) {\n    vector<Point> route;\n    Point office(400, 400);\n    route.push_back(office);\n    \n    // Track state: 0 = not picked up, 1 = picked up but not delivered, 2 = delivered\n    vector<int> state(selected.size(), 0);\n    Point current = office;\n    \n    int deliveredCount = 0;\n    while (deliveredCount < (int)selected.size()) {\n        int bestDist = 1e9;\n        Point bestPoint;\n        int bestOrderIdx = -1;\n        bool bestIsDelivery = false;\n        \n        // Find closest available pickup\n        for (int i = 0; i < (int)selected.size(); i++) {\n            if (state[i] == 0) {\n                Point pickup(selected[i].a, selected[i].b);\n                int dist = manhattan(current, pickup);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPoint = pickup;\n                    bestOrderIdx = i;\n                    bestIsDelivery = false;\n                }\n            }\n        }\n        \n        // Find closest available delivery\n        for (int i = 0; i < (int)selected.size(); i++) {\n            if (state[i] == 1) {\n                Point delivery(selected[i].c, selected[i].d);\n                int dist = manhattan(current, delivery);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPoint = delivery;\n                    bestOrderIdx = i;\n                    bestIsDelivery = true;\n                }\n            }\n        }\n        \n        // Add best point to route\n        route.push_back(bestPoint);\n        current = bestPoint;\n        \n        // Update state\n        if (bestIsDelivery) {\n            state[bestOrderIdx] = 2;\n            deliveredCount++;\n        } else {\n            state[bestOrderIdx] = 1;\n        }\n    }\n    \n    route.push_back(office);\n    return route;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<Order> allOrders;\n    for (int i = 0; i < 1000; i++) {\n        Order order;\n        cin >> order.a >> order.b >> order.c >> order.d;\n        order.index = i + 1;\n        allOrders.push_back(order);\n    }\n    \n    vector<Order> selected = selectOrders(allOrders);\n    vector<Point> route = buildRoute(selected);\n    \n    cout << selected.size();\n    for (const Order& order : selected) {\n        cout << \" \" << order.index;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const Point& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int INF = 1000000000;\n\nvector<int> parent;\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<pair<int, int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n    }\n\n    vector<int> d(M);\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        long long dx = x[u] - x[v];\n        long long dy = y[u] - y[v];\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = (int)round(dist);\n    }\n\n    parent.resize(N);\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n\n    vector<vector<int>> count_between(N, vector<int>(N, 0));\n    vector<vector<int>> min_baseline_between(N, vector<int>(N, INF));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        count_between[u][v] = 1;\n        count_between[v][u] = 1;\n        min_baseline_between[u][v] = d[i];\n        min_baseline_between[v][u] = d[i];\n    }\n\n    vector<bool> is_rep(N, true);\n    int adopted_count = 0;\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n\n        int rep_u = find(u);\n        int rep_v = find(v);\n\n        if (rep_u == rep_v) {\n            cout << 0 << endl;\n        } else {\n            int current_count = count_between[rep_u][rep_v];\n            bool adopt = false;\n\n            if (current_count == 1) {\n                adopt = true;\n            } else {\n                if (l_i <= 2 * d[i]) {\n                    adopt = true;\n                } else {\n                    adopt = false;\n                }\n            }\n\n            count_between[rep_u][rep_v] = current_count - 1;\n            count_between[rep_v][rep_u] = current_count - 1;\n\n            if (adopt) {\n                cout << 1 << endl;\n                adopted_count++;\n\n                int new_rep = min(rep_u, rep_v);\n                int old_rep = max(rep_u, rep_v);\n\n                parent[old_rep] = new_rep;\n\n                for (int j = 0; j < N; j++) {\n                    if (is_rep[j] && j != new_rep && j != old_rep) {\n                        count_between[new_rep][j] += count_between[old_rep][j];\n                        if (min_baseline_between[new_rep][j] > min_baseline_between[old_rep][j]) {\n                            min_baseline_between[new_rep][j] = min_baseline_between[old_rep][j];\n                        }\n                        count_between[j][new_rep] = count_between[new_rep][j];\n                        min_baseline_between[j][new_rep] = min_baseline_between[new_rep][j];\n                    }\n                }\n\n                is_rep[old_rep] = false;\n\n                for (int j = 0; j < N; j++) {\n                    count_between[old_rep][j] = 0;\n                    count_between[j][old_rep] = 0;\n                    min_baseline_between[old_rep][j] = INF;\n                    min_baseline_between[j][old_rep] = INF;\n                }\n            } else {\n                cout << 0 << endl;\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\nusing namespace std;\n\nconst int dx4[4] = {-1, 1, 0, 0};\nconst int dy4[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int N;\n    cin >> N;\n    vector<int> pet_x(N), pet_y(N), pet_type(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n        pet_x[i]--; \n        pet_y[i]--;\n    }\n\n    int M;\n    cin >> M;\n    vector<int> human_x(M), human_y(M);\n    for (int i = 0; i < M; i++) {\n        cin >> human_x[i] >> human_y[i];\n        human_x[i]--;\n        human_y[i]--;\n    }\n\n    bool blocked[30][30] = {false};\n\n    for (int turn = 0; turn < 300; turn++) {\n        string action_string = \"\";\n        vector<char> actions(M, '.');\n\n        for (int i = 0; i < M; i++) {\n            int hx = human_x[i], hy = human_y[i];\n            int best_dist = 1000;\n            int best_pet = -1;\n            for (int j = 0; j < N; j++) {\n                int dist = abs(hx - pet_x[j]) + abs(hy - pet_y[j]);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pet = j;\n                }\n            }\n\n            if (best_dist <= 3 && best_pet != -1) {\n                int px = pet_x[best_pet], py = pet_y[best_pet];\n                int dx = px - hx;\n                int dy = py - hy;\n                int block_x = hx, block_y = hy;\n                if (abs(dx) > abs(dy)) {\n                    block_x += (dx > 0 ? 1 : -1);\n                } else {\n                    block_y += (dy > 0 ? 1 : -1);\n                }\n                if (block_x >= 0 && block_x < 30 && block_y >= 0 && block_y < 30) {\n                    bool occupied = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == block_x && pet_y[j] == block_y) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    if (!occupied) {\n                        for (int j = 0; j < M; j++) {\n                            if (human_x[j] == block_x && human_y[j] == block_y) {\n                                occupied = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (!occupied) {\n                        bool adjacent_pet = false;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = block_x + dx4[d];\n                            int ny = block_y + dy4[d];\n                            if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                            for (int j = 0; j < N; j++) {\n                                if (pet_x[j] == nx && pet_y[j] == ny) {\n                                    adjacent_pet = true;\n                                    break;\n                                }\n                            }\n                            if (adjacent_pet) break;\n                        }\n                        if (!adjacent_pet) {\n                            if (block_x == hx - 1) actions[i] = 'u';\n                            else if (block_x == hx + 1) actions[i] = 'd';\n                            else if (block_y == hy - 1) actions[i] = 'l';\n                            else if (block_y == hy + 1) actions[i] = 'r';\n                        }\n                    }\n                }\n                if (actions[i] == '.') {\n                    if (abs(dx) > abs(dy)) {\n                        if (dx > 0) actions[i] = 'U';\n                        else actions[i] = 'D';\n                    } else {\n                        if (dy > 0) actions[i] = 'L';\n                        else actions[i] = 'R';\n                    }\n                    int nx = hx, ny = hy;\n                    if (actions[i] == 'U') nx--;\n                    else if (actions[i] == 'D') nx++;\n                    else if (actions[i] == 'L') ny--;\n                    else if (actions[i] == 'R') ny++;\n                    if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30 || blocked[nx][ny]) {\n                        actions[i] = '.';\n                    } else {\n                        bool has_pet = false;\n                        for (int j = 0; j < N; j++) {\n                            if (pet_x[j] == nx && pet_y[j] == ny) {\n                                has_pet = true;\n                                break;\n                            }\n                        }\n                        if (has_pet) {\n                            actions[i] = '.';\n                        }\n                    }\n                }\n            } else {\n                int target_x = 14, target_y = 14;\n                int dx = target_x - hx;\n                int dy = target_y - hy;\n                if (abs(dx) > abs(dy)) {\n                    if (dx > 0) actions[i] = 'D';\n                    else actions[i] = 'U';\n                } else {\n                    if (dy > 0) actions[i] = 'R';\n                    else actions[i] = 'L';\n                }\n                int nx = hx, ny = hy;\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30 || blocked[nx][ny]) {\n                    actions[i] = '.';\n                } else {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (has_pet) {\n                        actions[i] = '.';\n                    }\n                }\n            }\n            action_string += actions[i];\n        }\n\n        cout << action_string << endl;\n        cout.flush();\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u' || actions[i] == 'd' || actions[i] == 'l' || actions[i] == 'r') {\n                int bx = human_x[i];\n                int by = human_y[i];\n                if (actions[i] == 'u') bx--;\n                else if (actions[i] == 'd') bx++;\n                else if (actions[i] == 'l') by--;\n                else if (actions[i] == 'r') by++;\n                if (bx >= 0 && bx < 30 && by >= 0 && by < 30) {\n                    blocked[bx][by] = true;\n                }\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U' || actions[i] == 'D' || actions[i] == 'L' || actions[i] == 'R') {\n                int nx = human_x[i];\n                int ny = human_y[i];\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx >= 0 && nx < 30 && ny >= 0 && ny < 30 && !blocked[nx][ny]) {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (!has_pet) {\n                        human_x[i] = nx;\n                        human_y[i] = ny;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            string move_str;\n            cin >> move_str;\n            if (move_str == \".\") continue;\n            for (char c : move_str) {\n                if (c == 'U') pet_x[i]--;\n                else if (c == 'D') pet_x[i]++;\n                else if (c == 'L') pet_y[i]--;\n                else if (c == 'R') pet_y[i]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <tuple>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int s_i, s_j, t_i, t_j;\n    double p;\n    cin >> s_i >> s_j >> t_i >> t_j >> p;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n\n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n\n    vector<vector<int>> dist(20, vector<int>(20, INT_MAX));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move_char(20, vector<char>(20, ' '));\n\n    queue<pair<int, int>> q;\n    dist[s_i][s_j] = 0;\n    q.push({s_i, s_j});\n\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (i == t_i && j == t_j) break;\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 >= 20 || nj < 0 || nj >= 20) continue;\n\n            bool canMove = true;\n            if (d == 0) {\n                if (i == 0) canMove = false;\n                else if (v[i-1][j] == '1') canMove = false;\n            } else if (d == 1) {\n                if (i == 19) canMove = false;\n                else if (v[i][j] == '1') canMove = false;\n            } else if (d == 2) {\n                if (j == 0) canMove = false;\n                else if (h[i][j-1] == '1') canMove = false;\n            } else if (d == 3) {\n                if (j == 19) canMove = false;\n                else if (h[i][j] == '1') canMove = false;\n            }\n\n            if (canMove && dist[ni][nj] == INT_MAX) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent[ni][nj] = {i, j};\n                move_char[ni][nj] = dir_char[d];\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    string path = \"\";\n    int i = t_i, j = t_j;\n    while (i != s_i || j != s_j) {\n        path += move_char[i][j];\n        auto [pi, pj] = parent[i][j];\n        i = pi;\n        j = pj;\n    }\n    reverse(path.begin(), path.end());\n\n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n\n    int L0 = path.size();\n    int r = 200 / L0;\n    if (r < 1) r = 1;\n\n    string result = \"\";\n    for (char c : path) {\n        for (int i = 0; i < r; i++) {\n            result += c;\n        }\n    }\n\n    if (result.size() > 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 di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nconst int base_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 to_table[8][4][4];\n\nvoid precompute_to_table() {\n    for (int t = 0; t < 8; t++) {\n        for (int r = 0; r < 4; r++) {\n            for (int d = 0; d < 4; d++) {\n                int s_in_orig = (d + r) % 4;\n                int s_out_orig = base_to[t][s_in_orig];\n                if (s_out_orig == -1) {\n                    to_table[t][r][d] = -1;\n                } else {\n                    to_table[t][r][d] = (s_out_orig - r + 4) % 4;\n                }\n            }\n        }\n    }\n}\n\nlong long compute_score(const vector<vector<int>>& grid, const vector<vector<int>>& rotations) {\n    bool visited[30][30][4] = {};\n    vector<long long> cycles;\n\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int si = i, sj = j, sd = d;\n                    int ci = i, cj = j, cd = d;\n                    long long steps = 0;\n                    bool is_cycle = false;\n                    while (true) {\n                        if (visited[ci][cj][cd]) {\n                            break;\n                        }\n                        visited[ci][cj][cd] = true;\n                        int t = grid[ci][cj];\n                        int r = rotations[ci][cj];\n                        int d2 = to_table[t][r][cd];\n                        if (d2 == -1) {\n                            break;\n                        }\n                        int ni = ci + di[d2];\n                        int nj = cj + dj[d2];\n                        if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) {\n                            break;\n                        }\n                        int nd = (d2 + 2) % 4;\n                        ci = ni;\n                        cj = nj;\n                        cd = nd;\n                        steps++;\n                        if (ci == si && cj == sj && cd == sd) {\n                            is_cycle = true;\n                            break;\n                        }\n                    }\n                    if (is_cycle) {\n                        cycles.push_back(steps);\n                    }\n                }\n            }\n        }\n    }\n\n    if (cycles.size() < 2) {\n        return 0;\n    }\n    sort(cycles.rbegin(), cycles.rend());\n    return cycles[0] * cycles[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    precompute_to_table();\n    const int num_test_cases = 100;\n\n    random_device rd;\n    mt19937 base_rng(rd());\n\n    for (int tc = 0; tc < num_test_cases; tc++) {\n        vector<vector<int>> grid(30, vector<int>(30));\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                cin >> grid[i][j];\n            }\n        }\n\n        mt19937 rng(base_rng());\n        vector<vector<int>> rotations(30, vector<int>(30));\n        uniform_int_distribution<int> dist(0, 3);\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                rotations[i][j] = dist(rng);\n            }\n        }\n\n        long long current_score = compute_score(grid, rotations);\n\n        int num_passes = 1;\n        for (int pass = 0; pass < num_passes; pass++) {\n            vector<pair<int, int>> tiles;\n            for (int i = 0; i < 30; i++) {\n                for (int j = 0; j < 30; j++) {\n                    tiles.push_back({i, j});\n                }\n            }\n            shuffle(tiles.begin(), tiles.end(), rng);\n\n            for (auto [i, j] : tiles) {\n                int best_rot = rotations[i][j];\n                long long best_score = current_score;\n                int orig_rot = rotations[i][j];\n\n                for (int r = 0; r < 4; r++) {\n                    if (r == orig_rot) continue;\n                    rotations[i][j] = r;\n                    long long score = compute_score(grid, rotations);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_rot = r;\n                    }\n                }\n\n                if (best_rot != orig_rot) {\n                    rotations[i][j] = best_rot;\n                    current_score = best_score;\n                } else {\n                    rotations[i][j] = orig_rot;\n                }\n            }\n        }\n\n        string output;\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                output += ('0' + rotations[i][j]);\n            }\n        }\n        cout << output << endl;\n    }\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <unordered_set>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nconst int MAX_N = 10;\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\n// Directions: U, D, L, R\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Cache for component computations\nvector<vector<int>> comp_id;\nvector<int> comp_size;\nint comp_counter = 0;\n\n// Hash function for board state\nstruct BoardHash {\n    size_t operator()(const vector<vector<int>>& b) const {\n        size_t h = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                h = h * 131 + b[i][j];\n            }\n        }\n        return h;\n    }\n};\n\n// Compute connected components with cycle detection\nvoid compute_components() {\n    comp_id.assign(N, vector<int>(N, -1));\n    comp_size.clear();\n    comp_counter = 0;\n    \n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            // BFS to find component\n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            comp_id[i][j] = comp_counter;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                size++;\n                \n                // Check all four directions\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    if (visited[nx][ny]) continue;\n                    \n                    // Check if there's a connection\n                    bool connected = false;\n                    if (d == 0 && (board[x][y] & 2) && (board[nx][ny] & 8)) connected = true; // U\n                    else if (d == 1 && (board[x][y] & 8) && (board[nx][ny] & 2)) connected = true; // D\n                    else if (d == 2 && (board[x][y] & 1) && (board[nx][ny] & 4)) connected = true; // L\n                    else if (d == 3 && (board[x][y] & 4) && (board[nx][ny] & 1)) connected = true; // R\n                    \n                    if (connected) {\n                        visited[nx][ny] = true;\n                        comp_id[nx][ny] = comp_counter;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            comp_size.push_back(size);\n            comp_counter++;\n        }\n    }\n}\n\n// Get the size of the largest tree (connected component without cycles)\nint get_largest_tree_size() {\n    compute_components();\n    \n    // For each component, check if it's a tree (connected, no cycles)\n    // A connected component with V vertices is a tree if it has exactly V-1 edges\n    vector<int> comp_edges(comp_counter, 0);\n    vector<bool> is_tree(comp_counter, true);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            int cid = comp_id[i][j];\n            \n            // Count edges from this tile\n            int edges = 0;\n            if (i > 0 && board[i-1][j] != 0 && (board[i][j] & 2) && (board[i-1][j] & 8)) edges++;\n            if (i < N-1 && board[i+1][j] != 0 && (board[i][j] & 8) && (board[i+1][j] & 2)) edges++;\n            if (j > 0 && board[i][j-1] != 0 && (board[i][j] & 1) && (board[i][j-1] & 4)) edges++;\n            if (j < N-1 && board[i][j+1] != 0 && (board[i][j] & 4) && (board[i][j+1] & 1)) edges++;\n            \n            comp_edges[cid] += edges;\n        }\n    }\n    \n    // Check if each component is a tree: edges = vertices - 1\n    int max_tree = 0;\n    for (int cid = 0; cid < comp_counter; cid++) {\n        if (comp_size[cid] == 0) continue;\n        if (comp_edges[cid] / 2 == comp_size[cid] - 1) { // Each edge counted twice\n            max_tree = max(max_tree, comp_size[cid]);\n        }\n    }\n    \n    return max_tree;\n}\n\n// Evaluate a move and return the resulting tree size\nint evaluate_move(int move, vector<vector<int>>& current_board, int ei, int ej) {\n    int ni = ei + di[move];\n    int nj = ej + dj[move];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return -1;\n    \n    swap(current_board[ei][ej], current_board[ni][nj]);\n    int score = get_largest_tree_size();\n    swap(current_board[ei][ej], current_board[ni][nj]); // backtrack\n    \n    return score;\n}\n\n// Lookahead search with limited depth\nint lookahead_search(int depth, vector<vector<int>>& current_board, int ei, int ej, string& best_seq, int current_best) {\n    if (depth == 0) {\n        int score = get_largest_tree_size();\n        if (score > current_best) {\n            current_best = score;\n        }\n        return current_best;\n    }\n    \n    for (int d = 0; d < 4; d++) {\n        int ni = ei + di[d];\n        int nj = ej + dj[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        \n        swap(current_board[ei][ej], current_board[ni][nj]);\n        int score = lookahead_search(depth-1, current_board, ni, nj, best_seq, current_best);\n        if (score > current_best) {\n            current_best = score;\n            best_seq = dir_char[d] + best_seq; // Note: this builds sequence in reverse\n        }\n        swap(current_board[ei][ej], current_board[ni][nj]);\n    }\n    \n    return current_best;\n}\n\nint main() {\n    auto start_time = high_resolution_clock::now();\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(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            char c = s[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = 10 + c - 'a';\n            }\n            if (board[i][j] == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int current_tree_size = get_largest_tree_size();\n    int target_size = N * N - 1;\n    \n    // If already optimal\n    if (current_tree_size == target_size) {\n        cout << result << endl;\n        return 0;\n    }\n    \n    // Main loop with time management\n    for (int step = 0; step < T; step++) {\n        auto current_time = high_resolution_clock::now();\n        auto elapsed = duration_cast<milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break; // Leave margin for time limit\n        \n        // Try to find best move with lookahead\n        int best_score = -1;\n        int best_move = -1;\n        \n        // First, try immediate moves\n        for (int d = 0; d < 4; d++) {\n            int score = evaluate_move(d, board, empty_i, empty_j);\n            if (score > best_score) {\n                best_score = score;\n                best_move = d;\n            }\n        }\n        \n        // If we have time, try 2-step lookahead for promising moves\n        if (step < T - 2 && elapsed < 2500) {\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                swap(board[empty_i][empty_j], board[ni][nj]);\n                \n                // Try second moves\n                for (int d2 = 0; d2 < 4; d2++) {\n                    if (d2 == d) continue; // Don't immediately undo\n                    int score2 = evaluate_move(d2, board, ni, nj);\n                    if (score2 > best_score) {\n                        best_score = score2;\n                        best_move = d;\n                    }\n                }\n                \n                swap(board[empty_i][empty_j], board[ni][nj]);\n            }\n        }\n        \n        // If no improvement, try random moves to escape local optima\n        if (best_score <= current_tree_size && step > T/2) {\n            vector<int> valid_moves;\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    valid_moves.push_back(d);\n                }\n            }\n            if (!valid_moves.empty()) {\n                best_move = valid_moves[rand() % valid_moves.size()];\n                best_score = evaluate_move(best_move, board, empty_i, empty_j);\n            }\n        }\n        \n        // If still no good move, break\n        if (best_move == -1) break;\n        \n        // Execute the best move\n        int ni = empty_i + di[best_move];\n        int nj = empty_j + dj[best_move];\n        swap(board[empty_i][empty_j], board[ni][nj]);\n        empty_i = ni;\n        empty_j = nj;\n        result += dir_char[best_move];\n        \n        current_tree_size = best_score;\n        \n        // If we achieved full tree, we can break early\n        if (current_tree_size == target_size) {\n            // We'll continue to try to reduce moves, but break if time is short\n            if (duration_cast<milliseconds>(high_resolution_clock::now() - start_time).count() > 2500) {\n                break;\n            }\n        }\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef __int128 int128;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Line {\n    Point p1, p2;\n};\n\n// Check if a line passes through a strawberry\nbool passes_through(const Line& l, const Point& s) {\n    ll dx = l.p2.x - l.p1.x;\n    ll dy = l.p2.y - l.p1.y;\n    int128 cross = int128(dx) * (s.y - l.p1.y) - int128(dy) * (s.x - l.p1.x);\n    return cross == 0;\n}\n\n// Extended Euclidean algorithm to solve a*x + b*y = gcd(a,b)\ntuple<ll, ll, ll> extended_gcd(ll a, ll b) {\n    if (b == 0) {\n        return {1, 0, a};\n    }\n    auto [x0, y0, g] = extended_gcd(b, a % b);\n    ll x = y0;\n    ll y = x0 - (a / b) * y0;\n    return {x, y, g};\n}\n\n// Generate a line from dx, dy, C\nLine generate_line_from_params(ll dx, ll dy, ll C) {\n    if (dx == 0 && dy == 0) {\n        return {{0,0},{1,1}};\n    }\n    \n    // Handle vertical lines\n    if (dx == 0) {\n        ll abs_dy = abs(dy);\n        ll sign_dy = (dy >= 0) ? 1 : -1;\n        if (abs_dy != 1) {\n            ll g = abs_dy;\n            dy /= g;\n        }\n        if (dy == 1) {\n            return {{0, C}, {1, C}};\n        } else {\n            return {{0, -C}, {1, -C}};\n        }\n    }\n    \n    // Handle horizontal lines\n    if (dy == 0) {\n        ll abs_dx = abs(dx);\n        if (abs_dx != 1) {\n            ll g = abs_dx;\n            dx /= g;\n        }\n        if (dx == 1) {\n            return {{C, 0}, {C, 1}};\n        } else {\n            return {{-C, 0}, {-C, 1}};\n        }\n    }\n    \n    // Normalize dx and dy\n    ll g = gcd(abs(dx), abs(dy));\n    dx /= g;\n    dy /= g;\n    \n    // Get signs\n    ll sign_dx = (dx >= 0) ? 1 : -1;\n    ll sign_dy = (dy >= 0) ? 1 : -1;\n    ll abs_dx = abs(dx);\n    ll abs_dy = abs(dy);\n    \n    // Solve abs_dx * x0 + abs_dy * y0 = 1\n    auto [x0, y0, gcd_val] = extended_gcd(abs_dx, abs_dy);\n    \n    // Adjust signs\n    x0 *= sign_dx;\n    y0 *= sign_dy;\n    \n    // Multiply by C\n    ll x = x0 * C;\n    ll y = y0 * C;\n    \n    // Adjust to minimize |x|\n    if (dy != 0) {\n        ll t = (-x) / dy;\n        ll best_t = t;\n        ll best_val = abs(x + t*dy);\n        for (int dt = -1; dt <= 1; dt++) {\n            ll t2 = t + dt;\n            ll val = abs(x + t2*dy);\n            if (val < best_val) {\n                best_val = val;\n                best_t = t2;\n            }\n        }\n        x += best_t * dy;\n        y -= best_t * dx;\n    }\n    \n    // Second point\n    ll x2 = x + dy;\n    ll y2 = y - dx;\n    \n    // Check if within range\n    const ll MAX_VAL = 1000000000;\n    if (abs(x) > MAX_VAL || abs(y) > MAX_VAL || abs(x2) > MAX_VAL || abs(y2) > MAX_VAL) {\n        // Try alternative point (should not happen with our adjustment)\n        return {{0,0},{1,1}};\n    }\n    \n    return {{x, y}, {x2, y2}};\n}\n\nint main() {\n    srand(time(0));\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Calculate desired distribution\n    vector<int> desired(11, 0);\n    for (int i = 1; i <= 10; i++) {\n        desired[i] = a[i];\n    }\n\n    // We'll use a greedy approach: repeatedly split the largest piece that doesn't match desired distribution\n    vector<Line> lines;\n    vector<vector<int>> pieces; // each piece is a list of strawberry indices\n    pieces.push_back(vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        pieces[0][i] = i;\n    }\n\n    // Current distribution\n    vector<int> current_dist(11, 0);\n\n    while (lines.size() < K && !pieces.empty()) {\n        // Find a piece to split\n        int best_idx = -1;\n        int best_size = 0;\n        for (int i = 0; i < pieces.size(); i++) {\n            int size = pieces[i].size();\n            if (size <= 1) continue;\n            if (size > 10) {\n                best_idx = i;\n                best_size = size;\n                break;\n            }\n            if (size >= 1 && size <= 10 && current_dist[size] < desired[size]) {\n                continue;\n            }\n            if (size > best_size) {\n                best_size = size;\n                best_idx = i;\n            }\n        }\n        if (best_idx == -1) break;\n\n        vector<int> S = pieces[best_idx];\n        pieces.erase(pieces.begin() + best_idx);\n\n        // Try to find a line that splits S into two non-empty groups\n        bool found = false;\n        Line best_line;\n        vector<int> best_S1, best_S2;\n\n        for (int attempt = 0; attempt < 100 && !found; attempt++) {\n            // Generate random direction\n            ll dx = rand() % 2001 - 1000;\n            ll dy = rand() % 2001 - 1000;\n            if (dx == 0 && dy == 0) continue;\n\n            // Compute projections for all strawberries\n            vector<ll> proj_all;\n            for (int i = 0; i < N; i++) {\n                ll proj = dx * strawberries[i].x + dy * strawberries[i].y;\n                proj_all.push_back(proj);\n            }\n            sort(proj_all.begin(), proj_all.end());\n\n            // Compute projections for S\n            vector<ll> proj_S;\n            for (int idx : S) {\n                ll proj = dx * strawberries[idx].x + dy * strawberries[idx].y;\n                proj_S.push_back(proj);\n            }\n            sort(proj_S.begin(), proj_S.end());\n\n            // Find a gap in proj_S that is not in proj_all\n            for (int i = 0; i < (int)proj_S.size() - 1; i++) {\n                if (proj_S[i] + 1 < proj_S[i + 1]) {\n                    ll C = proj_S[i] + 1;\n                    // Check that C is not in proj_all\n                    if (!binary_search(proj_all.begin(), proj_all.end(), C)) {\n                        vector<int> S1, S2;\n                        for (int idx : S) {\n                            ll proj = dx * strawberries[idx].x + dy * strawberries[idx].y;\n                            if (proj < C) {\n                                S1.push_back(idx);\n                            } else if (proj > C) {\n                                S2.push_back(idx);\n                            }\n                        }\n                        if (S1.empty() || S2.empty()) continue;\n\n                        // Generate line\n                        Line line = generate_line_from_params(dx, dy, C);\n                        \n                        // Check coordinates range\n                        const ll MAX_VAL = 1000000000;\n                        if (abs(line.p1.x) > MAX_VAL || abs(line.p1.y) > MAX_VAL || \n                            abs(line.p2.x) > MAX_VAL || abs(line.p2.y) > MAX_VAL) {\n                            continue;\n                        }\n                        \n                        // Check if line passes through any strawberry\n                        bool valid = true;\n                        for (int i = 0; i < N; i++) {\n                            if (passes_through(line, strawberries[i])) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        best_line = line;\n                        best_S1 = S1;\n                        best_S2 = S2;\n                        found = true;\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (found) {\n            lines.push_back(best_line);\n            pieces.push_back(best_S1);\n            pieces.push_back(best_S2);\n        } else {\n            pieces.push_back(S);\n        }\n    }\n\n    // Output the lines\n    cout << lines.size() << endl;\n    for (const Line& line : lines) {\n        cout << line.p1.x << \" \" << line.p1.y << \" \" << line.p2.x << \" \" << line.p2.y << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <unordered_set>\n#include <queue>\nusing namespace std;\n\nusing Point = pair<int, int>;\nusing Segment = pair<Point, Point>;\n\nstruct Candidate {\n    Point new_dot;\n    vector<Point> existing;\n    int type; // 0: axis-aligned, 1: 45-degree square\n    int weight;\n};\n\nSegment make_segment(Point a, Point b) {\n    if (a < b) {\n        return {a, b};\n    } else {\n        return {b, a};\n    }\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<Point> initial_dots;\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> row_set(N);\n    vector<set<int>> col_set(N);\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initial_dots.push_back({x, y});\n        grid[x][y] = true;\n        row_set[y].insert(x);\n        col_set[x].insert(y);\n    }\n\n    int c = (N-1)/2;\n    auto weight_func = [c](int x, int y) {\n        int dx = x - c;\n        int dy = y - c;\n        return dx*dx + dy*dy + 1;\n    };\n\n    set<Segment> drawn_segments;\n    vector<vector<int>> operations;\n\n    int max_operations = 10000;\n    int K_top = 1000;\n\n    for (int iter = 0; iter < max_operations; iter++) {\n        vector<Candidate> candidates;\n\n        for (int y = 0; y < N; y++) {\n            if (row_set[y].size() < 2) continue;\n            vector<int> xs(row_set[y].begin(), row_set[y].end());\n            sort(xs.begin(), xs.end());\n            for (int i = 0; i < xs.size(); i++) {\n                for (int j = i+1; j < xs.size(); j++) {\n                    int x1 = xs[i], x2 = xs[j];\n                    for (int y1 : col_set[x1]) {\n                        if (y1 == y) continue;\n                        if (!grid[x2][y1]) {\n                            Point new_dot = {x2, y1};\n                            vector<Point> existing = {{x1,y}, {x2,y}, {x1,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                    for (int y1 : col_set[x2]) {\n                        if (y1 == y) continue;\n                        if (!grid[x1][y1]) {\n                            Point new_dot = {x1, y1};\n                            vector<Point> existing = {{x1,y}, {x2,y}, {x2,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            if (col_set[x].size() < 2) continue;\n            vector<int> ys(col_set[x].begin(), col_set[x].end());\n            sort(ys.begin(), ys.end());\n            for (int i = 0; i < ys.size(); i++) {\n                for (int j = i+1; j < ys.size(); j++) {\n                    int y1 = ys[i], y2 = ys[j];\n                    for (int x1 : row_set[y1]) {\n                        if (x1 == x) continue;\n                        if (!grid[x1][y2]) {\n                            Point new_dot = {x1, y2};\n                            vector<Point> existing = {{x,y1}, {x,y2}, {x1,y1}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                    for (int x1 : row_set[y2]) {\n                        if (x1 == x) continue;\n                        if (!grid[x1][y1]) {\n                            Point new_dot = {x1, y1};\n                            vector<Point> existing = {{x,y1}, {x,y2}, {x1,y2}};\n                            int w = weight_func(new_dot.first, new_dot.second);\n                            candidates.push_back({new_dot, existing, 0, w});\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y]) continue;\n                int w = weight_func(x, y);\n                for (int type = 0; type < 4; type++) {\n                    if (type == 0) {\n                        int a_max = min({x, N-1-x, y/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x+a, y-a};\n                            Point C = {x, y-2*a};\n                            Point D = {x-a, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 1) {\n                        int a_max = min({y, N-1-y, (N-1-x)/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x, y+a};\n                            Point C = {x+2*a, y};\n                            Point D = {x, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 2) {\n                        int a_max = min({N-1-x, N-1-y, (N-1-y)/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x+a, y+a};\n                            Point C = {x, y+2*a};\n                            Point D = {x-a, y+a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    } else if (type == 3) {\n                        int a_max = min({y, N-1-y, x/2});\n                        for (int a = 1; a <= a_max; a++) {\n                            Point B = {x, y+a};\n                            Point C = {x-2*a, y};\n                            Point D = {x, y-a};\n                            if (B.first < 0 || B.first >= N || B.second < 0 || B.second >= N) continue;\n                            if (C.first < 0 || C.first >= N || C.second < 0 || C.second >= N) continue;\n                            if (D.first < 0 || D.first >= N || D.second < 0 || D.second >= N) continue;\n                            if (grid[B.first][B.second] && grid[C.first][C.second] && grid[D.first][D.second]) {\n                                candidates.push_back({{x,y}, {B, C, D}, 1, w});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (candidates.empty()) {\n            break;\n        }\n\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            return a.weight > b.weight;\n        });\n\n        if (candidates.size() > K_top) {\n            candidates.resize(K_top);\n        }\n\n        bool found_valid = false;\n        for (const Candidate& cand : candidates) {\n            Point new_dot = cand.new_dot;\n            vector<Point> existing = cand.existing;\n            int type = cand.type;\n\n            set<Point> corners = {new_dot, existing[0], existing[1], existing[2]};\n\n            bool condition2_ok = true;\n            vector<Point> perimeter_points;\n\n            if (type == 0) {\n                int x_min = new_dot.first;\n                int x_max = new_dot.first;\n                int y_min = new_dot.second;\n                int y_max = new_dot.second;\n                for (const Point& p : existing) {\n                    x_min = min(x_min, p.first);\n                    x_max = max(x_max, p.first);\n                    y_min = min(y_min, p.second);\n                    y_max = max(y_max, p.second);\n                }\n                for (int x = x_min; x <= x_max; x++) {\n                    perimeter_points.push_back({x, y_min});\n                    perimeter_points.push_back({x, y_max});\n                }\n                for (int y = y_min+1; y < y_max; y++) {\n                    perimeter_points.push_back({x_min, y});\n                    perimeter_points.push_back({x_max, y});\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = abs(dx);\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k <= steps; k++) {\n                        perimeter_points.push_back(current);\n                        if (k < steps) {\n                            current.first += sx;\n                            current.second += sy;\n                        }\n                    }\n                }\n            }\n\n            for (const Point& p : perimeter_points) {\n                if (corners.find(p) == corners.end() && grid[p.first][p.second]) {\n                    condition2_ok = false;\n                    break;\n                }\n            }\n            if (!condition2_ok) continue;\n\n            bool condition3_ok = true;\n            vector<Segment> new_segments;\n\n            if (type == 0) {\n                int x_min = new_dot.first;\n                int x_max = new_dot.first;\n                int y_min = new_dot.second;\n                int y_max = new_dot.second;\n                for (const Point& p : existing) {\n                    x_min = min(x_min, p.first);\n                    x_max = max(x_max, p.first);\n                    y_min = min(y_min, p.second);\n                    y_max = max(y_max, p.second);\n                }\n                for (int x = x_min; x < x_max; x++) {\n                    Segment seg = make_segment({x, y_min}, {x+1, y_min});\n                    new_segments.push_back(seg);\n                }\n                for (int x = x_min; x < x_max; x++) {\n                    Segment seg = make_segment({x, y_max}, {x+1, y_max});\n                    new_segments.push_back(seg);\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    Segment seg = make_segment({x_min, y}, {x_min, y+1});\n                    new_segments.push_back(seg);\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    Segment seg = make_segment({x_max, y}, {x_max, y+1});\n                    new_segments.push_back(seg);\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = abs(dx);\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k < steps; k++) {\n                        Point next = {current.first + sx, current.second + sy};\n                        Segment seg = make_segment(current, next);\n                        new_segments.push_back(seg);\n                        current = next;\n                    }\n                }\n            }\n\n            for (const Segment& seg : new_segments) {\n                if (drawn_segments.find(seg) != drawn_segments.end()) {\n                    condition3_ok = false;\n                    break;\n                }\n            }\n            if (!condition3_ok) continue;\n\n            for (const Segment& seg : new_segments) {\n                drawn_segments.insert(seg);\n            }\n            grid[new_dot.first][new_dot.second] = true;\n            row_set[new_dot.second].insert(new_dot.first);\n            col_set[new_dot.first].insert(new_dot.second);\n\n            vector<int> op;\n            op.push_back(new_dot.first);\n            op.push_back(new_dot.second);\n            for (const Point& p : existing) {\n                op.push_back(p.first);\n                op.push_back(p.second);\n            }\n            operations.push_back(op);\n\n            found_valid = true;\n            break;\n        }\n\n        if (!found_valid) {\n            break;\n        }\n    }\n\n    cout << operations.size() << endl;\n    for (const vector<int>& op : operations) {\n        for (int i = 0; i < op.size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <unordered_map>\nusing namespace std;\n\n// Simulate tilting the grid in the given direction\nvector<vector<int>> tilt_grid(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> new_grid(10, vector<int>(10, 0));\n    if (dir == 'F') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 9; i >= 0; i--) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 9;\n            for (int candy : candies) {\n                new_grid[idx--][j] = candy;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 0;\n            for (int candy : candies) {\n                new_grid[idx++][j] = candy;\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 0;\n            for (int candy : candies) {\n                new_grid[i][idx++] = candy;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 9; j >= 0; j--) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 9;\n            for (int candy : candies) {\n                new_grid[i][idx--] = candy;\n            }\n        }\n    }\n    return new_grid;\n}\n\n// Compute sum of squares of connected components\nint compute_components(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dx[4] = {1, -1, 0, 0};\n    int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0 && !visited[i][j]) {\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int flavor = grid[i][j];\n                int size = 0;\n\n                while (!q.empty()) {\n                    auto [x, y] = q.front();\n                    q.pop();\n                    size++;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x + dx[d];\n                        int ny = y + dy[d];\n                        if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && \n                            !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n// Advanced scoring with zone analysis and potential\nint advanced_score(const vector<vector<int>>& grid, int current_flavor, const vector<int>& flavor_counts) {\n    int base_score = compute_components(grid);\n    \n    // Zone-based analysis: assign each flavor to a corner/edge zone\n    // Flavor 1 -> Top-Left, Flavor 2 -> Top-Right, Flavor 3 -> Bottom\n    int zone_bonus = 0;\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0) {\n                int flavor = grid[i][j];\n                // Check if in preferred zone\n                bool in_zone = false;\n                if (flavor == 1 && i < 5 && j < 5) in_zone = true;\n                if (flavor == 2 && i < 5 && j >= 5) in_zone = true;\n                if (flavor == 3 && i >= 5) in_zone = true;\n                \n                if (in_zone) {\n                    zone_bonus += 10; // Bonus for being in the right zone\n                }\n                \n                // Bonus for being adjacent to same flavor\n                int dx[4] = {1, -1, 0, 0};\n                int dy[4] = {0, 0, 1, -1};\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 < 10 && nj >= 0 && nj < 10 && grid[ni][nj] == flavor) {\n                        zone_bonus += 5;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Compactness bonus: measure how concentrated each flavor is\n    int compactness_bonus = 0;\n    for (int flavor = 1; flavor <= 3; flavor++) {\n        if (flavor_counts[flavor] == 0) continue;\n        \n        vector<pair<int, int>> positions;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == flavor) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.size() >= 2) {\n            // Calculate center of mass\n            double sum_i = 0, sum_j = 0;\n            for (auto [i, j] : positions) {\n                sum_i += i;\n                sum_j += j;\n            }\n            double center_i = sum_i / positions.size();\n            double center_j = sum_j / positions.size();\n            \n            // Calculate variance\n            double variance = 0;\n            for (auto [i, j] : positions) {\n                variance += (i - center_i) * (i - center_i) + (j - center_j) * (j - center_j);\n            }\n            variance /= positions.size();\n            \n            // Higher bonus for lower variance (more compact)\n            compactness_bonus += (int)(100.0 / (1.0 + variance));\n        }\n    }\n    \n    // Future potential: estimate how many more candies of each flavor will come\n    int future_bonus = 0;\n    for (int flavor = 1; flavor <= 3; flavor++) {\n        if (flavor_counts[flavor] > 0) {\n            // If we have some of this flavor already, bonus for each one\n            // The more we have, the more valuable it is to connect them\n            int count = 0;\n            for (int i = 0; i < 10; i++) {\n                for (int j = 0; j < 10; j++) {\n                    if (grid[i][j] == flavor) count++;\n                }\n            }\n            if (count >= 2) {\n                future_bonus += count * flavor_counts[flavor] * 2;\n            }\n        }\n    }\n    \n    // Combine scores with weights\n    return base_score * 100 + zone_bonus + compactness_bonus + future_bonus;\n}\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n\n    // Count total occurrences of each flavor\n    vector<int> total_counts(4, 0);\n    for (int f : flavors) {\n        total_counts[f]++;\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n    vector<int> placed_counts(4, 0); // Track how many of each flavor have been placed\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell\n        int count = 0;\n        int i0 = -1, j0 = -1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == 0) {\n                    count++;\n                    if (count == p) {\n                        i0 = i;\n                        j0 = j;\n                        break;\n                    }\n                }\n            }\n            if (i0 != -1) break;\n        }\n\n        // Place the candy\n        grid[i0][j0] = flavors[t];\n        placed_counts[flavors[t]]++;\n\n        // If it's the last candy, we don't need to tilt\n        if (t == 99) {\n            break;\n        }\n\n        // Calculate remaining counts for future potential\n        vector<int> remaining_counts(4, 0);\n        for (int flavor = 1; flavor <= 3; flavor++) {\n            remaining_counts[flavor] = total_counts[flavor] - placed_counts[flavor];\n        }\n\n        // Try all directions and choose the best\n        char best_dir = 'F';\n        int best_score = -1;\n        string dirs = \"FBLR\";\n        \n        for (char d : dirs) {\n            vector<vector<int>> temp_grid = grid;\n            vector<vector<int>> tilted = tilt_grid(temp_grid, d);\n            int score = advanced_score(tilted, flavors[t], remaining_counts);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        cout << best_dir << endl;\n\n        // Apply the best tilt to our grid state\n        grid = tilt_grid(grid, best_dir);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\nusing namespace std;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // More refined N selection based on M and epsilon\n    int N;\n    if (M <= 15 && epsilon <= 0.05) {\n        N = 20;\n    } else if (M <= 25 && epsilon <= 0.1) {\n        N = 30;\n    } else if (M <= 40 && epsilon <= 0.15) {\n        N = 50;\n    } else if (M <= 60 && epsilon <= 0.25) {\n        N = 70;\n    } else {\n        N = 100;\n    }\n\n    const int T = N * (N - 1) / 2;\n    int g = T / (M - 1);\n    if (g < 1) g = 1;\n\n    // Precompute prototype degree sequences with optimized edge assignment\n    vector<vector<int>> proto_degrees(M, vector<int>(N, 0));\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        \n        // More balanced edge assignment to maximize degree sequence distinctiveness\n        vector<int> deg(N, 0);\n        if (edge_count > 0) {\n            // Distribute edges to create distinct degree profiles\n            int remaining = edge_count;\n            int current_vertex = 0;\n            while (remaining > 0) {\n                for (int j = current_vertex + 1; j < N && remaining > 0; j++) {\n                    if (deg[current_vertex] < N - 1) {\n                        deg[current_vertex]++;\n                        deg[j]++;\n                        remaining--;\n                    }\n                }\n                current_vertex = (current_vertex + 1) % N;\n            }\n        }\n        sort(deg.begin(), deg.end());\n        proto_degrees[k] = deg;\n    }\n\n    // Precompute expected degree sequences after noise\n    vector<vector<double>> proto_expected(M, vector<double>(N, 0));\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < N; i++) {\n            proto_expected[k][i] = proto_degrees[k][i] * (1 - 2 * epsilon) + (N - 1) * epsilon;\n        }\n    }\n\n    // Output graphs\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        string s = \"\";\n        int count = 0;\n        // Use the same edge assignment as in degree sequence calculation\n        vector<int> deg(N, 0);\n        if (edge_count > 0) {\n            int remaining = edge_count;\n            int current_vertex = 0;\n            while (remaining > 0) {\n                for (int j = current_vertex + 1; j < N && remaining > 0; j++) {\n                    if (deg[current_vertex] < N - 1) {\n                        deg[current_vertex]++;\n                        deg[j]++;\n                        remaining--;\n                    }\n                }\n                current_vertex = (current_vertex + 1) % N;\n            }\n        }\n        // Convert degree assignment to edge string\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                // Check if this edge was assigned in our degree calculation\n                bool edge_exists = false;\n                if (deg[i] > 0 && deg[j] > 0) {\n                    // We need to reconstruct the edge existence from degrees\n                    // This is a simplification - in practice, we should store the edge matrix\n                    // For now, we'll use a heuristic: if both degrees are positive, assume edge exists\n                    // But this might not be accurate\n                    // Instead, let's generate edges in the same order as degree calculation\n                    // We'll recreate the edge assignment\n                    edge_exists = (i < j && deg[i] > 0 && deg[j] > 0);\n                }\n                s += edge_exists ? '1' : '0';\n                count++;\n            }\n        }\n        // Actually, let's generate edges properly based on our degree assignment\n        // We need to reconstruct the edge string from the degree assignment\n        // Since we know the degree sequence, we can try to reconstruct a graph with that degree sequence\n        // But that's complex. Instead, let's use a simpler method: assign edges in canonical order up to edge_count\n        s = \"\";\n        int assigned = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (assigned < edge_count) {\n                    s += '1';\n                    assigned++;\n                } else {\n                    s += '0';\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    // Process queries\n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        vector<int> obs_deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (s[idx] == '1') {\n                    obs_deg[i]++;\n                    obs_deg[j]++;\n                }\n                idx++;\n            }\n        }\n        sort(obs_deg.begin(), obs_deg.end());\n\n        // Use degree sequence method with noise-adjusted expected values\n        double best_dist = 1e18;\n        int best_k = 0;\n        for (int k = 0; k < M; k++) {\n            double dist = 0.0;\n            for (int i = 0; i < N; i++) {\n                double diff = obs_deg[i] - proto_expected[k][i];\n                dist += diff * diff;\n            }\n            // Add small regularization to break ties\n            dist += 1e-6 * k;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_k = k;\n            }\n        }\n        cout << best_k << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long LL;\ntypedef long double LD;\n\nstruct Edge {\n    int to;\n    LL w;\n    int id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<tuple<int, int, LL>> edges;\n    vector<vector<Edge>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        LL w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edges.push_back({u, v, w});\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<LD> betweenness(M, 0.0);\n\n    for (int s = 0; s < N; s++) {\n        vector<LL> dist(N, LLONG_MAX);\n        vector<LD> sigma(N, 0.0);\n        vector<vector<pair<int, int>>> pred(N);\n\n        priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<pair<LL, int>>> pq;\n        dist[s] = 0;\n        sigma[s] = 1;\n        pq.push({0, s});\n\n        while (!pq.empty()) {\n            LL d = pq.top().first;\n            int u = pq.top().second;\n            pq.pop();\n            if (d != dist[u]) continue;\n            for (const Edge &e : adj[u]) {\n                int v = e.to;\n                LL w = e.w;\n                LL nd = dist[u] + w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    sigma[v] = sigma[u];\n                    pred[v].clear();\n                    pred[v].push_back({u, e.id});\n                    pq.push({nd, v});\n                } else if (nd == dist[v]) {\n                    sigma[v] += sigma[u];\n                    pred[v].push_back({u, e.id});\n                }\n            }\n        }\n\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            if (dist[a] != dist[b])\n                return dist[a] > dist[b];\n            return a > b;\n        });\n\n        vector<LD> delta(N, 0.0);\n        for (int i = 0; i < N; i++) {\n            int v = order[i];\n            if (dist[v] == LLONG_MAX) continue;\n            if (v == s) continue;\n            for (auto &p : pred[v]) {\n                int u = p.first;\n                int eid = p.second;\n                if (sigma[v] == 0) continue;\n                LD contrib = (sigma[u] / sigma[v]) * (1.0 + delta[v]);\n                delta[u] += contrib;\n                betweenness[eid] += contrib;\n            }\n        }\n    }\n\n    vector<LD> cost(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, w] = edges[i];\n        cost[i] = betweenness[i] * (LD)w;\n    }\n\n    vector<pair<LD, int>> sorted_edges;\n    for (int i = 0; i < M; i++) {\n        sorted_edges.push_back({cost[i], i});\n    }\n    sort(sorted_edges.rbegin(), sorted_edges.rend());\n\n    vector<LD> total_cost(D, 0.0);\n    vector<int> count(D, 0);\n    vector<int> ans(M, -1);\n\n    for (auto &p : sorted_edges) {\n        LD c = p.first;\n        int eid = p.second;\n        int best_day = -1;\n        LD min_cost = 1e30;\n        for (int d = 0; d < D; d++) {\n            if (count[d] < K) {\n                if (total_cost[d] < min_cost) {\n                    min_cost = total_cost[d];\n                    best_day = d;\n                }\n            }\n        }\n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if (count[d] < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n            if (best_day == -1) {\n                best_day = 0;\n            }\n        }\n        ans[eid] = best_day;\n        total_cost[best_day] += c;\n        count[best_day]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        if (i) cout << \" \";\n        cout << ans[i] + 1;\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> is_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\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                bool in1 = (f1[z][x] == '1' && r1[z][y] == '1');\n                bool in2 = (f2[z][x] == '1' && r2[z][y] == '1');\n                if (in1 && in2) {\n                    is_common[x][y][z] = true;\n                } else if (in1) {\n                    is_only1[x][y][z] = true;\n                } else if (in2) {\n                    is_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<int>>> block1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> block2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    int next_block_id = 1;\n    vector<int> dx = {1, -1, 0, 0, 0, 0};\n    vector<int> dy = {0, 0, 1, -1, 0, 0};\n    vector<int> dz = {0, 0, 0, 0, 1, -1};\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 (is_common[x][y][z] && !visited[x][y][z]) {\n                    queue<tuple<int, int, int>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    block1[x][y][z] = next_block_id;\n                    block2[x][y][z] = next_block_id;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D) {\n                                if (is_common[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                    visited[nx][ny][nz] = true;\n                                    block1[nx][ny][nz] = next_block_id;\n                                    block2[nx][ny][nz] = next_block_id;\n                                    q.push({nx, ny, nz});\n                                }\n                            }\n                        }\n                    }\n                    next_block_id++;\n                }\n            }\n        }\n    }\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 (is_only1[x][y][z]) {\n                    block1[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n                if (is_only2[x][y][z]) {\n                    block2[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n            }\n        }\n    }\n\n    cout << next_block_id - 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 << block1[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 << block2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstring>\n#include <unordered_map>\n\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nconst double INF = 1e18;\nconst int MAXN = 100;\nconst int MAXM = 300;\nconst int MAXK = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nvector<pii> edges;\nint w[MAXM];\ndouble resident_x[MAXK], resident_y[MAXK];\n\nvector<pair<int, int>> adj[MAXN];\ndouble dist_2d[MAXN][MAXN];\nint parent_2d[MAXN][MAXN];\n\nint best_node[MAXK];\ndouble min_dist[MAXK];\n\nvector<int> T_list;\ndouble d_T[MAXK];\nbool inT[MAXN];\n\nvector<pii> MST_edges;\n\nmap<pii, int> edge_index_map;\n\ndouble euclid(double x1, double y1, double x2, double y2) {\n    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));\n}\n\nvoid dijkstra(int src) {\n    for (int i = 0; i < N; i++) {\n        dist_2d[src][i] = INF;\n        parent_2d[src][i] = -1;\n    }\n    dist_2d[src][src] = 0;\n    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n    pq.push({0, src});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n        if (d != dist_2d[src][u]) continue;\n        for (auto &edge : adj[u]) {\n            int v = edge.first;\n            int weight = edge.second;\n            double new_d = d + weight;\n            if (new_d < dist_2d[src][v]) {\n                dist_2d[src][v] = new_d;\n                parent_2d[src][v] = u;\n                pq.push({new_d, v});\n            }\n        }\n    }\n}\n\nvector<int> get_path(int src, int dest) {\n    vector<int> path;\n    if (dist_2d[src][dest] >= INF) return path;\n    int cur = dest;\n    while (cur != src) {\n        path.push_back(cur);\n        cur = parent_2d[src][cur];\n    }\n    path.push_back(src);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstruct Edge {\n    int u, v;\n    double weight;\n    bool operator<(const Edge& other) const {\n        return weight < other.weight;\n    }\n};\n\nvector<int> parent_kruskal;\n\nint find_set(int v) {\n    if (v == parent_kruskal[v]) return v;\n    return parent_kruskal[v] = find_set(parent_kruskal[v]);\n}\n\nbool union_sets(int a, int b) {\n    a = find_set(a);\n    b = find_set(b);\n    if (a == b) return false;\n    parent_kruskal[b] = a;\n    return true;\n}\n\nvoid build_MST_on_T() {\n    int t_size = T_list.size();\n    map<int, int> comp;\n    for (int i = 0; i < t_size; i++) {\n        comp[T_list[i]] = i;\n    }\n\n    vector<Edge> edges_complete;\n    for (int i = 0; i < t_size; i++) {\n        for (int j = i+1; j < t_size; j++) {\n            int u = T_list[i];\n            int v = T_list[j];\n            double d = dist_2d[u][v];\n            edges_complete.push_back({u, v, d});\n        }\n    }\n\n    sort(edges_complete.begin(), edges_complete.end());\n\n    parent_kruskal.resize(t_size);\n    for (int i = 0; i < t_size; i++) parent_kruskal[i] = i;\n\n    MST_edges.clear();\n    for (const Edge& e : edges_complete) {\n        int u_comp = comp[e.u];\n        int v_comp = comp[e.v];\n        if (union_sets(u_comp, v_comp)) {\n            MST_edges.push_back({e.u, e.v});\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> K;\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    for (int j = 0; j < M; j++) {\n        int u, v, weight;\n        cin >> u >> v >> weight;\n        u--; v--;\n        edges.push_back({u, v});\n        w[j] = weight;\n        adj[u].push_back({v, weight});\n        adj[v].push_back({u, weight});\n        int a = min(u, v);\n        int b = max(u, v);\n        edge_index_map[{a, b}] = j;\n    }\n    for (int k = 0; k < K; k++) {\n        cin >> resident_x[k] >> resident_y[k];\n    }\n\n    // Precompute all-pairs shortest paths\n    for (int i = 0; i < N; i++) {\n        dijkstra(i);\n    }\n\n    // Find closest node for each resident\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best = -1;\n        for (int i = 0; i < N; i++) {\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d < min_d) {\n                min_d = d;\n                best = i;\n            }\n        }\n        best_node[k] = best;\n        min_dist[k] = min_d;\n    }\n\n    // Improved node selection: prioritize nodes that cover many distant residents\n    memset(inT, 0, sizeof(inT));\n    T_list.clear();\n    T_list.push_back(0);\n    inT[0] = true;\n\n    for (int k = 0; k < K; k++) {\n        d_T[k] = euclid(resident_x[k], resident_y[k], x[0], y[0]);\n    }\n\n    set<int> uncovered;\n    for (int k = 0; k < K; k++) {\n        uncovered.insert(k);\n    }\n\n    while (!uncovered.empty()) {\n        // Find the resident with maximum distance to current network\n        int k0 = -1;\n        double max_d = -1;\n        for (int k : uncovered) {\n            if (d_T[k] > max_d) {\n                max_d = d_T[k];\n                k0 = k;\n            }\n        }\n\n        if (d_T[k0] <= 5000) {\n            uncovered.erase(k0);\n            continue;\n        }\n\n        // Select the node that covers the most uncovered residents within 5000\n        // and has the best cost-benefit ratio\n        int best_i = -1;\n        double best_benefit = -1e18;\n        \n        for (int i = 0; i < N; i++) {\n            if (inT[i]) continue;\n            \n            int count_covered = 0;\n            double total_reduction = 0;\n            for (int k : uncovered) {\n                double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n                if (d <= 5000) {\n                    count_covered++;\n                    total_reduction += (d_T[k] * d_T[k] - d * d);\n                }\n            }\n            \n            if (count_covered == 0) continue;\n            \n            // Estimate edge cost to connect this node\n            double min_edge_cost = INF;\n            for (int existing : T_list) {\n                min_edge_cost = min(min_edge_cost, dist_2d[i][existing]);\n            }\n            \n            // Benefit is reduction in square cost minus edge cost\n            double benefit = total_reduction - min_edge_cost;\n            \n            if (benefit > best_benefit) {\n                best_benefit = benefit;\n                best_i = i;\n            }\n        }\n        \n        // Fallback if no good node found\n        if (best_i == -1) {\n            best_i = best_node[k0];\n        }\n        \n        if (!inT[best_i]) {\n            T_list.push_back(best_i);\n            inT[best_i] = true;\n            for (int k = 0; k < K; k++) {\n                double d = euclid(resident_x[k], resident_y[k], x[best_i], y[best_i]);\n                if (d < d_T[k]) {\n                    d_T[k] = d;\n                }\n            }\n        }\n        \n        // Remove covered residents\n        vector<int> to_remove;\n        for (int k : uncovered) {\n            if (d_T[k] <= 5000) {\n                to_remove.push_back(k);\n            }\n        }\n        for (int k : to_remove) {\n            uncovered.erase(k);\n        }\n    }\n\n    if (T_list.size() > 1) {\n        build_MST_on_T();\n    } else {\n        MST_edges.clear();\n    }\n\n    set<int> activated_edges;\n\n    for (auto &e : MST_edges) {\n        int u = e.first;\n        int v = e.second;\n        vector<int> path = get_path(u, v);\n        for (int idx = 0; idx < (int)path.size()-1; idx++) {\n            int a = path[idx];\n            int b = path[idx+1];\n            int aa = min(a, b);\n            int bb = max(a, b);\n            auto key = make_pair(aa, bb);\n            if (edge_index_map.find(key) != edge_index_map.end()) {\n                int j = edge_index_map[key];\n                activated_edges.insert(j);\n            }\n        }\n    }\n\n    vector<bool> inV_prime(N, false);\n    vector<vector<int>> adj_steiner(N);\n    for (int j : activated_edges) {\n        int u = edges[j].first;\n        int v = edges[j].second;\n        adj_steiner[u].push_back(v);\n        adj_steiner[v].push_back(u);\n    }\n    queue<int> q;\n    q.push(0);\n    inV_prime[0] = true;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj_steiner[u]) {\n            if (!inV_prime[v]) {\n                inV_prime[v] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    vector<int> V_prime;\n    for (int i = 0; i < N; i++) {\n        if (inV_prime[i]) {\n            V_prime.push_back(i);\n        }\n    }\n\n    // Precompute distances from residents to nodes in V_prime\n    vector<vector<double>> dist_res_node(K, vector<double>(N, 0.0));\n    for (int k = 0; k < K; k++) {\n        for (int i : V_prime) {\n            dist_res_node[k][i] = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n        }\n    }\n\n    // Initial assignment: assign each resident to the closest node in V_prime\n    vector<int> assign(K, -1);\n    vector<vector<int>> residents(N);\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best_i = -1;\n        for (int i : V_prime) {\n            double d = dist_res_node[k][i];\n            if (d < min_d) {\n                min_d = d;\n                best_i = i;\n            }\n        }\n        assign[k] = best_i;\n        residents[best_i].push_back(k);\n    }\n\n    // Statistics for efficient reassignment\n    vector<double> max1(N, 0.0);\n    vector<int> count_max1(N, 0);\n    vector<double> max2(N, 0.0);\n\n    for (int i : V_prime) {\n        if (residents[i].empty()) {\n            max1[i] = 0;\n            count_max1[i] = 0;\n            max2[i] = 0;\n            continue;\n        }\n        double m1 = 0, m2 = 0;\n        int cnt = 0;\n        for (int k : residents[i]) {\n            double d = dist_res_node[k][i];\n            if (d > m1) {\n                m2 = m1;\n                m1 = d;\n                cnt = 1;\n            } else if (d == m1) {\n                cnt++;\n            } else if (d > m2) {\n                m2 = d;\n            }\n        }\n        max1[i] = m1;\n        count_max1[i] = cnt;\n        max2[i] = m2;\n    }\n\n    // Reassignment: try to move residents to reduce the sum of squares\n    int iter = 0;\n    bool improved = true;\n    while (improved && iter < 20) {\n        improved = false;\n        double best_reduction = 0;\n        int best_k = -1, best_j = -1, best_i = -1;\n\n        for (int k = 0; k < K; k++) {\n            int i = assign[k];\n            for (int j : V_prime) {\n                if (j == i) continue;\n                double d_i = dist_res_node[k][i];\n                double d_j = dist_res_node[k][j];\n                \n                // Calculate new max for i if we remove k\n                double new_max_i;\n                if (d_i == max1[i]) {\n                    if (count_max1[i] > 1) {\n                        new_max_i = max1[i];\n                    } else {\n                        new_max_i = max2[i];\n                    }\n                } else {\n                    new_max_i = max1[i];\n                }\n                \n                // Calculate new max for j if we add k\n                double new_max_j = max(max1[j], d_j);\n                \n                double reduction = max1[i]*max1[i] + max1[j]*max1[j] - (new_max_i*new_max_i + new_max_j*new_max_j);\n                \n                if (reduction > best_reduction) {\n                    best_reduction = reduction;\n                    best_k = k;\n                    best_j = j;\n                    best_i = i;\n                }\n            }\n        }\n\n        if (best_reduction > 1e-9) {\n            // Move resident best_k from best_i to best_j\n            residents[best_i].erase(remove(residents[best_i].begin(), residents[best_i].end(), best_k), residents[best_i].end());\n            residents[best_j].push_back(best_k);\n            assign[best_k] = best_j;\n\n            // Recompute statistics for both nodes\n            for (int node : {best_i, best_j}) {\n                if (residents[node].empty()) {\n                    max1[node] = 0;\n                    count_max1[node] = 0;\n                    max2[node] = 0;\n                } else {\n                    double m1 = 0, m2 = 0;\n                    int cnt = 0;\n                    for (int k : residents[node]) {\n                        double d = dist_res_node[k][node];\n                        if (d > m1) {\n                            m2 = m1;\n                            m1 = d;\n                            cnt = 1;\n                        } else if (d == m1) {\n                            cnt++;\n                        } else if (d > m2) {\n                            m2 = d;\n                        }\n                    }\n                    max1[node] = m1;\n                    count_max1[node] = cnt;\n                    max2[node] = m2;\n                }\n            }\n\n            improved = true;\n            iter++;\n        }\n    }\n\n    // Set output strengths\n    vector<int> P(N, 0);\n    for (int i : V_prime) {\n        if (max1[i] > 0) {\n            P[i] = ceil(max1[i]);\n            if (P[i] > 5000) P[i] = 5000;\n        } else {\n            P[i] = 0;\n        }\n    }\n\n    // Output P_i\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << endl;\n\n    // Output B_j\n    vector<int> B(M, 0);\n    for (int j = 0; j < M; j++) {\n        if (activated_edges.find(j) != activated_edges.end()) {\n            B[j] = 1;\n        }\n        if (j > 0) cout << \" \";\n        cout << B[j];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N = 30;\n    vector<vector<int>> grid(N);\n    for (int i = 0; i < N; i++) {\n        grid[i].resize(i+1);\n        for (int j = 0; j <= i; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n    priority_queue<tuple<int, int, int>> pq;\n\n    auto check_and_push = [&](int x, int y) {\n        if (x < 0 || x >= N-1 || y < 0 || y > x) return;\n        if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n            pq.push({grid[x][y], x, y});\n        }\n    };\n\n    // Initial push of all violating nodes\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            check_and_push(x, y);\n        }\n    }\n\n    while (!pq.empty() && swaps.size() < 10000) {\n        auto [val, x, y] = pq.top();\n        pq.pop();\n        \n        // Check if this node still violates the condition\n        if (grid[x][y] <= grid[x+1][y] && grid[x][y] <= grid[x+1][y+1]) {\n            continue;\n        }\n\n        // Find the smaller child\n        int min_x = x+1;\n        int min_y = (grid[x+1][y] < grid[x+1][y+1]) ? y : y+1;\n        \n        // Swap\n        swap(grid[x][y], grid[min_x][min_y]);\n        swaps.push_back({x, y, min_x, min_y});\n\n        // Push affected nodes\n        check_and_push(x, y);          // The node that moved up\n        check_and_push(min_x, min_y);   // The node that moved down\n        check_and_push(x-1, y-1);       // Left parent of the moved up node\n        check_and_push(x-1, y);         // Right parent of the moved up node\n    }\n\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <utility>\nusing namespace std;\n\nconst int MAX_D = 9;\nconst int entrance_i = 0;\nconst int entrance_j = 4;\nint dx[4] = {1, -1, 0, 0};\nint dy[4] = {0, 0, 1, -1};\n\nint main() {\n    int D, N;\n    cin >> D >> N;\n    bool obstacle[MAX_D][MAX_D] = {false};\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N;\n    bool occupied[MAX_D][MAX_D] = {false};\n    int container_number[MAX_D][MAX_D];\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            container_number[i][j] = -1;\n        }\n    }\n\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n\n        vector<vector<int>> dist(MAX_D, vector<int>(MAX_D, -1));\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                        dist[ni][nj] = dist[i][j] + 1;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> available;\n        for (int i = 0; i < MAX_D; i++) {\n            for (int j = 0; j < MAX_D; j++) {\n                if (dist[i][j] != -1 && !(i == entrance_i && j == entrance_j)) {\n                    available.push_back({i, j});\n                }\n            }\n        }\n\n        sort(available.begin(), available.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            if (dist[a.first][a.second] != dist[b.first][b.second]) {\n                return dist[a.first][a.second] < dist[b.first][b.second];\n            }\n            if (a.first != b.first) {\n                return a.first < b.first;\n            }\n            return a.second < b.second;\n        });\n\n        if (available.empty()) {\n            continue;\n        }\n\n        int k = (t * available.size()) / M;\n        auto chosen = available[k];\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n\n        occupied[chosen.first][chosen.second] = true;\n        container_number[chosen.first][chosen.second] = t;\n    }\n\n    vector<vector<bool>> empty(MAX_D, vector<bool>(MAX_D, false));\n    empty[entrance_i][entrance_j] = true;\n\n    vector<pair<int, int>> containers;\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            if (occupied[i][j]) {\n                containers.push_back({i, j});\n            }\n        }\n    }\n\n    vector<pair<int, int>> removal_order;\n\n    while (!containers.empty()) {\n        vector<vector<bool>> visited(MAX_D, vector<bool>(MAX_D, false));\n        queue<pair<int, int>> q;\n        q.push({entrance_i, entrance_j});\n        visited[entrance_i][entrance_j] = true;\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && empty[ni][nj] && !visited[ni][nj]) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<int> removable_indices;\n        for (int idx = 0; idx < containers.size(); idx++) {\n            auto [i, j] = containers[idx];\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (visited[ni][nj]) {\n                        removable_indices.push_back(idx);\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (removable_indices.empty()) {\n            break;\n        }\n\n        int min_num = 1000000;\n        int best_idx = -1;\n        for (int idx : removable_indices) {\n            auto [i, j] = containers[idx];\n            int num = container_number[i][j];\n            if (num < min_num) {\n                min_num = num;\n                best_idx = idx;\n            }\n        }\n\n        auto coord = containers[best_idx];\n        removal_order.push_back(coord);\n        empty[coord.first][coord.second] = true;\n        swap(containers[best_idx], containers.back());\n        containers.pop_back();\n    }\n\n    for (auto [i, j] : removal_order) {\n        cout << i << \" \" << j << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c;\n            cin >> c;\n            cout << c;\n            if (j < n-1) cout << \" \";\n        }\n        cout << endl;\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n#include <cmath>\n#include <iomanip>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Phase 1: Robust weight estimation using insertion sort with refinement\n    vector<int> order;\n    int queries_used = 0;\n    \n    // Build initial order with binary search insertion\n    for (int i = 0; i < N; i++) {\n        int low = 0, high = order.size();\n        while (low < high && queries_used < Q) {\n            int mid = (low + high) / 2;\n            cout << \"1 1 \" << i << \" \" << order[mid] << endl;\n            cout.flush();\n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \">\") {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        order.insert(order.begin() + low, i);\n    }\n    \n    // Refine the order using remaining queries\n    // Use a more sophisticated approach: compare items that are likely to be out of order\n    while (queries_used < Q) {\n        bool found = false;\n        // Try to find two adjacent items that might be in wrong order\n        for (int i = 0; i < (int)order.size() - 1 && queries_used < Q; i++) {\n            // Compare order[i] and order[i+1]\n            cout << \"1 1 \" << order[i] << \" \" << order[i+1] << endl;\n            cout.flush();\n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \"<\") {\n                // order[i] is lighter than order[i+1], so swap\n                swap(order[i], order[i+1]);\n                found = true;\n            }\n        }\n        \n        // If no swaps, try random pairs\n        if (!found && queries_used < Q) {\n            // Compare random items that are not adjacent\n            int i = rand() % N;\n            int j = rand() % N;\n            if (i != j && queries_used < Q) {\n                cout << \"1 1 \" << order[i] << \" \" << order[j] << endl;\n                cout.flush();\n                string res;\n                cin >> res;\n                queries_used++;\n                \n                // Update order based on result\n                if (res == \">\" && i < j) {\n                    // order[i] is heavier, should come before order[j]\n                    // But we need to find their positions\n                    auto it_i = find(order.begin(), order.end(), order[i]);\n                    auto it_j = find(order.begin(), order.end(), order[j]);\n                    if (it_i > it_j) {\n                        swap(*it_i, *it_j);\n                    }\n                } else if (res == \"<\" && i > j) {\n                    auto it_i = find(order.begin(), order.end(), order[i]);\n                    auto it_j = find(order.begin(), order.end(), order[j]);\n                    if (it_i < it_j) {\n                        swap(*it_i, *it_j);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Try multiple assignment strategies and pick the best\n    vector<int> best_assignment;\n    double best_variance = 1e18;\n    \n    // Strategy 1: Simple greedy by order\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            int min_set = 0;\n            for (int d = 1; d < D; d++) {\n                if (set_totals[d] < set_totals[min_set]) {\n                    min_set = d;\n                }\n            }\n            assignment[item] = min_set;\n            set_totals[min_set] += (N - i); // Weight estimate\n        }\n        \n        // Calculate variance\n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 2: Round-robin assignment\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            assignment[item] = i % D;\n            set_totals[i % D] += (N - i);\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 3: Alternate assignment (heaviest to smallest set, then lightest to largest set)\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            if (i % 2 == 0) {\n                // Heaviest items: assign to smallest set\n                int min_set = 0;\n                for (int d = 1; d < D; d++) {\n                    if (set_totals[d] < set_totals[min_set]) {\n                        min_set = d;\n                    }\n                }\n                assignment[item] = min_set;\n                set_totals[min_set] += (N - i);\n            } else {\n                // Lightest items: assign to largest set\n                int max_set = 0;\n                for (int d = 1; d < D; d++) {\n                    if (set_totals[d] > set_totals[max_set]) {\n                        max_set = d;\n                    }\n                }\n                assignment[item] = max_set;\n                set_totals[max_set] += (N - i);\n            }\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 4: Use the sorted order but with weighted assignment\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        // Use exponential weights: heaviest items get much higher weight\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            double weight = pow(2.0, (N - i) / (N / 4.0)); // Exponential weighting\n            int min_set = 0;\n            for (int d = 1; d < D; d++) {\n                if (set_totals[d] < set_totals[min_set]) {\n                    min_set = d;\n                }\n            }\n            assignment[item] = min_set;\n            set_totals[min_set] += weight;\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Output the best assignment found\n    for (int i = 0; i < N; i++) {\n        cout << best_assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cout.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    int per_stack = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < per_stack; ++j) {\n            int x;\n            cin >> x;\n            stacks[i].push_back(x);   // bottom to top\n        }\n    }\n\n    // arrays to store position of each box\n    vector<int> stack_of(n + 1, -1);\n    vector<int> idx_in_stack(n + 1, -1);\n\n    // function to recompute positions\n    auto recompute = [&]() {\n        fill(stack_of.begin(), stack_of.end(), -1);\n        fill(idx_in_stack.begin(), idx_in_stack.end(), -1);\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                int box = stacks[i][j];\n                stack_of[box] = i;\n                idx_in_stack[box] = j;\n            }\n        }\n    };\n\n    vector<pair<int, int>> ops;\n    int op_count = 0;\n\n    for (int v = 1; v <= n; ++v) {\n        recompute();\n        int s = stack_of[v];\n        int i = idx_in_stack[v];\n\n        // if v is already on top, carry out\n        if (i == (int)stacks[s].size() - 1) {\n            ops.emplace_back(v, 0);\n            ++op_count;\n            stacks[s].pop_back();\n            continue;\n        }\n\n        // otherwise, move boxes above v one by one\n        while (true) {\n            recompute();\n            s = stack_of[v];\n            i = idx_in_stack[v];\n            if (i == (int)stacks[s].size() - 1) break;   // v is now top\n\n            int w = stacks[s].back();   // current top box\n\n            // choose destination stack t (0\u2011based)\n            int t = -1;\n            vector<int> empty, good, other;\n            for (int idx = 0; idx < m; ++idx) {\n                if (idx == s) continue;\n                if (stacks[idx].empty()) {\n                    empty.push_back(idx);\n                } else if (stacks[idx].back() > w) {\n                    good.push_back(idx);\n                } else {\n                    other.push_back(idx);\n                }\n            }\n\n            if (!empty.empty()) {\n                t = empty[0];   // prefer empty stack\n            } else if (!good.empty()) {\n                // choose stack with smallest top > w\n                int best_top = 1e9;\n                for (int idx : good) {\n                    int top = stacks[idx].back();\n                    if (top < best_top) {\n                        best_top = top;\n                        t = idx;\n                    }\n                }\n            } else if (!other.empty()) {\n                // fallback: choose stack with largest top (< w)\n                int best_top = -1;\n                for (int idx : other) {\n                    int top = stacks[idx].back();\n                    if (top > best_top) {\n                        best_top = top;\n                        t = idx;\n                    }\n                }\n            } else {\n                // should not happen (m>=2), but fallback\n                t = (s + 1) % m;\n            }\n\n            // output move operation (convert to 1\u2011based stack index)\n            ops.emplace_back(w, t + 1);\n            ++op_count;\n\n            // perform the move\n            stacks[s].pop_back();\n            stacks[t].push_back(w);\n        }\n\n        // v is now on top, carry out\n        ops.emplace_back(v, 0);\n        ++op_count;\n        stacks[s].pop_back();   // remove v\n    }\n\n    // output all operations\n    for (auto &p : ops) {\n        cout << p.first << \" \" << p.second << \"\\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;\nvector<vector<bool>> visited;\nstring moves = \"\";\n\n// Direction vectors: right, down, left, up\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'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    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check walls based on direction\n    if (dir == 0) { // right\n        return v[i][j] == '0';\n    } else if (dir == 1) { // down\n        return h[i][j] == '0';\n    } else if (dir == 2) { // left\n        return j > 0 && v[i][j-1] == '0';\n    } else { // up\n        return i > 0 && h[i-1][j] == '0';\n    }\n}\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    \n    // Collect all possible moves to unvisited squares\n    vector<tuple<int, int, int>> candidates; // (d_value, new_i, new_j)\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n            !visited[ni][nj] && can_move(i, j, dir)) {\n            candidates.emplace_back(d[ni][nj], ni, nj);\n        }\n    }\n    \n    // Sort by susceptibility in descending order - visit high-susceptibility squares first\n    sort(candidates.begin(), candidates.end(), [](const tuple<int,int,int>& a, const tuple<int,int,int>& b) {\n        return get<0>(a) > get<0>(b);\n    });\n    \n    for (auto& candidate : candidates) {\n        int new_d = get<0>(candidate);\n        int ni = get<1>(candidate);\n        int nj = get<2>(candidate);\n        \n        // Determine direction\n        int dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (i + di[d] == ni && j + dj[d] == nj) {\n                dir = d;\n                break;\n            }\n        }\n        \n        // Move to the new square\n        moves += dir_char[dir];\n        dfs(ni, nj);\n        \n        // Move back\n        moves += dir_char[(dir + 2) % 4];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    visited.assign(N, vector<bool>(N, false));\n    \n    dfs(0, 0);\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 15;\nconst int NN = GRID_SIZE * GRID_SIZE;\nconst int INF = 1e9;\n\nvector<int> pos[26];  // positions (linear index) for each letter\n\ninline int row(int idx) { return idx / GRID_SIZE; }\ninline int col(int idx) { return idx % GRID_SIZE; }\n\n// Manhattan distance transform: out[v] = min_u (cur[u] + dist(u, v))\nvoid dist_transform(const vector<int>& cur, vector<int>& out) {\n    int val[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j)\n            val[i][j] = cur[i * GRID_SIZE + j];\n\n    int tmp[GRID_SIZE][GRID_SIZE];\n    // horizontal pass\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        // left to right\n        tmp[i][0] = val[i][0];\n        for (int j = 1; j < GRID_SIZE; ++j) {\n            int a = val[i][j];\n            int b = tmp[i][j-1] + 1;\n            tmp[i][j] = a < b ? a : b;\n        }\n        // right to left\n        for (int j = GRID_SIZE - 2; j >= 0; --j) {\n            int b = tmp[i][j+1] + 1;\n            if (b < tmp[i][j]) tmp[i][j] = b;\n        }\n    }\n\n    // vertical pass\n    for (int j = 0; j < GRID_SIZE; ++j) {\n        // top to bottom\n        out[0 * GRID_SIZE + j] = tmp[0][j];\n        for (int i = 1; i < GRID_SIZE; ++i) {\n            int a = tmp[i][j];\n            int b = out[(i-1) * GRID_SIZE + j] + 1;\n            out[i * GRID_SIZE + j] = a < b ? a : b;\n        }\n        // bottom to top\n        for (int i = GRID_SIZE - 2; i >= 0; --i) {\n            int b = out[(i+1) * GRID_SIZE + j] + 1;\n            if (b < out[i * GRID_SIZE + j]) out[i * GRID_SIZE + j] = b;\n        }\n    }\n}\n\n// Compute minimal additional cost to type X from current distribution dp\nint compute_cost(const vector<int>& dp, const string& X,\n                 vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    int ans = INF;\n    for (int v : pos[X.back() - 'A'])\n        if (cur[v] < ans) ans = cur[v];\n    return ans;\n}\n\n// Extend dp by typing X, returning the new distribution\nvector<int> extend_dp(const vector<int>& dp, const string& X,\n                      vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    return cur;\n}\n\n// Reconstruct the optimal sequence of squares for typing X\nvector<int> reconstruct_path(const vector<int>& dp, const string& X) {\n    int L = X.size();\n    vector<vector<int>> cost(L + 1, vector<int>(NN, INF));\n    vector<vector<int>> prev(L + 1, vector<int>(NN, -1));\n\n    // pos 0\n    for (int u = 0; u < NN; ++u) cost[0][u] = dp[u];\n\n    for (int p = 0; p < L; ++p) {\n        char c = X[p];\n        for (int v : pos[c - 'A']) {\n            for (int u = 0; u < NN; ++u) {\n                if (cost[p][u] == INF) continue;\n                int d = abs(row(u) - row(v)) + abs(col(u) - col(v));\n                int new_cost = cost[p][u] + d + 1;\n                if (new_cost < cost[p+1][v]) {\n                    cost[p+1][v] = new_cost;\n                    prev[p+1][v] = u;\n                }\n            }\n        }\n    }\n\n    // find best end\n    int best_v = -1, best_cost = INF;\n    for (int v : pos[X.back() - 'A']) {\n        if (cost[L][v] < best_cost) {\n            best_cost = cost[L][v];\n            best_v = v;\n        }\n    }\n\n    // backtrack\n    vector<int> path(L);\n    int cur_v = best_v;\n    for (int p = L; p >= 1; --p) {\n        path[p-1] = cur_v;\n        cur_v = prev[p][cur_v];\n    }\n    return path;\n}\n\n// Compute maximum overlap (0..4) between suffix of S and prefix of tk\nint compute_overlap(const string& S, const string& tk) {\n    int slen = S.size();\n    int max_possible = min(4, slen);\n    for (int l = max_possible; l >= 1; --l) {\n        if (S.compare(slen - l, l, tk, 0, l) == 0)\n            return l;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_input, M;\n    cin >> N_input >> M;\n    int si, sj;\n    cin >> si >> sj;\n\n    // read grid\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            char c = row[j];\n            pos[c - 'A'].push_back(i * GRID_SIZE + j);\n        }\n    }\n\n    // read target strings\n    vector<string> t(M);\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    // initial state\n    vector<int> dp(NN, INF);\n    int start_idx = si * GRID_SIZE + sj;\n    dp[start_idx] = 0;\n\n    string S = \"\";\n    vector<pair<int, int>> ops;\n    vector<bool> covered(M, false);\n\n    // buffers for DP\n    vector<int> cur_buf(NN), minDist_buf(NN), next_buf(NN);\n\n    while (true) {\n        // check if all covered\n        bool all_covered = true;\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k]) {\n                all_covered = false;\n                break;\n            }\n        }\n        if (all_covered) break;\n\n        int best_k = -1;\n        int best_cost_val = INF;\n        string best_X;\n\n        // evaluate all uncovered t_k\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n            const string& tk = t[k];\n            int overlap = compute_overlap(S, tk);\n            string X = tk.substr(overlap);\n            if (X.empty()) {   // already covered\n                covered[k] = true;\n                continue;\n            }\n            int cost = compute_cost(dp, X, cur_buf, minDist_buf, next_buf);\n            if (cost < best_cost_val) {\n                best_cost_val = cost;\n                best_k = k;\n                best_X = X;\n            }\n        }\n\n        if (best_k == -1) break;  // nothing left to type\n\n        // reconstruct the optimal path for best_X\n        vector<int> path = reconstruct_path(dp, best_X);\n        for (int idx : path) {\n            ops.push_back({row(idx), col(idx)});\n        }\n\n        // update dp and S\n        dp = extend_dp(dp, best_X, cur_buf, minDist_buf, next_buf);\n        S += best_X;\n\n        // update covered set\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k] && S.find(t[k]) != string::npos)\n                covered[k] = true;\n        }\n    }\n\n    // output operations\n    for (auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    vector<vector<pair<int, int>>> polyominoes(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        vector<pair<int, int>> poly(d);\n        for (int i = 0; i < d; i++) {\n            cin >> poly[i].first >> poly[i].second;\n        }\n        polyominoes[k] = poly;\n    }\n\n    vector<pair<int, int>> has_oil;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int val;\n            cin >> val;\n            if (val > 0) {\n                has_oil.push_back({i, j});\n            }\n        }\n    }\n\n    cout << \"a \" << has_oil.size();\n    for (auto &p : has_oil) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl;\n    cout.flush();\n\n    int result;\n    cin >> result;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> A(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < N; i++) {\n            cin >> A[d][i];\n        }\n    }\n\n    vector<int> H(D);\n\n    for (int d = 0; d < D; d++) {\n        if (d == 0) {\n            int best_H = 1;\n            int best_value = 1e9;\n            for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                int total_width = 0;\n                for (int i = 0; i < N; i++) {\n                    total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                }\n                if (total_width <= W) {\n                    int value = total_width + N * H_candidate;\n                    if (value < best_value) {\n                        best_value = value;\n                        best_H = H_candidate;\n                    }\n                }\n            }\n            H[d] = best_H;\n        } else {\n            int H_prev = H[d-1];\n            int total_width = 0;\n            for (int i = 0; i < N; i++) {\n                total_width += (A[d][i] + H_prev - 1) / H_prev;\n            }\n            if (total_width <= W) {\n                H[d] = H_prev;\n            } else {\n                int best_H = 1;\n                int best_value = 1e9;\n                for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                    int total_width = 0;\n                    for (int i = 0; i < N; i++) {\n                        total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                    }\n                    if (total_width <= W) {\n                        int value = total_width + N * H_candidate;\n                        if (value < best_value) {\n                            best_value = value;\n                            best_H = H_candidate;\n                        }\n                    }\n                }\n                H[d] = best_H;\n            }\n        }\n    }\n\n    for (int d = 0; d < D; d++) {\n        int top, bottom;\n        if (d == 0) {\n            top = 0;\n            bottom = H[d];\n        } else {\n            if (H[d] <= H[d-1]) {\n                top = H[d-1] - H[d];\n                bottom = H[d-1];\n            } else {\n                top = 0;\n                bottom = H[d];\n            }\n        }\n        int left = 0;\n        for (int i = 0; i < N; i++) {\n            int width = (A[d][i] + H[d] - 1) / H[d];\n            int right = left + width;\n            cout << top << \" \" << left << \" \" << bottom << \" \" << right << endl;\n            left = right;\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <climits>\n\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    int rem[9][9];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> rem[i][j];\n            rem[i][j] %= MOD;\n        }\n    }\n\n    int s[20][3][3];\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n\n    for (int step = 0; step < K; step++) {\n        long long best_change = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= 6; p++) {\n                for (int q = 0; q <= 6; q++) {\n                    long long change = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int r = rem[p+i][q+j];\n                            int s_val = s[m][i][j];\n                            if (r + s_val < MOD) {\n                                change += s_val;\n                            } else {\n                                change += s_val - MOD;\n                            }\n                        }\n                    }\n                    if (change > best_change) {\n                        best_change = change;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_change <= 0) {\n            break;\n        }\n\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int &r = rem[best_p+i][best_q+j];\n                int s_val = s[best_m][i][j];\n                if (r + s_val < MOD) {\n                    r += s_val;\n                } else {\n                    r = r + s_val - MOD;\n                }\n            }\n        }\n\n        ops.push_back(make_tuple(best_m, best_p, best_q));\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto op : ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <cstring>\n#include <set>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\n\nstruct Crane {\n    int x, y;\n    int carrying; // -1 if not carrying, else container number\n};\n\nint grid[MAX_N][MAX_N]; // -1: empty, else container number\nCrane cranes[MAX_N];\nint next_arrival[MAX_N]; // next index to arrive for each row\nvector<int> dispatched[MAX_N]; // dispatched containers per gate\n\nint next_required[MAX_N]; // next required container for each gate\n\nvoid init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        cranes[i] = {i, 0, -1};\n        next_arrival[i] = 0;\n        next_required[i] = i * N; // smallest in the set\n    }\n}\n\nbool is_next_to_dispatch(int container, int gate) {\n    if (container < gate * N || container >= (gate + 1) * N) {\n        return false;\n    }\n    return container == next_required[gate];\n}\n\nvoid update_next_required(int gate) {\n    set<int> desired;\n    for (int i = 0; i < N; i++) {\n        desired.insert(gate * N + i);\n    }\n    for (int d : dispatched[gate]) {\n        desired.erase(d);\n    }\n    if (!desired.empty()) {\n        next_required[gate] = *desired.begin();\n    } else {\n        next_required[gate] = -1;\n    }\n}\n\nint main() {\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    init();\n\n    vector<string> actions_per_crane(N, \"\");\n    int total_containers = N * N;\n    int dispatched_count = 0;\n    int turn = 0;\n\n    while (turn < MAX_TURNS && dispatched_count < total_containers) {\n        // Step 1: New container arrival\n        for (int i = 0; i < N; i++) {\n            if (next_arrival[i] < N) {\n                bool gate_occupied = false;\n                if (grid[i][0] != -1) {\n                    gate_occupied = true;\n                }\n                for (int k = 0; k < N; k++) {\n                    if (cranes[k].x == i && cranes[k].y == 0) {\n                        gate_occupied = true;\n                        break;\n                    }\n                }\n                if (!gate_occupied) {\n                    grid[i][0] = A[i][next_arrival[i]];\n                    next_arrival[i]++;\n                }\n            }\n        }\n\n        // Prepare for crane actions\n        Crane next_cranes[MAX_N];\n        for (int i = 0; i < N; i++) {\n            next_cranes[i] = cranes[i];\n        }\n        int next_grid[MAX_N][MAX_N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                next_grid[i][j] = grid[i][j];\n            }\n        }\n\n        // For collision detection: record intended next positions\n        int intended_x[MAX_N], intended_y[MAX_N];\n        for (int i = 0; i < N; i++) {\n            intended_x[i] = cranes[i].x;\n            intended_y[i] = cranes[i].y;\n        }\n\n        // Process each crane in order (large crane first, then small cranes)\n        for (int idx = 0; idx < N; idx++) {\n            char action = '.';\n            Crane& crane = cranes[idx];\n            int x = crane.x;\n            int y = crane.y;\n            int carrying = crane.carrying;\n\n            if (carrying != -1) {\n                int target_gate = carrying / N;\n                int target_x = target_gate;\n                int target_y = N-1;\n\n                if (x == target_x && y == target_y) {\n                    if (is_next_to_dispatch(carrying, target_gate)) {\n                        action = 'Q';\n                    } else {\n                        if (x+1 < N && next_grid[x+1][y] == -1) {\n                            action = 'D';\n                        } else if (x-1 >=0 && next_grid[x-1][y] == -1) {\n                            action = 'U';\n                        } else if (y-1 >=0 && next_grid[x][y-1] == -1) {\n                            action = 'L';\n                        } else {\n                            action = '.';\n                        }\n                    }\n                } else {\n                    if (y < target_y) {\n                        action = 'R';\n                    } else if (x < target_x) {\n                        action = 'D';\n                    } else if (x > target_x) {\n                        action = 'U';\n                    } else {\n                        action = '.';\n                    }\n                }\n            } else {\n                if (grid[x][y] != -1) {\n                    action = 'P';\n                } else {\n                    if (y < N-1) {\n                        action = 'R';\n                    } else {\n                        action = '.';\n                    }\n                }\n            }\n\n            // Validate action and update intended position\n            int nx = x, ny = y;\n            bool valid = true;\n            if (action == 'U') nx--;\n            else if (action == 'D') nx++;\n            else if (action == 'L') ny--;\n            else if (action == 'R') ny++;\n\n            if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) valid = false;\n                else {\n                    if (carrying != -1 && idx >= 1) {\n                        if (next_grid[nx][ny] != -1) valid = false;\n                    }\n                    for (int i = 0; i < N; i++) {\n                        if (i != idx) {\n                            if (intended_x[i] == nx && intended_y[i] == ny) {\n                                valid = false;\n                                break;\n                            }\n                            if (intended_x[i] == x && intended_y[i] == y && \n                                intended_x[idx] == nx && intended_y[idx] == ny) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                    }\n                }\n            } else if (action == 'P') {\n                if (carrying != -1 || next_grid[x][y] == -1) valid = false;\n            } else if (action == 'Q') {\n                if (carrying == -1 || next_grid[x][y] != -1) valid = false;\n            }\n\n            if (!valid) {\n                action = '.';\n                nx = x;\n                ny = y;\n            }\n\n            // Apply action\n            if (action == 'P') {\n                next_cranes[idx].carrying = next_grid[x][y];\n                next_grid[x][y] = -1;\n            } else if (action == 'Q') {\n                next_grid[x][y] = carrying;\n                next_cranes[idx].carrying = -1;\n            } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                next_cranes[idx].x = nx;\n                next_cranes[idx].y = ny;\n                intended_x[idx] = nx;\n                intended_y[idx] = ny;\n            }\n\n            actions_per_crane[idx] += action;\n        }\n\n        // Update global state\n        for (int i = 0; i < N; i++) {\n            cranes[i] = next_cranes[i];\n            for (int j = 0; j < N; j++) {\n                grid[i][j] = next_grid[i][j];\n            }\n        }\n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container = grid[i][N-1];\n                grid[i][N-1] = -1;\n                dispatched[i].push_back(container);\n                dispatched_count++;\n                update_next_required(i);\n            }\n        }\n\n        turn++;\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << actions_per_crane[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(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    vector<tuple<int, int, int>> surp;\n    vector<tuple<int, int, int>> def;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                surp.push_back(make_tuple(i, j, grid[i][j]));\n            } else if (grid[i][j] < 0) {\n                def.push_back(make_tuple(i, j, -grid[i][j]));\n            }\n        }\n    }\n\n    int cur_i = 0, cur_j = 0;\n    vector<string> ops;\n\n    auto move_to = [&](int target_i, int target_j) {\n        while (cur_i < target_i) {\n            ops.push_back(\"D\");\n            cur_i++;\n        }\n        while (cur_i > target_i) {\n            ops.push_back(\"U\");\n            cur_i--;\n        }\n        while (cur_j < target_j) {\n            ops.push_back(\"R\");\n            cur_j++;\n        }\n        while (cur_j > target_j) {\n            ops.push_back(\"L\");\n            cur_j--;\n        }\n    };\n\n    while (!surp.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < surp.size(); idx++) {\n            auto [i, j, amt] = surp[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = surp[best_idx];\n        move_to(i, j);\n        ops.push_back(\"+\" + to_string(amt));\n        surp.erase(surp.begin() + best_idx);\n    }\n\n    while (!def.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < def.size(); idx++) {\n            auto [i, j, amt] = def[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = def[best_idx];\n        move_to(i, j);\n        ops.push_back(\"-\" + to_string(amt));\n        def.erase(def.begin() + best_idx);\n    }\n\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n    int grid_size = N * N;\n\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n\n    // Initialize random number generator\n    mt19937 rng(12345);\n    \n    // Precompute maximum values for each criterion\n    vector<int> max_vals(M, 0);\n    for (int l = 0; l < M; l++) {\n        for (int i = 0; i < seed_count; i++) {\n            max_vals[l] = max(max_vals[l], seeds[i][l]);\n        }\n    }\n    \n    // Target sum to aim for\n    long long target_sum = 0;\n    for (int l = 0; l < M; l++) {\n        target_sum += max_vals[l];\n    }\n\n    // Grid directions\n    vector<int> di = {-1, 1, 0, 0};\n    vector<int> dj = {0, 0, -1, 1};\n\n    for (int t = 0; t < T; t++) {\n        // 1. ADVANCED SEED SELECTION\n        // Calculate total values and criterion-wise strengths\n        vector<int> total(seed_count, 0);\n        vector<vector<int>> criterion_strength(M, vector<int>(seed_count));\n        for (int i = 0; i < seed_count; i++) {\n            for (int l = 0; l < M; l++) {\n                total[i] += seeds[i][l];\n                criterion_strength[l][i] = seeds[i][l];\n            }\n        }\n\n        // Sort seeds by total value\n        vector<int> indices(seed_count);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(), [&](int i, int j) { \n            if (total[i] != total[j]) return total[i] > total[j];\n            return i < j;\n        });\n\n        // Select seeds using a hybrid approach\n        vector<int> selected_indices;\n        set<int> selected_set;\n        \n        // Strategy: Select seeds that are good in different criteria\n        // Phase 1: Top seeds by total value (50% of grid)\n        for (int i = 0; i < grid_size / 2 && i < seed_count; i++) {\n            if (selected_set.count(indices[i]) == 0) {\n                selected_indices.push_back(indices[i]);\n                selected_set.insert(indices[i]);\n            }\n        }\n        \n        // Phase 2: Seeds that are strong in specific criteria (25% of grid)\n        for (int l = 0; l < M && selected_indices.size() < grid_size * 3 / 4; l++) {\n            // Find top seeds for this criterion\n            vector<int> candidates;\n            for (int i = 0; i < seed_count; i++) {\n                if (selected_set.count(i) == 0) {\n                    candidates.push_back(i);\n                }\n            }\n            sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                return criterion_strength[l][a] > criterion_strength[l][b];\n            });\n            for (int i = 0; i < min(2, (int)candidates.size()) && selected_indices.size() < grid_size * 3 / 4; i++) {\n                selected_indices.push_back(candidates[i]);\n                selected_set.insert(candidates[i]);\n            }\n        }\n        \n        // Phase 3: Fill remaining with seeds that have high variance (diverse profiles)\n        vector<pair<double, int>> variance_seeds;\n        for (int i = 0; i < seed_count; i++) {\n            if (selected_set.count(i)) continue;\n            // Calculate variance of the seed's values\n            double mean = total[i] / (double)M;\n            double variance = 0;\n            for (int l = 0; l < M; l++) {\n                variance += (seeds[i][l] - mean) * (seeds[i][l] - mean);\n            }\n            variance /= M;\n            variance_seeds.push_back({variance, i});\n        }\n        sort(variance_seeds.begin(), variance_seeds.end(), greater<pair<double, int>>());\n        for (auto [var, idx] : variance_seeds) {\n            if (selected_indices.size() >= grid_size) break;\n            if (selected_set.count(idx) == 0) {\n                selected_indices.push_back(idx);\n                selected_set.insert(idx);\n            }\n        }\n\n        // 2. SMART GRID ASSIGNMENT\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Precompute potential value of pairs\n        auto pair_potential = [&](int a, int b) {\n            long long potential = 0;\n            for (int l = 0; l < M; l++) {\n                // Expected value if we could always take the max\n                potential += max(seeds[a][l], seeds[b][l]);\n                // Add a bonus for complementarity (how well they cover different criteria)\n                if (seeds[a][l] > 0 && seeds[b][l] > 0) {\n                    potential += min(seeds[a][l], seeds[b][l]) * 0.1;\n                }\n            }\n            return potential;\n        };\n\n        // Precompute \"goodness\" of each seed\n        vector<double> seed_goodness(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            if (selected_set.count(i) == 0) continue;\n            // Goodness is based on total value and diversity\n            double goodness = total[i];\n            double mean = total[i] / (double)M;\n            double variance = 0;\n            for (int l = 0; l < M; l++) {\n                variance += (seeds[i][l] - mean) * (seeds[i][l] - mean);\n            }\n            goodness += sqrt(variance) * 0.5; // Reward diversity\n            seed_goodness[i] = goodness;\n        }\n\n        // Assignment strategy: Place good seeds in the center, and pair complementary seeds\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cells.push_back({i, j});\n            }\n        }\n        \n        // Sort cells by number of neighbors (center first)\n        sort(cells.begin(), cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            int na = 0, nb = 0;\n            for (int d = 0; d < 4; d++) {\n                int ai = a.first + di[d], aj = a.second + dj[d];\n                if (ai >= 0 && ai < N && aj >= 0 && aj < N) na++;\n                int bi = b.first + di[d], bj = b.second + dj[d];\n                if (bi >= 0 && bi < N && bj >= 0 && bj < N) nb++;\n            }\n            if (na != nb) return na > nb;\n            return a < b;\n        });\n\n        // Greedy assignment with lookahead\n        for (auto [i, j] : cells) {\n            int best_seed = -1;\n            double best_score = -1e18;\n            \n            // Try each unused seed\n            for (int seed_idx : selected_indices) {\n                if (used[seed_idx]) continue;\n                \n                // Calculate score for placing this seed here\n                double score = seed_goodness[seed_idx];\n                int neighbor_count = 0;\n                \n                // Consider existing neighbors\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor = grid[ni][nj];\n                        double pair_score = pair_potential(seed_idx, neighbor);\n                        score += pair_score;\n                        neighbor_count++;\n                    }\n                }\n                \n                // If no neighbors, use the seed's own potential\n                if (neighbor_count == 0) {\n                    score += seed_goodness[seed_idx];\n                }\n                \n                // Add small exploration factor that decreases over time\n                double exploration = max(0.0, 1.0 - (double)t / T) * 5.0;\n                score += exploration * (rng() % 100);\n                \n                // Penalty for seeds that are too similar to existing neighbors\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor = grid[ni][nj];\n                        // Calculate similarity (lower is better)\n                        double similarity = 0;\n                        for (int l = 0; l < M; l++) {\n                            similarity += abs(seeds[seed_idx][l] - seeds[neighbor][l]);\n                        }\n                        score -= similarity * 0.01; // Small penalty for similarity\n                    }\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_seed = seed_idx;\n                }\n            }\n            \n            if (best_seed != -1) {\n                grid[i][j] = best_seed;\n                used[best_seed] = true;\n            }\n        }\n\n        // 3. OUTPUT\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // 4. READ NEW SEEDS\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n        \n        // 5. ADAPTIVE STRATEGY\n        // Check if we're making progress\n        int current_max = 0;\n        for (int i = 0; i < seed_count; i++) {\n            int sum = 0;\n            for (int l = 0; l < M; l++) sum += seeds[i][l];\n            current_max = max(current_max, sum);\n        }\n        \n        // If we're close to target, we can adjust parameters for more aggressive optimization\n        if (current_max > target_sum * 0.9) {\n            // Increase exploration in future iterations\n            // This is handled implicitly by the decreasing exploration factor\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <queue>\n#include <map>\n#include <set>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nPoint get_grab_pos(Point s, char dir, int d) {\n    if (dir == 'R') return Point(s.x - d, s.y);\n    if (dir == 'L') return Point(s.x + d, s.y);\n    if (dir == 'D') return Point(s.x, s.y - d);\n    if (dir == 'U') return Point(s.x, s.y + d);\n    return Point();\n}\n\nPoint get_release_pos(Point t, char dir, int d) {\n    if (dir == 'R') return Point(t.x - d, t.y);\n    if (dir == 'L') return Point(t.x + d, t.y);\n    if (dir == 'D') return Point(t.x, t.y - d);\n    if (dir == 'U') return Point(t.x, t.y + d);\n    return Point();\n}\n\nbool is_valid(Point p, int N) {\n    return p.x >= 0 && p.x < N && p.y >= 0 && p.y < N;\n}\n\nvector<char> get_path(Point from, Point to) {\n    vector<char> path;\n    int x = from.x;\n    int y = from.y;\n    while (x != to.x) {\n        if (x < to.x) {\n            path.push_back('R');\n            x++;\n        } else {\n            path.push_back('L');\n            x--;\n        }\n    }\n    while (y != to.y) {\n        if (y < to.y) {\n            path.push_back('D');\n            y++;\n        } else {\n            path.push_back('U');\n            y--;\n        }\n    }\n    return path;\n}\n\nstring create_turn(char movement, int leaf_index, char direction, bool grab, int V) {\n    string s(2 * V, '.');\n    s[0] = movement;\n    if (leaf_index != -1) {\n        s[leaf_index] = direction;\n        if (grab) {\n            s[V + leaf_index] = 'P';\n        }\n    }\n    return s;\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\n    vector<string> S(N), T(N);\n    for (int i = 0; i < N; i++) cin >> S[i];\n    for (int i = 0; i < N; i++) cin >> T[i];\n\n    vector<Point> initial_positions;\n    vector<Point> target_positions;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (S[i][j] == '1') initial_positions.push_back(Point(i, j));\n            if (T[i][j] == '1') target_positions.push_back(Point(i, j));\n        }\n    }\n\n    vector<pair<Point, Point>> pairs;\n    vector<bool> assigned(M, false);\n\n    for (int i = 0; i < M; i++) {\n        Point s = initial_positions[i];\n        int best_j = -1;\n        int best_dist = 1e9;\n        for (int j = 0; j < M; j++) {\n            if (assigned[j]) continue;\n            int dist = manhattan(s, target_positions[j]);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_j = j;\n            }\n        }\n        assigned[best_j] = true;\n        pairs.push_back({s, target_positions[best_j]});\n    }\n\n    Point current_root(N / 2, N / 2);\n    vector<string> turns;\n\n    vector<pair<Point, Point>> remaining = pairs;\n\n    while (!remaining.empty()) {\n        int best_cost = 1e9;\n        int best_index = -1;\n        int best_leaf = -1;\n        char best_grab_dir = ' ';\n        char best_release_dir = ' ';\n        Point best_grab_pos, best_release_pos;\n\n        for (int i = 0; i < remaining.size(); i++) {\n            Point s = remaining[i].first;\n            Point t = remaining[i].second;\n            for (int leaf = 1; leaf < V; leaf++) {\n                int d = leaf;\n                for (char grab_dir : {'L', 'R', 'U', 'D'}) {\n                    Point grab_pos = get_grab_pos(s, grab_dir, d);\n                    if (!is_valid(grab_pos, N)) continue;\n                    for (char release_dir : {'L', 'R', 'U', 'D'}) {\n                        Point release_pos = get_release_pos(t, release_dir, d);\n                        if (!is_valid(release_pos, N)) continue;\n                        int cost = manhattan(current_root, grab_pos) + manhattan(grab_pos, release_pos);\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_index = i;\n                            best_leaf = leaf;\n                            best_grab_dir = grab_dir;\n                            best_release_dir = release_dir;\n                            best_grab_pos = grab_pos;\n                            best_release_pos = release_pos;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_index == -1) {\n            break;\n        }\n\n        vector<char> path1 = get_path(current_root, best_grab_pos);\n        if (path1.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_grab_dir, true, V));\n        } else {\n            for (int j = 0; j < path1.size(); j++) {\n                bool grab = (j == path1.size() - 1);\n                turns.push_back(create_turn(path1[j], best_leaf, best_grab_dir, grab, V));\n            }\n        }\n        current_root = best_grab_pos;\n\n        vector<char> path2 = get_path(best_grab_pos, best_release_pos);\n        if (path2.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_release_dir, true, V));\n        } else {\n            for (int j = 0; j < path2.size(); j++) {\n                bool release = (j == path2.size() - 1);\n                turns.push_back(create_turn(path2[j], best_leaf, best_release_dir, release, V));\n            }\n        }\n        current_root = best_release_pos;\n\n        remaining.erase(remaining.begin() + best_index);\n    }\n\n    cout << V << endl;\n    for (int i = 1; i < V; i++) {\n        cout << 0 << \" \" << i << endl;\n    }\n    cout << N/2 << \" \" << N/2 << endl;\n\n    for (const string& turn : turns) {\n        cout << turn << endl;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct Point {\n    int x, y, weight;\n};\n\nclass SegmentTree {\npublic:\n    int n;\n    vector<int> sum;\n    vector<int> max_prefix;\n    vector<int> max_suffix;\n    vector<int> max_sum;\n\n    SegmentTree(int size) {\n        n = size;\n        sum.resize(4 * n, 0);\n        max_prefix.resize(4 * n, 0);\n        max_suffix.resize(4 * n, 0);\n        max_sum.resize(4 * n, 0);\n    }\n\n    void update(int idx, int val, int node = 1, int left = 0, int right = -1) {\n        if (right == -1) right = n - 1;\n        if (left == right) {\n            sum[node] += val;\n            max_prefix[node] = sum[node];\n            max_suffix[node] = sum[node];\n            max_sum[node] = sum[node];\n            return;\n        }\n        int mid = (left + right) / 2;\n        if (idx <= mid) {\n            update(idx, val, 2 * node, left, mid);\n        } else {\n            update(idx, val, 2 * node + 1, mid + 1, right);\n        }\n        sum[node] = sum[2 * node] + sum[2 * node + 1];\n        max_prefix[node] = max(max_prefix[2 * node], sum[2 * node] + max_prefix[2 * node + 1]);\n        max_suffix[node] = max(max_suffix[2 * node + 1], sum[2 * node + 1] + max_suffix[2 * node]);\n        max_sum[node] = max({max_sum[2 * node], max_sum[2 * node + 1], max_suffix[2 * node] + max_prefix[2 * node + 1]});\n    }\n\n    int query() {\n        return max_sum[1];\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    srand(time(0));\n\n    int N;\n    cin >> N;\n    vector<Point> points;\n    set<pair<int, int>> point_set;\n    \n    for (int i = 0; i < 2 * N; i++) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 0});\n        point_set.insert({x, y});\n    }\n\n    for (int i = 0; i < N; i++) {\n        points[i].weight = 1;\n    }\n    for (int i = N; i < 2 * N; i++) {\n        points[i].weight = -1;\n    }\n\n    // Get unique x-coordinates and sort\n    set<int> x_set;\n    for (auto& p : points) {\n        x_set.insert(p.x);\n    }\n    vector<int> unique_x(x_set.begin(), x_set.end());\n    sort(unique_x.begin(), unique_x.end());\n    int total_x = unique_x.size();\n\n    // Group points by x\n    map<int, vector<Point>> points_by_x;\n    for (auto& p : points) {\n        points_by_x[p.x].push_back(p);\n    }\n\n    // Get unique y-coordinates and mapping\n    set<int> y_set;\n    for (auto& p : points) {\n        y_set.insert(p.y);\n    }\n    vector<int> unique_y(y_set.begin(), y_set.end());\n    sort(unique_y.begin(), unique_y.end());\n    map<int, int> y_to_idx;\n    for (int i = 0; i < unique_y.size(); i++) {\n        y_to_idx[unique_y[i]] = i;\n    }\n    int m = unique_y.size();\n\n    // Select candidate x1: first 100, last 100, and 10 evenly spaced\n    vector<int> candidate_x1;\n    int num_take = min(100, total_x);\n    for (int i = 0; i < num_take; i++) {\n        candidate_x1.push_back(unique_x[i]);\n    }\n    for (int i = max(0, total_x - num_take); i < total_x; i++) {\n        candidate_x1.push_back(unique_x[i]);\n    }\n    for (int i = 1; i <= 10; i++) {\n        int idx = total_x * i / 11;\n        if (idx < total_x) {\n            candidate_x1.push_back(unique_x[idx]);\n        }\n    }\n    sort(candidate_x1.begin(), candidate_x1.end());\n    candidate_x1.erase(unique(candidate_x1.begin(), candidate_x1.end()), candidate_x1.end());\n\n    int best_score = -1e9;\n    int best_x1 = 0, best_x2 = 0;\n\n    for (int x1 : candidate_x1) {\n        SegmentTree seg(m);\n        for (int x2 : unique_x) {\n            if (x2 < x1) continue;\n            for (auto& p : points_by_x[x2]) {\n                int idx = y_to_idx[p.y];\n                seg.update(idx, p.weight);\n            }\n            int current_score = seg.query();\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_x1 = x1;\n                best_x2 = x2;\n            }\n        }\n    }\n\n    if (best_score < 0) {\n        while (true) {\n            int x = rand() % 100000;\n            int y = rand() % 100000;\n            if (point_set.find({x, y}) == point_set.end() &&\n                point_set.find({x, y+1}) == point_set.end() &&\n                point_set.find({x+1, y}) == point_set.end() &&\n                point_set.find({x+1, y+1}) == point_set.end()) {\n                cout << 4 << endl;\n                cout << x << \" \" << y << endl;\n                cout << x << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y << endl;\n                break;\n            }\n        }\n    } else {\n        vector<int> y_weights(m, 0);\n        for (int x = best_x1; x <= best_x2; x++) {\n            if (points_by_x.find(x) != points_by_x.end()) {\n                for (auto& p : points_by_x[x]) {\n                    int idx = y_to_idx[p.y];\n                    y_weights[idx] += p.weight;\n                }\n            }\n        }\n\n        int best_sum = 0;\n        int current_sum = 0;\n        int best_start = 0, best_end = 0;\n        int current_start = 0;\n\n        for (int i = 0; i < m; i++) {\n            current_sum += y_weights[i];\n            if (current_sum > best_sum) {\n                best_sum = current_sum;\n                best_start = current_start;\n                best_end = i;\n            }\n            if (current_sum < 0) {\n                current_sum = 0;\n                current_start = i + 1;\n            }\n        }\n\n        if (best_sum <= 0) {\n            while (true) {\n                int x = rand() % 100000;\n                int y = rand() % 100000;\n                if (point_set.find({x, y}) == point_set.end() &&\n                    point_set.find({x, y+1}) == point_set.end() &&\n                    point_set.find({x+1, y}) == point_set.end() &&\n                    point_set.find({x+1, y+1}) == point_set.end()) {\n                    cout << 4 << endl;\n                    cout << x << \" \" << y << endl;\n                    cout << x << \" \" << y+1 << endl;\n                    cout << x+1 << \" \" << y+1 << endl;\n                    cout << x+1 << \" \" << y << endl;\n                    break;\n                }\n            }\n        } else {\n            int y1 = unique_y[best_start];\n            int y2 = unique_y[best_end];\n            cout << 4 << endl;\n            cout << best_x1 << \" \" << y1 << endl;\n            cout << best_x1 << \" \" << y2 << endl;\n            cout << best_x2 << \" \" << y2 << endl;\n            cout << best_x2 << \" \" << y1 << endl;\n        }\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nstruct Rectangle {\n    int id;\n    double w_est, h_est;\n    double w_var, h_var;\n};\n\nstruct Placement {\n    int id;\n    int rotated;\n    char direction;\n    int reference;\n};\n\nstruct PlacedRect {\n    int id;\n    double x, y, w, h;\n};\n\nclass FastPacker {\nprivate:\n    vector<Rectangle> rects;\n    double sigma;\n    int N, T;\n    mt19937 rng;\n    \n    void updateEstimates(int turn, double W_meas, double H_meas, const vector<Placement>& placement) {\n        if (placement.empty()) return;\n        \n        // Fast update: adjust all placed rectangles proportionally\n        for (const auto& p : placement) {\n            Rectangle& rect = rects[p.id];\n            double factor = 1.0 + (W_meas + H_meas) / 200000.0;\n            rect.w_est = rect.w_est * 0.95 + rect.w_est * factor * 0.05;\n            rect.h_est = rect.h_est * 0.95 + rect.h_est * factor * 0.05;\n            rect.w_est = max(1.0, min(1e9, rect.w_est));\n            rect.h_est = max(1.0, min(1e9, rect.h_est));\n        }\n    }\n    \n    // Fast simulation without expensive operations\n    void fastSimulate(const vector<Placement>& placement, vector<PlacedRect>& placed, double& W, double& H) {\n        placed.clear();\n        W = 0; H = 0;\n        \n        for (const auto& p : placement) {\n            const Rectangle& rect = rects[p.id];\n            double w = p.rotated ? rect.h_est : rect.w_est;\n            double h = p.rotated ? rect.w_est : rect.h_est;\n            \n            double x = 0, y = 0;\n            \n            if (p.direction == 'U') {\n                if (p.reference != -1) {\n                    for (const auto& r : placed) {\n                        if (r.id == p.reference) { x = r.x + r.w; break; }\n                    }\n                }\n                // Find highest y without overlap (simplified)\n                y = 0;\n                for (const auto& r : placed) {\n                    if (x < r.x + r.w && x + w > r.x) {\n                        y = max(y, r.y + r.h);\n                    }\n                }\n            } else {\n                if (p.reference != -1) {\n                    for (const auto& r : placed) {\n                        if (r.id == p.reference) { y = r.y + r.h; break; }\n                    }\n                }\n                // Find leftmost x without overlap (simplified)\n                x = 0;\n                for (const auto& r : placed) {\n                    if (y < r.y + r.h && y + h > r.y) {\n                        x = max(x, r.x + r.w);\n                    }\n                }\n            }\n            \n            placed.push_back({p.id, x, y, w, h});\n            W = max(W, x + w);\n            H = max(H, y + h);\n        }\n    }\n    \n    vector<Placement> constructSolution(int turn) {\n        vector<Placement> solution;\n        solution.reserve(N);\n        \n        // Precompute suffix sum\n        vector<double> suffix_sum(N + 1, 0);\n        for (int i = N - 1; i >= 0; i--) {\n            suffix_sum[i] = suffix_sum[i + 1] + rects[i].w_est + rects[i].h_est;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            const Rectangle& rect = rects[i];\n            \n            // Fast rotation choice: minimize max dimension\n            int rot = (max(rect.h_est, rect.w_est) == rect.h_est && rect.h_est < rect.w_est) ? 1 : 0;\n            \n            // Fast direction choice: 'U' for most, 'L' for tall rectangles\n            double w = rot ? rect.h_est : rect.w_est;\n            double h = rot ? rect.w_est : rect.h_est;\n            char dir = (h > w * 1.5) ? 'L' : 'U';\n            \n            // Reference: previous or -1\n            int ref = solution.empty() ? -1 : solution.back().id;\n            \n            // Quick evaluation\n            vector<Placement> temp = solution;\n            temp.push_back({i, rot, dir, ref});\n            \n            double new_W, new_H;\n            vector<PlacedRect> new_placed;\n            fastSimulate(temp, new_placed, new_W, new_H);\n            \n            double current_W = 0, current_H = 0;\n            if (!solution.empty()) {\n                vector<PlacedRect> cur_placed;\n                fastSimulate(solution, cur_placed, current_W, current_H);\n            }\n            \n            double current_score = current_W + current_H + suffix_sum[i];\n            double new_score = new_W + new_H + suffix_sum[i + 1];\n            \n            // Include if beneficial or early turn\n            if (new_score <= current_score * 1.05 || turn < T / 3 || i < 5) {\n                solution.push_back({i, rot, dir, ref});\n            }\n        }\n        \n        return solution;\n    }\n    \n    vector<Placement> validateQuick(vector<Placement> solution) {\n        if (solution.empty()) return solution;\n        \n        // Ensure ascending order\n        sort(solution.begin(), solution.end(), [](const Placement& a, const Placement& b) {\n            return a.id < b.id;\n        });\n        \n        // Fix references\n        for (size_t i = 0; i < solution.size(); i++) {\n            if (solution[i].reference != -1) {\n                bool found = false;\n                for (size_t j = 0; j < i; j++) {\n                    if (solution[j].id == solution[i].reference) {\n                        found = true; break;\n                    }\n                }\n                if (!found) solution[i].reference = -1;\n            }\n        }\n        \n        return solution;\n    }\n\npublic:\n    FastPacker(int n, int t, double s, const vector<pair<double, double>>& observed) \n        : N(n), T(t), sigma(s), rng(12345 + n * 7) {\n        rects.resize(N);\n        for (int i = 0; i < N; i++) {\n            rects[i].id = i;\n            normal_distribution<double> dist(0, sigma * 0.03);\n            rects[i].w_est = observed[i].first + dist(rng);\n            rects[i].h_est = observed[i].second + dist(rng);\n            rects[i].w_var = sigma * sigma;\n            rects[i].h_var = sigma * sigma;\n            \n            rects[i].w_est = max(1.0, min(1e9, rects[i].w_est));\n            rects[i].h_est = max(1.0, min(1e9, rects[i].h_est));\n        }\n    }\n    \n    vector<Placement> solve(int turn, double W_meas, double H_meas, const vector<Placement>& last_placement) {\n        if (turn > 0) {\n            updateEstimates(turn, W_meas, H_meas, last_placement);\n        }\n        \n        vector<Placement> solution = constructSolution(turn);\n        solution = validateQuick(solution);\n        \n        // Fallback\n        if (solution.empty()) {\n            for (int i = 0; i < N; i++) {\n                solution.push_back({i, 0, 'U', (i == 0) ? -1 : i - 1});\n            }\n        }\n        \n        return solution;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<double, double>> observed(N);\n    for (int i = 0; i < N; i++) {\n        cin >> observed[i].first >> observed[i].second;\n    }\n    \n    FastPacker packer(N, T, sigma, observed);\n    \n    vector<Placement> last_placement;\n    \n    for (int turn = 0; turn < T; turn++) {\n        double W_meas = 0, H_meas = 0;\n        if (turn > 0) cin >> W_meas >> H_meas;\n        \n        vector<Placement> placement = packer.solve(turn, W_meas, H_meas, last_placement);\n        \n        cout << placement.size() << \"\\n\";\n        for (const auto& p : placement) {\n            cout << p.id << \" \" << p.rotated << \" \" << p.direction << \" \" << p.reference << \"\\n\";\n        }\n        cout.flush();\n        \n        last_placement = placement;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n\n    void read_input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; ++i) cin >> A[i];\n        adj.assign(N, {});\n        for (int i = 0; i < M; ++i) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // read and ignore coordinates\n        for (int i = 0; i < N; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n\n    vector<int> solve() {\n        // Try multiple strategies with safe improvements\n        vector<int> best_parent;\n        long long best_score = -1;\n        \n        // Strategy 1: High beauty roots with safe improvement\n        {\n            auto parent1 = build_with_high_roots();\n            improve_safe(parent1);\n            long long score1 = compute_score(parent1);\n            if (score1 > best_score) {\n                best_score = score1;\n                best_parent = parent1;\n            }\n        }\n        \n        // Strategy 2: Descending beauty with safe improvement\n        {\n            auto parent2 = build_bfs_descending();\n            improve_safe(parent2);\n            long long score2 = compute_score(parent2);\n            if (score2 > best_score) {\n                best_score = score2;\n                best_parent = parent2;\n            }\n        }\n        \n        // Strategy 3: Ascending beauty with safe improvement\n        {\n            auto parent3 = build_bfs_ascending();\n            improve_safe(parent3);\n            long long score3 = compute_score(parent3);\n            if (score3 > best_score) {\n                best_score = score3;\n                best_parent = parent3;\n            }\n        }\n        \n        // Strategy 4: Try a hybrid approach\n        {\n            auto parent4 = build_hybrid();\n            improve_safe(parent4);\n            long long score4 = compute_score(parent4);\n            if (score4 > best_score) {\n                best_score = score4;\n                best_parent = parent4;\n            }\n        }\n        \n        return best_parent;\n    }\n\n    vector<int> build_with_high_roots() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n        \n        int num_roots = max(1, N / 5);\n        for (int i = 0; i < num_roots; ++i) {\n            int root = vertices[i];\n            if (assigned[root]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({root, 0});\n            assigned[root] = true;\n            parent[root] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] > A[b];\n                });\n                \n                for (int v : neighbors) {\n                    if (!assigned[v]) {\n                        assigned[v] = true;\n                        parent[v] = u;\n                        if (d + 1 < H) {\n                            q.push({v, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_bfs_descending() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] > A[b];\n                });\n                \n                for (int w : neighbors) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_bfs_ascending() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] < A[b];\n        });\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] < A[b];\n                });\n                \n                for (int w : neighbors) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_hybrid() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        // Mix of strategies: start with high beauty, then fill gaps\n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n        \n        // First pass: build trees from top 10% vertices\n        for (int i = 0; i < N / 10; ++i) {\n            int v = vertices[i];\n            if (assigned[v]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w] && A[w] >= A[v] / 2) { // Prefer high beauty neighbors\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Second pass: cover remaining vertices\n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            // Find best parent among assigned neighbors\n            int best_parent = -1;\n            int best_depth = -1;\n            \n            for (int u : adj[v]) {\n                if (assigned[u]) {\n                    // Need to compute depth of u\n                    int depth_u = 0;\n                    int cur = u;\n                    while (parent[cur] != -1) {\n                        depth_u++;\n                        cur = parent[cur];\n                    }\n                    \n                    if (depth_u < H - 1 && depth_u > best_depth) {\n                        best_depth = depth_u;\n                        best_parent = u;\n                    }\n                }\n            }\n            \n            if (best_parent != -1) {\n                assigned[v] = true;\n                parent[v] = best_parent;\n            } else {\n                // Make it a root\n                assigned[v] = true;\n                parent[v] = -1;\n            }\n        }\n        \n        return parent;\n    }\n\n    void improve_safe(vector<int>& parent) {\n        const int MAX_ITER = 10;\n        vector<int> depth(N, 0);\n        vector<vector<int>> children(N);\n        \n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            // Rebuild depth and children\n            fill(depth.begin(), depth.end(), 0);\n            for (int i = 0; i < N; ++i) children[i].clear();\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] != -1) {\n                    children[parent[v]].push_back(v);\n                }\n            }\n            \n            function<void(int)> compute_depth = [&](int v) {\n                for (int c : children[v]) {\n                    depth[c] = depth[v] + 1;\n                    compute_depth(c);\n                }\n            };\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) {\n                    compute_depth(v);\n                }\n            }\n            \n            // Compute subtree info\n            vector<int> subtree_sum(N, 0);\n            vector<int> max_depth(N, 0);\n            \n            function<void(int)> dfs = [&](int v) {\n                subtree_sum[v] = A[v];\n                max_depth[v] = 0;\n                for (int c : children[v]) {\n                    dfs(c);\n                    subtree_sum[v] += subtree_sum[c];\n                    max_depth[v] = max(max_depth[v], max_depth[c] + 1);\n                }\n            };\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) {\n                    dfs(v);\n                }\n            }\n            \n            bool changed = false;\n            \n            // Only try moving subtrees to neighbors - safe operation\n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) continue;\n                \n                int best_u = -1;\n                long long best_gain = 0;\n                \n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    \n                    // Check if u is already in v's subtree (would create cycle)\n                    bool in_subtree = false;\n                    function<void(int)> check_cycle = [&](int x) {\n                        if (x == u) { in_subtree = true; return; }\n                        for (int c : children[x]) check_cycle(c);\n                    };\n                    check_cycle(v);\n                    if (in_subtree) continue;\n                    \n                    // Compute depth of u\n                    int depth_u = 0;\n                    int cur = u;\n                    while (parent[cur] != -1) {\n                        depth_u++;\n                        cur = parent[cur];\n                    }\n                    \n                    int new_depth = depth_u + 1;\n                    if (new_depth > H) continue;\n                    if (new_depth + max_depth[v] > H) continue;\n                    \n                    int delta = new_depth - depth[v];\n                    if (delta <= 0) continue;\n                    \n                    long long gain = (long long)delta * subtree_sum[v];\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_u = u;\n                    }\n                }\n                \n                if (best_u != -1) {\n                    // Perform the move\n                    int old_parent = parent[v];\n                    \n                    // Update children list\n                    auto& old_children = children[old_parent];\n                    old_children.erase(remove(old_children.begin(), old_children.end(), v), old_children.end());\n                    children[best_u].push_back(v);\n                    \n                    // Update parent\n                    parent[v] = best_u;\n                    \n                    // Update depths\n                    int delta = (depth[best_u] + 1) - depth[v];\n                    function<void(int)> update_depths = [&](int x) {\n                        depth[x] += delta;\n                        for (int c : children[x]) update_depths(c);\n                    };\n                    update_depths(v);\n                    \n                    changed = true;\n                    break; // Restart with updated state\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n\n    long long compute_score(const vector<int>& parent) {\n        vector<int> depth(N, 0);\n        vector<vector<int>> children(N);\n        \n        for (int v = 0; v < N; ++v) {\n            if (parent[v] != -1) {\n                children[parent[v]].push_back(v);\n            }\n        }\n        \n        function<void(int)> compute_depth = [&](int v) {\n            for (int c : children[v]) {\n                depth[c] = depth[v] + 1;\n                compute_depth(c);\n            }\n        };\n        \n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                compute_depth(v);\n            }\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; ++v) {\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver solver;\n    solver.read_input();\n    vector<int> result = solver.solve();\n\n    for (int i = 0; i < (int)result.size(); ++i) {\n        if (i > 0) cout << ' ';\n        cout << result[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>> operations;\n    const int MAX_OPERATIONS = 4 * N * N;\n\n    while (operations.size() < MAX_OPERATIONS) {\n        bool hasOni = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    hasOni = true;\n                    break;\n                }\n            }\n            if (hasOni) break;\n        }\n        if (!hasOni) break;\n\n        bool removed = false;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == 'x') {\n                operations.push_back({'L', i});\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[i][N-1] == 'x') {\n                operations.push_back({'R', i});\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == 'x') {\n                operations.push_back({'U', j});\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[N-1][j] == 'x') {\n                operations.push_back({'D', j});\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        int best_dist = 1000000;\n        char best_dir = 0;\n        int best_index = -1;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == '.') {\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        if (j < best_dist) {\n                            best_dist = j;\n                            best_dir = 'L';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][N-1] == '.') {\n                for (int j = N-1; j >= 0; j--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - j;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'R';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == '.') {\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        if (i < best_dist) {\n                            best_dist = i;\n                            best_dir = 'U';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[N-1][j] == '.') {\n                for (int i = N-1; i >= 0; i--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - i;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'D';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (best_index != -1) {\n            operations.push_back({best_dir, best_index});\n            if (best_dir == 'L') {\n                int i = best_index;\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n            } else if (best_dir == 'R') {\n                int i = best_index;\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n            } else if (best_dir == 'U') {\n                int j = best_index;\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n            } else if (best_dir == 'D') {\n                int j = best_index;\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n            }\n        } else {\n            break;\n        }\n    }\n\n    for (auto op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int N, L;\n    cin >> N >> L;\n    int T[100];\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    for (int i = 0; i < N; i++) {\n        int a = (i + 1) % N;\n        int b = (i + 2) % N;\n        cout << a << \" \" << b << endl;\n    }\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\n// Global variables for input and query counting\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> cx, cy;   // center coordinates\nint queries_used = 0;\n\n// Perform a query on a set of cities and return the MST edges\nvector<pair<int, int>> do_query(vector<int> cities) {\n    sort(cities.begin(), cities.end());\n    cout << \"? \" << cities.size();\n    for (int c : cities) {\n        cout << \" \" << c;\n    }\n    cout << endl;\n    vector<pair<int, int>> edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.push_back(make_pair(a, b));\n    }\n    queries_used++;\n    return edges;\n}\n\n// Recursively build a spanning tree for a set of cities (already sorted by center)\nvector<pair<int, int>> build_tree(vector<int> cities) {\n    int n = cities.size();\n    if (n == 1) {\n        return {};\n    }\n    if (n == 2) {\n        return {make_pair(cities[0], cities[1])};\n    }\n    if (n <= L) {\n        if (n >= 3 && queries_used < Q) {\n            return do_query(cities);\n        } else {\n            // Fallback: connect in a chain\n            vector<pair<int, int>> edges;\n            for (int i = 0; i < n - 1; i++) {\n                edges.push_back(make_pair(cities[i], cities[i + 1]));\n            }\n            return edges;\n        }\n    } else {\n        // Split into two halves\n        int mid = n / 2;\n        vector<int> A(cities.begin(), cities.begin() + mid);\n        vector<int> B(cities.begin() + mid, cities.end());\n\n        // Ensure both halves have at least 2 cities\n        if (A.size() < 2) {\n            A.push_back(B[0]);\n            B.erase(B.begin());\n        }\n        if (B.size() < 2) {\n            B.push_back(A.back());\n            A.pop_back();\n        }\n\n        // Build trees for both halves\n        vector<pair<int, int>> treeA = build_tree(A);\n        vector<pair<int, int>> treeB = build_tree(B);\n\n        // Connect the two halves\n        vector<pair<int, int>> edges_connect;\n        if (queries_used < Q) {\n            // Choose a set S of size L from the boundary\n            int k = min((int)A.size(), L / 2);\n            int l = L - k;\n            if (l > (int)B.size()) {\n                l = B.size();\n                k = L - l;\n            }\n            vector<int> S;\n            // Add last k cities from A\n            for (int i = A.size() - k; i < A.size(); i++) {\n                S.push_back(A[i]);\n            }\n            // Add first l cities from B\n            for (int i = 0; i < l; i++) {\n                S.push_back(B[i]);\n            }\n            vector<pair<int, int>> edges_S = do_query(S);\n            // Find the first edge that connects A and B\n            set<int> setA(A.begin(), A.end());\n            set<int> setB(B.begin(), B.end());\n            pair<int, int> connect_edge = make_pair(-1, -1);\n            for (auto& e : edges_S) {\n                int u = e.first, v = e.second;\n                if ((setA.count(u) && setB.count(v)) || (setA.count(v) && setB.count(u))) {\n                    connect_edge = e;\n                    break;\n                }\n            }\n            if (connect_edge.first == -1) {\n                // Fallback: connect the last of A and first of B\n                connect_edge = make_pair(A.back(), B[0]);\n            }\n            edges_connect.push_back(connect_edge);\n        } else {\n            // No queries left: use a direct edge between the two halves\n            edges_connect.push_back(make_pair(A.back(), B[0]));\n        }\n\n        // Combine all edges\n        vector<pair<int, int>> result;\n        result.reserve(treeA.size() + treeB.size() + edges_connect.size());\n        result.insert(result.end(), treeA.begin(), treeA.end());\n        result.insert(result.end(), treeB.begin(), treeB.end());\n        result.insert(result.end(), edges_connect.begin(), edges_connect.end());\n        return result;\n    }\n}\n\nint main() {\n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> G[i];\n    }\n    cx.resize(N);\n    cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        cx[i] = (lx + rx) / 2;\n        cy[i] = (ly + ry) / 2;\n    }\n\n    // Sort cities by center\n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        if (cx[i] != cx[j]) return cx[i] < cx[j];\n        return cy[i] < cy[j];\n    });\n\n    // Split into groups according to G\n    vector<vector<int>> groups(M);\n    int start = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i] = vector<int>(indices.begin() + start, indices.begin() + start + G[i]);\n        start += G[i];\n    }\n\n    // Build spanning trees for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    for (int i = 0; i < M; i++) {\n        group_edges[i] = build_tree(groups[i]);\n    }\n\n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        // Output cities of the group\n        for (int j = 0; j < groups[i].size(); j++) {\n            if (j) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        // Output edges of the spanning tree\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nbool can_slide(int r, int c, int tr, int tc, const vector<vector<bool>>& block, int N) {\n    if (r == tr) {\n        if (c < tc) {\n            for (int j = c+1; j <= tc; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc+1 < N) {\n                if (!block[r][tc+1]) return false;\n            }\n            return true;\n        } else if (c > tc) {\n            for (int j = tc; j < c; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc-1 >= 0) {\n                if (!block[r][tc-1]) return false;\n            }\n            return true;\n        }\n    } else if (c == tc) {\n        if (r < tr) {\n            for (int i = r+1; i <= tr; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr+1 < N) {\n                if (!block[tr+1][c]) return false;\n            }\n            return true;\n        } else if (r > tr) {\n            for (int i = tr; i < r; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr-1 >= 0) {\n                if (!block[tr-1][c]) return false;\n            }\n            return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.push_back({r, c});\n    }\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    int r = r0, c = c0;\n    vector<string> actions;\n\n    for (int idx = 0; idx < M; idx++) {\n        int tr = targets[idx].first;\n        int tc = targets[idx].second;\n\n        while (r != tr || c != tc) {\n            // Check if we can use a direct slide\n            if (can_slide(r, c, tr, tc, block, N)) {\n                if (r == tr) {\n                    if (c < tc) {\n                        actions.push_back(\"S R\");\n                        c = tc;\n                    } else {\n                        actions.push_back(\"S L\");\n                        c = tc;\n                    }\n                } else if (c == tc) {\n                    if (r < tr) {\n                        actions.push_back(\"S D\");\n                        r = tr;\n                    } else {\n                        actions.push_back(\"S U\");\n                        r = tr;\n                    }\n                }\n                continue;\n            }\n\n            int cost_manhattan = abs(r - tr) + abs(c - tc);\n            int best_cost = cost_manhattan;\n            vector<string> best_actions;\n\n            // Check boundary approaches only for corner targets and when not aligned\n            if (tr == 0 && tc == 0 && r > 0 && c > 0) {\n                int cost = r + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < r; i++) best_actions.push_back(\"M U\");\n                    best_actions.push_back(\"S L\");\n                }\n            } else if (tr == 0 && tc == N-1 && r > 0 && c < N-1) {\n                int cost = r + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < r; i++) best_actions.push_back(\"M U\");\n                    best_actions.push_back(\"S R\");\n                }\n            } else if (tr == N-1 && tc == 0 && r < N-1 && c > 0) {\n                int cost = (N-1 - r) + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < N-1 - r; i++) best_actions.push_back(\"M D\");\n                    best_actions.push_back(\"S L\");\n                }\n            } else if (tr == N-1 && tc == N-1 && r < N-1 && c < N-1) {\n                int cost = (N-1 - r) + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < N-1 - r; i++) best_actions.push_back(\"M D\");\n                    best_actions.push_back(\"S R\");\n                }\n            }\n\n            if (best_cost < cost_manhattan) {\n                for (const string& action : best_actions) {\n                    actions.push_back(action);\n                    if (action == \"M U\") r--;\n                    else if (action == \"M D\") r++;\n                    else if (action == \"M L\") c--;\n                    else if (action == \"M R\") c++;\n                    else if (action == \"S R\") c = tc;\n                    else if (action == \"S L\") c = tc;\n                    else if (action == \"S U\") r = tr;\n                    else if (action == \"S D\") r = tr;\n                }\n                continue;\n            }\n\n            // Step-by-step moves\n            int dr = tr - r;\n            int dc = tc - c;\n            int adr = abs(dr);\n            int adc = abs(dc);\n\n            if (adr > adc) {\n                if (dr > 0) {\n                    actions.push_back(\"M D\");\n                    r++;\n                } else {\n                    actions.push_back(\"M U\");\n                    r--;\n                }\n            } else if (adc > adr) {\n                if (dc > 0) {\n                    actions.push_back(\"M R\");\n                    c++;\n                } else {\n                    actions.push_back(\"M L\");\n                    c--;\n                }\n            } else {\n                if (tr == N-1 || tr == 0) {\n                    if (dr > 0) {\n                        actions.push_back(\"M D\");\n                        r++;\n                    } else if (dr < 0) {\n                        actions.push_back(\"M U\");\n                        r--;\n                    } else {\n                        if (dc > 0) {\n                            actions.push_back(\"M R\");\n                            c++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            c--;\n                        }\n                    }\n                } else if (tc == N-1 || tc == 0) {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else if (dc < 0) {\n                        actions.push_back(\"M L\");\n                        c--;\n                    } else {\n                        if (dr > 0) {\n                            actions.push_back(\"M D\");\n                            r++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            r--;\n                        }\n                    }\n                } else {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        c--;\n                    }\n                }\n            }\n        }\n    }\n\n    for (const string& action : actions) {\n        cout << action << endl;\n    }\n\n    return 0;\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n;\n    cin >> n;\n\n    vector<Company> companies(n);\n    for (int i = 0; i < n; i++) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n\n    // Sort by desired area descending, then by minimum distance to boundaries ascending\n    sort(companies.begin(), companies.end(), [](const Company& a, const Company& b) {\n        if (a.r != b.r) return a.r > b.r;\n        int da = min({a.x, a.y, 9999 - a.x, 9999 - a.y});\n        int db = min({b.x, b.y, 9999 - b.x, 9999 - b.y});\n        return da < db;\n    });\n\n    vector<Rect> assigned_rects;\n\n    for (int i = 0; i < n; i++) {\n        int L = companies[i].x;\n        int R = companies[i].x + 1;\n        int T = companies[i].y;\n        int B = companies[i].y + 1;\n\n        auto conflict_strip = [&](int x1, int x2, int y1, int y2) -> bool {\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                int xj = companies[j].x;\n                int yj = companies[j].y;\n                if (x1 <= xj && xj < x2 && y1 <= yj && yj < y2) {\n                    return true;\n                }\n            }\n            for (const auto& rect : assigned_rects) {\n                if (x1 < rect.c && rect.a < x2 && y1 < rect.d && rect.b < y2) {\n                    return true;\n                }\n            }\n            return false;\n        };\n\n        bool expanded = true;\n        while (expanded) {\n            expanded = false;\n            if (L > 0 && !conflict_strip(L-1, L, T, B)) {\n                L--;\n                expanded = true;\n            }\n            if (R < 10000 && !conflict_strip(R, R+1, T, B)) {\n                R++;\n                expanded = true;\n            }\n            if (T > 0 && !conflict_strip(L, R, T-1, T)) {\n                T--;\n                expanded = true;\n            }\n            if (B < 10000 && !conflict_strip(L, R, B, B+1)) {\n                B++;\n                expanded = true;\n            }\n        }\n\n        int max_w = R - L;\n        int max_h = B - T;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - companies[i].r);\n\n        // For very small areas, ensure we consider the minimum possible area\n        if (companies[i].r == 1) {\n            best_w = 1;\n            best_h = 1;\n        } else {\n            for (int w = 1; w <= max_w; w++) {\n                int left_min = max(L, companies[i].x - w + 1);\n                int left_max = min(companies[i].x, R - w);\n                if (left_min > left_max) continue;\n\n                int h0 = companies[i].r / w;\n                int h1 = (companies[i].r + w - 1) / w;\n                // Check a range of heights around the ideal values\n                vector<int> candidates;\n                for (int h = max(1, h0 - 2); h <= min(max_h, h0 + 2); h++) candidates.push_back(h);\n                for (int h = max(1, h1 - 2); h <= min(max_h, h1 + 2); h++) candidates.push_back(h);\n                sort(candidates.begin(), candidates.end());\n                candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n\n                for (int h : candidates) {\n                    if (h < 1 || h > max_h) continue;\n                    int top_min = max(T, companies[i].y - h + 1);\n                    int top_max = min(companies[i].y, B - h);\n                    if (top_min > top_max) continue;\n\n                    int area = w * h;\n                    int diff = abs(area - companies[i].r);\n                    if (diff < best_diff) {\n                        best_diff = diff;\n                        best_w = w;\n                        best_h = h;\n                    }\n                }\n            }\n        }\n\n        int left = max(L, companies[i].x - best_w + 1);\n        int top = max(T, companies[i].y - best_h + 1);\n        cout << left << \" \" << top << \" \" << left + best_w << \" \" << top + best_h << \"\\n\";\n\n        assigned_rects.push_back({left, top, left+best_w, top+best_h});\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <queue>\n#include <unordered_map>\n#include <cmath>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nstruct Candidate {\n    int score;\n    int ni;\n    int nj;\n    int tid;\n    double heuristic;\n    int depth;\n};\n\nint main() {\n    int si, sj;\n    cin >> si >> sj;\n    vector<vector<int>> t(50, vector<int>(50));\n    vector<vector<int>> p(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[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        }\n    }\n    \n    set<int> visitedTiles;\n    visitedTiles.insert(t[si][sj]);\n    \n    int i = si, j = sj;\n    string path = \"\";\n    int steps = 0;\n    int tiles_visited = 1;\n    \n    // Enhanced precomputation\n    vector<int> tileMax(3000, 0);\n    vector<int> tileSum(3000, 0);\n    vector<int> tileCount(3000, 0);\n    vector<vector<int>> tilePositions(3000);\n    vector<set<int>> tileNeighbors(3000);\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            int tid = t[i][j];\n            tileMax[tid] = max(tileMax[tid], p[i][j]);\n            tileSum[tid] += p[i][j];\n            tileCount[tid]++;\n            tilePositions[tid].push_back(i * 50 + j);\n        }\n    }\n    \n    // Precompute tile neighbors (both direct and diagonal)\n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            int tid = t[i][j];\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 < 50 && nj >= 0 && nj < 50) {\n                    int ntid = t[ni][nj];\n                    if (ntid != tid) {\n                        tileNeighbors[tid].insert(ntid);\n                    }\n                }\n            }\n            // Add diagonal neighbors for better connectivity estimation\n            for (int di = -1; di <= 1; di++) {\n                for (int dj = -1; dj <= 1; dj++) {\n                    if (di == 0 && dj == 0) continue;\n                    int ni = i + di;\n                    int nj = j + dj;\n                    if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                        int ntid = t[ni][nj];\n                        if (ntid != tid) {\n                            tileNeighbors[tid].insert(ntid);\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Calculate global tile density\n    vector<double> tileDensity(3000, 0.0);\n    for (int tid = 0; tid < 3000; tid++) {\n        if (tileCount[tid] == 0) continue;\n        double sum = 0;\n        int count = 0;\n        for (int pos : tilePositions[tid]) {\n            int x = pos / 50;\n            int y = pos % 50;\n            for (int di = -2; di <= 2; di++) {\n                for (int dj = -2; dj <= 2; dj++) {\n                    int ni = x + di;\n                    int nj = y + dj;\n                    if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                        sum += p[ni][nj];\n                        count++;\n                    }\n                }\n            }\n        }\n        tileDensity[tid] = (count > 0) ? sum / count : 0;\n    }\n    \n    while (true) {\n        vector<Candidate> candidates;\n        \n        // Collect all valid moves\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 >= 50 || nj < 0 || nj >= 50) continue;\n            int tid = t[ni][nj];\n            if (visitedTiles.find(tid) != visitedTiles.end()) continue;\n            \n            // Enhanced heuristic with multiple factors\n            double immediate = p[ni][nj];\n            double tile_potential = tileMax[tid] * 0.5 + (tileSum[tid] / (double)tileCount[tid]) * 0.3;\n            double local_density = tileDensity[tid];\n            \n            // Connectivity: number of unvisited neighbor tiles and their potential\n            int unvisited_neighbors = 0;\n            double neighbor_potential = 0;\n            for (int ntid : tileNeighbors[tid]) {\n                if (visitedTiles.find(ntid) == visitedTiles.end()) {\n                    unvisited_neighbors++;\n                    neighbor_potential += tileMax[ntid] * 0.1;\n                }\n            }\n            \n            // Distance from start (to avoid getting too far from high-value areas)\n            double distance_from_start = sqrt((ni - si) * (ni - si) + (nj - sj) * (nj - sj)) * 0.01;\n            \n            // Dynamic weight based on progress and remaining tiles\n            double progress = (double)tiles_visited / 100.0;\n            double weight = max(0.15, 0.6 - progress * 0.3);\n            \n            double heuristic = immediate + \n                             weight * tile_potential + \n                             (0.2 + progress * 0.05) * local_density +\n                             0.08 * unvisited_neighbors +\n                             0.05 * neighbor_potential -\n                             distance_from_start;\n            \n            candidates.push_back({p[ni][nj], ni, nj, tid, heuristic, 0});\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort candidates by heuristic\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            return a.heuristic > b.heuristic;\n        });\n        \n        // Adaptive candidate selection based on path length\n        int keep = min(12, (int)candidates.size());\n        if (steps < 10) keep = min(8, keep);\n        if (steps > 50) keep = min(6, keep);\n        \n        int best_ni = -1, best_nj = -1;\n        double best_score = -1;\n        \n        // Dynamic discount factors\n        double base_discount = max(0.2, 0.8 - steps * 0.005 - tiles_visited * 0.001);\n        double discount1 = base_discount;\n        double discount2 = base_discount * 0.7;\n        double discount3 = base_discount * 0.5;\n        \n        // Lookahead with variable depth\n        for (int idx = 0; idx < keep; idx++) {\n            auto& cand = candidates[idx];\n            set<int> temp_visited = visitedTiles;\n            temp_visited.insert(cand.tid);\n            \n            double total_score = cand.score;\n            \n            // First lookahead step (second move)\n            for (int d1 = 0; d1 < 4; d1++) {\n                int ni1 = cand.ni + dx[d1];\n                int nj1 = cand.nj + dy[d1];\n                if (ni1 < 0 || ni1 >= 50 || nj1 < 0 || nj1 >= 50) continue;\n                if (ni1 == i && nj1 == j) continue;\n                int tid1 = t[ni1][nj1];\n                if (temp_visited.find(tid1) != temp_visited.end()) continue;\n                \n                int score1 = p[ni1][nj1];\n                set<int> temp_visited2 = temp_visited;\n                temp_visited2.insert(tid1);\n                \n                int best_score2 = 0;\n                // Second lookahead step (third move)\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int ni2 = ni1 + dx[d2];\n                    int nj2 = nj1 + dy[d2];\n                    if (ni2 < 0 || ni2 >= 50 || nj2 < 0 || nj2 >= 50) continue;\n                    if (ni2 == cand.ni && nj2 == cand.nj) continue;\n                    int tid2 = t[ni2][nj2];\n                    if (temp_visited2.find(tid2) != temp_visited2.end()) continue;\n                    \n                    int score2 = p[ni2][nj2];\n                    double future_value = tileMax[tid2] * 0.15 + (tileSum[tid2]/(double)tileCount[tid2]) * 0.1;\n                    int adjusted_score2 = score2 + future_value;\n                    \n                    // Consider third move potential\n                    int best_score3 = 0;\n                    for (int d3 = 0; d3 < 4; d3++) {\n                        int ni3 = ni2 + dx[d3];\n                        int nj3 = nj2 + dy[d3];\n                        if (ni3 < 0 || ni3 >= 50 || nj3 < 0 || nj3 >= 50) continue;\n                        if (ni3 == ni1 && nj3 == nj1) continue;\n                        int tid3 = t[ni3][nj3];\n                        if (temp_visited2.find(tid3) != temp_visited2.end()) continue;\n                        \n                        int score3 = p[ni3][nj3];\n                        if (score3 > best_score3) best_score3 = score3;\n                    }\n                    \n                    adjusted_score2 += best_score3 * discount3;\n                    \n                    if (adjusted_score2 > best_score2) best_score2 = adjusted_score2;\n                }\n                \n                total_score += score1 * discount1 + best_score2 * discount2;\n            }\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_ni = cand.ni;\n                best_nj = cand.nj;\n            }\n        }\n        \n        // Fallback to best immediate candidate if lookahead failed\n        if (best_ni == -1) {\n            best_ni = candidates[0].ni;\n            best_nj = candidates[0].nj;\n        }\n        \n        // Convert to direction\n        int di = best_ni - i;\n        int dj = best_nj - j;\n        if (di == -1) path += 'U';\n        else if (di == 1) path += 'D';\n        else if (dj == -1) path += 'L';\n        else if (dj == 1) path += 'R';\n        \n        visitedTiles.insert(t[best_ni][best_nj]);\n        i = best_ni;\n        j = best_nj;\n        steps++;\n        tiles_visited++;\n    }\n    \n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <string>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nconst double low_bound = 1000.0;\nconst double high_bound = 9000.0;\n\ndouble H_est[30][29];\ndouble V_est[29][30];\nint H_count[30][29];\nint V_count[29][30];\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\ndouble get_edge_weight(int i, int j, int ni, int nj) {\n    if (ni == i-1 && nj == j) return V_est[i-1][j];\n    if (ni == i+1 && nj == j) return V_est[i][j];\n    if (ni == i && nj == j-1) return H_est[i][j-1];\n    if (ni == i && nj == j+1) return H_est[i][j];\n    return 1e18;\n}\n\nvoid update_edge(int i, int j, int ni, int nj, double delta) {\n    if (ni == i-1 && nj == j) {\n        V_est[i-1][j] += delta;\n        V_est[i-1][j] = max(low_bound, min(high_bound, V_est[i-1][j]));\n        V_count[i-1][j]++;\n    } else if (ni == i+1 && nj == j) {\n        V_est[i][j] += delta;\n        V_est[i][j] = max(low_bound, min(high_bound, V_est[i][j]));\n        V_count[i][j]++;\n    } else if (ni == i && nj == j-1) {\n        H_est[i][j-1] += delta;\n        H_est[i][j-1] = max(low_bound, min(high_bound, H_est[i][j-1]));\n        H_count[i][j-1]++;\n    } else if (ni == i && nj == j+1) {\n        H_est[i][j] += delta;\n        H_est[i][j] = max(low_bound, min(high_bound, H_est[i][j]));\n        H_count[i][j]++;\n    }\n}\n\nstring dijkstra_heuristic(int si, int sj, int ti, int tj, double &est_length, int query_idx) {\n    vector<vector<double>> dist(30, vector<double>(30, 1e18));\n    vector<vector<pair<int, int>>> parent(30, vector<pair<int, int>>(30, {-1, -1}));\n    \n    auto manhattan = [](int i, int j, int ti, int tj) {\n        return abs(i - ti) + abs(j - tj);\n    };\n    \n    priority_queue<tuple<double, double, int, int>, \n                   vector<tuple<double, double, int, int>>, \n                   greater<tuple<double, double, int, int>>> pq;\n    \n    dist[si][sj] = 0.0;\n    pq.push(make_tuple(0.0, manhattan(si, sj, ti, tj), si, sj));\n\n    while (!pq.empty()) {\n        auto [d, h, i, j] = pq.top();\n        pq.pop();\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n            \n            double w = get_edge_weight(i, j, ni, nj);\n            \n            // Add small exploration for early queries on less-traversed edges\n            int edge_count = 0;\n            if (ni == i-1) edge_count = V_count[ni][nj];\n            else if (ni == i+1) edge_count = V_count[i][nj];\n            else if (nj == j-1) edge_count = H_count[i][nj];\n            else if (nj == j+1) edge_count = H_count[i][j];\n            \n            double exploration = (query_idx < 100 && edge_count < 2) ? 100.0 : 0.0;\n            double adjusted_weight = w + exploration;\n            \n            if (dist[ni][nj] > dist[i][j] + adjusted_weight) {\n                dist[ni][nj] = dist[i][j] + adjusted_weight;\n                parent[ni][nj] = make_pair(i, j);\n                pq.push(make_tuple(dist[ni][nj], manhattan(ni, nj, ti, tj), ni, nj));\n            }\n        }\n    }\n\n    vector<pair<int, int>> path_nodes;\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        path_nodes.push_back({i, j});\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    path_nodes.push_back({si, sj});\n    reverse(path_nodes.begin(), path_nodes.end());\n\n    string path_str = \"\";\n    est_length = 0.0;\n    for (int idx = 0; idx < path_nodes.size()-1; idx++) {\n        int i1 = path_nodes[idx].first;\n        int j1 = path_nodes[idx].second;\n        int i2 = path_nodes[idx+1].first;\n        int j2 = path_nodes[idx+1].second;\n        char move;\n        if (i2 == i1-1) move = 'U';\n        else if (i2 == i1+1) move = 'D';\n        else if (j2 == j1-1) move = 'L';\n        else if (j2 == j1+1) move = 'R';\n        path_str += move;\n        est_length += get_edge_weight(i1, j1, i2, j2);\n    }\n\n    return path_str;\n}\n\nint main() {\n    // Initialize\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 29; j++) {\n            H_est[i][j] = 5000.0;\n            H_count[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 30; j++) {\n            V_est[i][j] = 5000.0;\n            V_count[i][j] = 0;\n        }\n    }\n\n    int si, sj, ti, tj;\n    for (int k = 0; k < 1000; k++) {\n        cin >> si >> sj >> ti >> tj;\n        \n        double est_length;\n        string path = dijkstra_heuristic(si, sj, ti, tj, est_length, k);\n        cout << path << endl;\n        cout.flush();\n\n        long long F;\n        cin >> F;\n\n        int n = path.size();\n        if (n == 0) continue;\n\n        double error = static_cast<double>(F) - est_length;\n        \n        // Adaptive learning rate based on error magnitude and query index\n        double base_alpha = 0.25;\n        if (k < 100) base_alpha = 0.35;\n        else if (k < 300) base_alpha = 0.25;\n        else if (k < 600) base_alpha = 0.15;\n        else base_alpha = 0.08;\n        \n        // Further adjust based on error magnitude (more aggressive for larger errors)\n        double error_factor = min(2.0, 1.0 + abs(error) / 10000.0);\n        base_alpha *= error_factor;\n        \n        // Clamp base_alpha\n        base_alpha = max(0.03, min(0.4, base_alpha));\n        \n        int cur_i = si, cur_j = sj;\n        for (char move : path) {\n            int next_i = cur_i, next_j = cur_j;\n            if (move == 'U') next_i--;\n            else if (move == 'D') next_i++;\n            else if (move == 'L') next_j--;\n            else if (move == 'R') next_j++;\n\n            int count = 0;\n            if (next_i == cur_i-1) count = V_count[cur_i-1][cur_j];\n            else if (next_i == cur_i+1) count = V_count[cur_i][cur_j];\n            else if (next_j == cur_j-1) count = H_count[cur_i][cur_j-1];\n            else if (next_j == cur_j+1) count = H_count[cur_i][cur_j];\n            \n            // Confidence-based update: less aggressive for well-measured edges\n            double confidence_factor = 1.0 / (1.0 + 0.1 * count);\n            \n            // Weight by edge contribution to path\n            double edge_weight = get_edge_weight(cur_i, cur_j, next_i, next_j);\n            double weight_factor = edge_weight / est_length;\n            \n            double delta = (error * weight_factor) * base_alpha * confidence_factor;\n            \n            update_edge(cur_i, cur_j, next_i, next_j, delta);\n\n            cur_i = next_i;\n            cur_j = next_j;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <map>\n#include <set>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct StringInfo {\n    string s;\n    int len;\n    double weight;\n    set<char> unique_chars;\n};\n\nbool try_place_horizontal(vector<string>& mat, const string& str, int N) {\n    int L = str.size();\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 < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < L; ++p) {\n                    int col = (j + p) % N;\n                    mat[i][col] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool try_place_vertical(vector<string>& mat, const string& str, int N) {\n    int L = str.size();\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < L; ++p) {\n                    int row = (i + p) % N;\n                    mat[row][j] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Try to place with a specific character preference\nbool try_place_with_pref(vector<string>& mat, const string& str, int N, char pref) {\n    int L = str.size();\n    // Try horizontal\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool ok = true;\n            char chosen = '.';\n            for (int p = 0; p < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n                if (mat[i][col] == '.') {\n                    if (chosen == '.') chosen = str[p];\n                    else if (chosen != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok && chosen != '.' && chosen == pref) {\n                for (int p = 0; p < L; ++p) {\n                    int col = (j + p) % N;\n                    mat[i][col] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    // Try vertical\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            char chosen = '.';\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n                if (mat[row][j] == '.') {\n                    if (chosen == '.') chosen = str[p];\n                    else if (chosen != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok && chosen != '.' && chosen == pref) {\n                for (int p = 0; p < L; ++p) {\n                    int row = (i + p) % N;\n                    mat[row][j] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> raw_strings(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> raw_strings[i];\n    }\n    \n    // Analyze strings\n    vector<StringInfo> strings(M);\n    map<char, int> global_char_freq;\n    \n    for (int i = 0; i < M; ++i) {\n        strings[i].s = raw_strings[i];\n        strings[i].len = raw_strings[i].size();\n        \n        for (char c : raw_strings[i]) {\n            global_char_freq[c]++;\n            strings[i].unique_chars.insert(c);\n        }\n        \n        double rarity = 0;\n        for (char c : strings[i].unique_chars) {\n            rarity += 1.0 / (global_char_freq[c] + 1);\n        }\n        strings[i].weight = strings[i].len * 10 + rarity;\n    }\n    \n    // Find the most frequent character overall\n    char most_frequent = 'A';\n    int max_freq = -1;\n    for (auto& p : global_char_freq) {\n        if (p.second > max_freq) {\n            max_freq = p.second;\n            most_frequent = p.first;\n        }\n    }\n    \n    // Generate orders\n    vector<vector<int>> orders;\n    \n    // Order 1: Length descending\n    vector<int> o1(M);\n    iota(o1.begin(), o1.end(), 0);\n    sort(o1.begin(), o1.end(), [&](int a, int b) { return strings[a].len > strings[b].len; });\n    orders.push_back(o1);\n    \n    // Order 2: Weight descending\n    vector<int> o2(M);\n    iota(o2.begin(), o2.end(), 0);\n    sort(o2.begin(), o2.end(), [&](int a, int b) { return strings[a].weight > strings[b].weight; });\n    orders.push_back(o2);\n    \n    // Order 3: Length ascending\n    vector<int> o3(M);\n    iota(o3.begin(), o3.end(), 0);\n    sort(o3.begin(), o3.end(), [&](int a, int b) { return strings[a].len < strings[b].len; });\n    orders.push_back(o3);\n    \n    // Order 4: Random shuffle\n    vector<int> o4(M);\n    iota(o4.begin(), o4.end(), 0);\n    shuffle(o4.begin(), o4.end(), rng);\n    orders.push_back(o4);\n    \n    // Order 5: Rarity based\n    vector<int> o5(M);\n    iota(o5.begin(), o5.end(), 0);\n    sort(o5.begin(), o5.end(), [&](int a, int b) {\n        double ra = 0, rb = 0;\n        for (char c : strings[a].unique_chars) ra += 1.0 / (global_char_freq[c] + 1);\n        for (char c : strings[b].unique_chars) rb += 1.0 / (global_char_freq[c] + 1);\n        return ra > rb;\n    });\n    orders.push_back(o5);\n    \n    // Order 6: Unique characters ascending\n    vector<int> o6(M);\n    iota(o6.begin(), o6.end(), 0);\n    sort(o6.begin(), o6.end(), [&](int a, int b) {\n        return strings[a].unique_chars.size() < strings[b].unique_chars.size();\n    });\n    orders.push_back(o6);\n    \n    // Order 7: Mixed - length then rarity\n    vector<int> o7(M);\n    iota(o7.begin(), o7.end(), 0);\n    sort(o7.begin(), o7.end(), [&](int a, int b) {\n        if (strings[a].len != strings[b].len) {\n            return strings[a].len > strings[b].len;\n        }\n        double ra = 0, rb = 0;\n        for (char c : strings[a].unique_chars) ra += 1.0 / (global_char_freq[c] + 1);\n        for (char c : strings[b].unique_chars) rb += 1.0 / (global_char_freq[c] + 1);\n        return ra > rb;\n    });\n    orders.push_back(o7);\n    \n    // Order 8: Character frequency based (strings with most frequent chars first)\n    vector<int> o8(M);\n    iota(o8.begin(), o8.end(), 0);\n    sort(o8.begin(), o8.end(), [&](int a, int b) {\n        double fa = 0, fb = 0;\n        for (char c : strings[a].unique_chars) fa += global_char_freq[c];\n        for (char c : strings[b].unique_chars) fb += global_char_freq[c];\n        return fa > fb;\n    });\n    orders.push_back(o8);\n    \n    // Best result tracking\n    int best_c = -1;\n    int best_d = -1;\n    vector<string> best_mat;\n    \n    // Try each order\n    for (const auto& order : orders) {\n        vector<string> mat(N, string(N, '.'));\n        vector<bool> covered(M, false);\n        int c = 0;\n        \n        // First pass: try with preferred character\n        for (int idx : order) {\n            if (covered[idx]) continue;\n            const string& str = strings[idx].s;\n            if (try_place_with_pref(mat, str, N, most_frequent) || \n                try_place_horizontal(mat, str, N) || \n                try_place_vertical(mat, str, N)) {\n                covered[idx] = true;\n                c++;\n            }\n        }\n        \n        // Second pass: try uncovered strings with different strategies\n        vector<int> uncovered;\n        for (int i = 0; i < M; ++i) {\n            if (!covered[i]) uncovered.push_back(i);\n        }\n        \n        // Sort uncovered by length descending\n        sort(uncovered.begin(), uncovered.end(), [&](int a, int b) {\n            return strings[a].len > strings[b].len;\n        });\n        \n        // Try uncovered strings multiple times with different approaches\n        for (int attempt = 0; attempt < 2; ++attempt) {\n            vector<int> still_uncovered;\n            for (int idx : uncovered) {\n                if (covered[idx]) continue;\n                const string& str = strings[idx].s;\n                bool placed = false;\n                \n                if (attempt == 0) {\n                    placed = try_place_vertical(mat, str, N) || try_place_horizontal(mat, str, N);\n                } else {\n                    placed = try_place_horizontal(mat, str, N) || try_place_vertical(mat, str, N);\n                }\n                \n                if (placed) {\n                    covered[idx] = true;\n                    c++;\n                } else {\n                    still_uncovered.push_back(idx);\n                }\n            }\n            uncovered = still_uncovered;\n            if (uncovered.empty()) break;\n        }\n        \n        // Final attempt: try with character preference\n        for (int idx : uncovered) {\n            if (covered[idx]) continue;\n            const string& str = strings[idx].s;\n            if (try_place_with_pref(mat, str, N, most_frequent)) {\n                covered[idx] = true;\n                c++;\n            }\n        }\n        \n        // Count dots\n        int d = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (mat[i][j] == '.') d++;\n            }\n        }\n        \n        // Update best\n        if (c > best_c) {\n            best_c = c;\n            best_d = d;\n            best_mat = mat;\n        } else if (c == best_c) {\n            if (c < M) {\n                if (d < best_d) {\n                    best_d = d;\n                    best_mat = mat;\n                }\n            } else {\n                if (d > best_d) {\n                    best_d = d;\n                    best_mat = mat;\n                }\n            }\n        }\n    }\n    \n    // Output the best matrix\n    for (int i = 0; i < N; ++i) {\n        cout << best_mat[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ITER = 100000; // Safeguard against infinite loops\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    // Precompute horizontal and vertical segments\n    vector<vector<int>> hid(N, vector<int>(N, -1));\n    vector<vector<int>> vid(N, vector<int>(N, -1));\n    int totalH = 0, totalV = 0;\n\n    // Horizontal segments\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '#') continue;\n            if (j == 0 || grid[i][j-1] == '#') {\n                int k = j;\n                while (k < N && grid[i][k] != '#') {\n                    hid[i][k] = totalH;\n                    k++;\n                }\n                totalH++;\n            }\n        }\n    }\n\n    // Vertical segments\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][j] == '#') continue;\n            if (i == 0 || grid[i-1][j] == '#') {\n                int k = i;\n                while (k < N && grid[k][j] != '#') {\n                    vid[k][j] = totalV;\n                    k++;\n                }\n                totalV++;\n            }\n        }\n    }\n\n    vector<bool> uncoveredH(totalH, true);\n    vector<bool> uncoveredV(totalV, true);\n\n    // Cover start position's segments\n    int startH = hid[si][sj];\n    int startV = vid[si][sj];\n    if (startH != -1) uncoveredH[startH] = false;\n    if (startV != -1) uncoveredV[startV] = false;\n\n    int cur_i = si, cur_j = sj;\n    string route = \"\";\n\n    int iter = 0;\n    while (iter < MAX_ITER) {\n        // Check if all segments are covered\n        bool has_uncovered = false;\n        for (bool b : uncoveredH) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) for (bool b : uncoveredV) if (b) { has_uncovered = true; break; }\n        if (!has_uncovered) break;\n\n        // Run Dijkstra to find shortest paths\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1,-1}));\n        vector<vector<char>> move_dir(N, vector<char>(N, 0));\n        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;\n\n        dist[cur_i][cur_j] = 0;\n        pq.push({0, cur_i, cur_j});\n\n        while (!pq.empty()) {\n            auto [cost, i, j] = pq.top();\n            pq.pop();\n            if (cost != dist[i][j]) continue;\n            const int dx[4] = {-1, 1, 0, 0};\n            const int dy[4] = {0, 0, -1, 1};\n            const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n                if (grid[ni][nj] == '#') continue;\n                int ncost = cost + (grid[ni][nj] - '0');\n                if (ncost < dist[ni][nj]) {\n                    dist[ni][nj] = ncost;\n                    parent[ni][nj] = {i, j};\n                    move_dir[ni][nj] = dirs[d];\n                    pq.push({ncost, ni, nj});\n                }\n            }\n        }\n\n        // Select candidate: prioritize covering more uncovered segments\n        int best_i = -1, best_j = -1;\n        int best_gain = -1;\n        int best_cost = INF;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == '#' || dist[i][j] == INF) continue;\n                int gain = 0;\n                if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) gain++;\n                if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) gain++;\n                if (gain == 0) continue;\n                if (gain > best_gain || (gain == best_gain && dist[i][j] < best_cost)) {\n                    best_gain = gain;\n                    best_cost = dist[i][j];\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n\n        // If no candidate found, break (shouldn't happen but safe)\n        if (best_i == -1) break;\n\n        // Build path and update coverage\n        string path_moves = \"\";\n        int i = best_i, j = best_j;\n        while (i != cur_i || j != cur_j) {\n            char m = move_dir[i][j];\n            path_moves = m + path_moves;\n            if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) uncoveredH[hid[i][j]] = false;\n            if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) uncoveredV[vid[i][j]] = false;\n            auto [pi, pj] = parent[i][j];\n            i = pi;\n            j = pj;\n        }\n\n        route += path_moves;\n        cur_i = best_i;\n        cur_j = best_j;\n        iter++;\n    }\n\n    // Return to start\n    vector<vector<int>> dist_ret(N, vector<int>(N, INF));\n    vector<vector<pair<int,int>>> parent_ret(N, vector<pair<int,int>>(N, {-1,-1}));\n    vector<vector<char>> move_dir_ret(N, vector<char>(N, 0));\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq_ret;\n\n    dist_ret[cur_i][cur_j] = 0;\n    pq_ret.push({0, cur_i, cur_j});\n\n    while (!pq_ret.empty()) {\n        auto [cost, i, j] = pq_ret.top();\n        pq_ret.pop();\n        if (cost != dist_ret[i][j]) continue;\n        const int dx[4] = {-1, 1, 0, 0};\n        const int dy[4] = {0, 0, -1, 1};\n        const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n            if (grid[ni][nj] == '#') continue;\n            int ncost = cost + (grid[ni][nj] - '0');\n            if (ncost < dist_ret[ni][nj]) {\n                dist_ret[ni][nj] = ncost;\n                parent_ret[ni][nj] = {i, j};\n                move_dir_ret[ni][nj] = dirs[d];\n                pq_ret.push({ncost, ni, nj});\n            }\n        }\n    }\n\n    if (dist_ret[si][sj] == INF) {\n        // Should not happen as the grid is connected, but just in case\n        cerr << \"No path back to start!\" << endl;\n    } else {\n        string return_path = \"\";\n        int i = si, j = sj;\n        while (i != cur_i || j != cur_j) {\n            auto [pi, pj] = parent_ret[i][j];\n            char m = move_dir_ret[i][j];\n            return_path = m + return_path;\n            i = pi;\n            j = pj;\n        }\n        route += return_path;\n    }\n\n    cout << route << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <tuple>\n#include <random>\n\nusing namespace std;\n\nstruct Task {\n    int id;\n    vector<int> requirements;\n    vector<int> dependents;\n    int remaining_dependencies;\n    double total_requirement;\n    int depth_forward;\n};\n\nstruct SkillDistribution {\n    double mean;\n    double variance;\n    int count;\n    \n    SkillDistribution() : mean(0.0), variance(100.0), count(0) {}\n    \n    void update(double observed_value) {\n        count++;\n        double alpha = 1.0 / (1.0 + count);\n        mean = (1 - alpha) * mean + alpha * observed_value;\n        variance = (1 - alpha) * variance + alpha * pow(observed_value - mean, 2);\n        mean = max(0.0, mean);\n    }\n};\n\nstruct TeamMember {\n    vector<SkillDistribution> skills;\n    int tasks_completed;\n    \n    TeamMember(int k) : tasks_completed(0) {\n        skills.resize(k);\n    }\n};\n\nstruct AssignmentCandidate {\n    double score;\n    int member_idx;\n    int task_idx;\n    \n    bool operator<(const AssignmentCandidate& other) const {\n        return score > other.score;\n    }\n};\n\nclass TaskScheduler {\nprivate:\n    int N, M, K;\n    vector<Task> tasks;\n    vector<TeamMember> members;\n    vector<bool> task_completed;\n    vector<int> task_assigned_to;\n    vector<int> member_assigned_task;\n    vector<int> start_day;\n    mt19937 rng;\n    \npublic:\n    TaskScheduler(int n, int m, int k) : N(n), M(m), K(k), rng(42) {\n        tasks.resize(N);\n        task_completed.assign(N, false);\n        task_assigned_to.assign(N, -1);\n        member_assigned_task.assign(M, -1);\n        start_day.assign(N, -1);\n        \n        for (int i = 0; i < M; i++) {\n            members.emplace_back(K);\n        }\n    }\n    \n    void setTaskRequirements(int task_idx, const vector<int>& reqs) {\n        tasks[task_idx].id = task_idx;\n        tasks[task_idx].requirements = reqs;\n        tasks[task_idx].remaining_dependencies = 0;\n        \n        double total_req = 0.0;\n        for (int req : reqs) total_req += req;\n        tasks[task_idx].total_requirement = total_req;\n    }\n    \n    void addDependency(int u, int v) {\n        tasks[u].dependents.push_back(v);\n        tasks[v].remaining_dependencies++;\n    }\n    \n    void computeDepthForward() {\n        // Compute critical path depth forward (longest path to completion)\n        for (int i = N-1; i >= 0; i--) {\n            if (tasks[i].dependents.empty()) {\n                tasks[i].depth_forward = 0;\n            } else {\n                int max_depth = 0;\n                for (int dep : tasks[i].dependents) {\n                    max_depth = max(max_depth, tasks[dep].depth_forward);\n                }\n                tasks[i].depth_forward = 1 + max_depth;\n            }\n        }\n    }\n    \n    bool areDependenciesComplete(int task_idx) {\n        return tasks[task_idx].remaining_dependencies == 0;\n    }\n    \n    // Estimate time with uncertainty\n    double estimateTime(int member_idx, int task_idx, double& uncertainty) {\n        double gap = 0.0;\n        const auto& reqs = tasks[task_idx].requirements;\n        const auto& member_skills = members[member_idx].skills;\n        \n        for (int k = 0; k < K; k++) {\n            double skill_estimate = max(0.0, member_skills[k].mean);\n            if (reqs[k] > skill_estimate) {\n                gap += reqs[k] - skill_estimate;\n            }\n        }\n        \n        if (gap == 0.0) {\n            uncertainty = 0.0;\n            return 1.0;\n        }\n        \n        uncertainty = 0.0;\n        for (int k = 0; k < K; k++) {\n            if (reqs[k] > member_skills[k].mean) {\n                uncertainty += member_skills[k].variance;\n            }\n        }\n        uncertainty = sqrt(uncertainty);\n        \n        return 1.0 + gap + uncertainty * 0.1;\n    }\n    \n    void updateSkills(int member_idx, int task_idx, int time_taken) {\n        if (time_taken <= 1) {\n            members[member_idx].tasks_completed++;\n            return;\n        }\n        \n        double total_gap = time_taken - 1.0;\n        const auto& reqs = tasks[task_idx].requirements;\n        auto& member_skills = members[member_idx].skills;\n        \n        vector<double> gaps(K, 0.0);\n        double total_gap_calc = 0.0;\n        for (int k = 0; k < K; k++) {\n            double skill_estimate = member_skills[k].mean;\n            if (reqs[k] > skill_estimate) {\n                gaps[k] = reqs[k] - skill_estimate;\n                total_gap_calc += gaps[k];\n            }\n        }\n        \n        if (total_gap_calc > 0) {\n            for (int k = 0; k < K; k++) {\n                if (gaps[k] > 0) {\n                    double observed_deficit = (gaps[k] / total_gap_calc) * total_gap;\n                    member_skills[k].update(observed_deficit);\n                    member_skills[k].mean = min(member_skills[k].mean, (double)reqs[k]);\n                }\n            }\n        }\n        \n        members[member_idx].tasks_completed++;\n    }\n    \n    void processCompletions(int current_day, const vector<int>& completed_members) {\n        for (int member_idx : completed_members) {\n            int task_idx = member_assigned_task[member_idx];\n            if (task_idx == -1) continue;\n            \n            int time_taken = current_day - start_day[task_idx] + 1;\n            updateSkills(member_idx, task_idx, time_taken);\n            \n            task_completed[task_idx] = true;\n            task_assigned_to[task_idx] = -1;\n            member_assigned_task[member_idx] = -1;\n            \n            for (int dependent : tasks[task_idx].dependents) {\n                tasks[dependent].remaining_dependencies--;\n            }\n        }\n    }\n    \n    vector<pair<int, int>> getAssignments(int current_day) {\n        vector<int> free_members;\n        for (int i = 0; i < M; i++) {\n            if (member_assigned_task[i] == -1) {\n                free_members.push_back(i);\n            }\n        }\n        \n        vector<int> available_tasks;\n        for (int i = 0; i < N; i++) {\n            if (!task_completed[i] && task_assigned_to[i] == -1 && areDependenciesComplete(i)) {\n                available_tasks.push_back(i);\n            }\n        }\n        \n        if (available_tasks.empty() || free_members.empty()) {\n            return {};\n        }\n        \n        vector<AssignmentCandidate> candidates;\n        \n        for (int task_idx : available_tasks) {\n            for (int member_idx : free_members) {\n                double uncertainty;\n                double time_est = estimateTime(member_idx, task_idx, uncertainty);\n                \n                // Multi-factor scoring:\n                // 1. Time efficiency: 1000/(time+1)\n                // 2. Criticality bonus: depth * 50\n                // 3. Exploration: -uncertainty * 0.5 (encourages learning)\n                // 4. Experience bonus: +tasks_completed * 10\n                double score = 1000.0 / (time_est + 1.0) + \n                               tasks[task_idx].depth_forward * 50.0 - \n                               uncertainty * 0.5 + \n                               members[member_idx].tasks_completed * 10.0;\n                \n                // Add tiny random component to break ties\n                score += (rng() % 1000) * 0.001;\n                \n                candidates.push_back({score, member_idx, task_idx});\n            }\n        }\n        \n        sort(candidates.begin(), candidates.end());\n        \n        vector<pair<int, int>> assignments;\n        vector<bool> member_used(M, false);\n        vector<bool> task_used(N, false);\n        \n        for (const auto& cand : candidates) {\n            if (member_used[cand.member_idx] || task_used[cand.task_idx]) continue;\n            \n            assignments.emplace_back(cand.member_idx, cand.task_idx);\n            member_used[cand.member_idx] = true;\n            task_used[cand.task_idx] = true;\n            \n            member_assigned_task[cand.member_idx] = cand.task_idx;\n            task_assigned_to[cand.task_idx] = cand.member_idx;\n            start_day[cand.task_idx] = -1;\n        }\n        \n        return assignments;\n    }\n    \n    void setStartDay(int task_idx, int day) {\n        start_day[task_idx] = day;\n    }\n    \n    bool allTasksCompleted() {\n        for (bool completed : task_completed) {\n            if (!completed) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    TaskScheduler scheduler(N, M, K);\n    \n    for (int i = 0; i < N; i++) {\n        vector<int> reqs(K);\n        for (int k = 0; k < K; k++) {\n            cin >> reqs[k];\n        }\n        scheduler.setTaskRequirements(i, reqs);\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        scheduler.addDependency(u, v);\n    }\n    \n    scheduler.computeDepthForward();\n    \n    for (int day = 1; day <= 2000; day++) {\n        if (day > 1) {\n            int n_completed;\n            cin >> n_completed;\n            \n            if (n_completed == -1) {\n                break;\n            }\n            \n            vector<int> completed_members(n_completed);\n            for (int i = 0; i < n_completed; i++) {\n                cin >> completed_members[i];\n                completed_members[i]--;\n            }\n            \n            scheduler.processCompletions(day - 1, completed_members);\n        }\n        \n        if (scheduler.allTasksCompleted()) {\n            cout << 0 << endl;\n            cout.flush();\n            while (day <= 2000) {\n                int check;\n                cin >> check;\n                if (check == -1) break;\n                day++;\n            }\n            break;\n        }\n        \n        auto assignments = scheduler.getAssignments(day);\n        \n        cout << assignments.size();\n        for (auto& assignment : assignments) {\n            int member_idx = assignment.first;\n            int task_idx = assignment.second;\n            scheduler.setStartDay(task_idx, day);\n            cout << \" \" << member_idx + 1 << \" \" << task_idx + 1;\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Order {\n    int a, b, c, d;\n    int index;\n};\n\ninline int manhattan(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nvector<Order> selectOrders(const vector<Order>& allOrders) {\n    Point office(400, 400);\n    vector<pair<int, int>> orderCosts;\n    \n    for (int i = 0; i < (int)allOrders.size(); i++) {\n        Point pickup(allOrders[i].a, allOrders[i].b);\n        Point delivery(allOrders[i].c, allOrders[i].d);\n        int cost = manhattan(office, pickup) + manhattan(pickup, delivery) + manhattan(delivery, office);\n        orderCosts.push_back({cost, i});\n    }\n    \n    sort(orderCosts.begin(), orderCosts.end());\n    \n    vector<Order> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(allOrders[orderCosts[i].second]);\n    }\n    return selected;\n}\n\nvector<Point> buildRoute(const vector<Order>& selected) {\n    vector<Point> route;\n    Point office(400, 400);\n    route.push_back(office);\n    \n    // Track state: 0 = not picked up, 1 = picked up but not delivered, 2 = delivered\n    vector<int> state(selected.size(), 0);\n    Point current = office;\n    \n    int deliveredCount = 0;\n    while (deliveredCount < (int)selected.size()) {\n        int bestDist = 1e9;\n        Point bestPoint;\n        int bestOrderIdx = -1;\n        bool bestIsDelivery = false;\n        \n        // Find closest available pickup\n        for (int i = 0; i < (int)selected.size(); i++) {\n            if (state[i] == 0) {\n                Point pickup(selected[i].a, selected[i].b);\n                int dist = manhattan(current, pickup);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPoint = pickup;\n                    bestOrderIdx = i;\n                    bestIsDelivery = false;\n                }\n            }\n        }\n        \n        // Find closest available delivery\n        for (int i = 0; i < (int)selected.size(); i++) {\n            if (state[i] == 1) {\n                Point delivery(selected[i].c, selected[i].d);\n                int dist = manhattan(current, delivery);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPoint = delivery;\n                    bestOrderIdx = i;\n                    bestIsDelivery = true;\n                }\n            }\n        }\n        \n        // Add best point to route\n        route.push_back(bestPoint);\n        current = bestPoint;\n        \n        // Update state\n        if (bestIsDelivery) {\n            state[bestOrderIdx] = 2;\n            deliveredCount++;\n        } else {\n            state[bestOrderIdx] = 1;\n        }\n    }\n    \n    route.push_back(office);\n    return route;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<Order> allOrders;\n    for (int i = 0; i < 1000; i++) {\n        Order order;\n        cin >> order.a >> order.b >> order.c >> order.d;\n        order.index = i + 1;\n        allOrders.push_back(order);\n    }\n    \n    vector<Order> selected = selectOrders(allOrders);\n    vector<Point> route = buildRoute(selected);\n    \n    cout << selected.size();\n    for (const Order& order : selected) {\n        cout << \" \" << order.index;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const Point& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct DSU {\n    vector<int> parent, rank;\n    DSU() {\n        parent.resize(N);\n        rank.resize(N, 0);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) {\n            parent[x] = y;\n        } else if (rank[x] > rank[y]) {\n            parent[y] = x;\n        } else {\n            parent[y] = x;\n            rank[x]++;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read coordinates\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n\n    // Read edges\n    vector<pair<int, int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n    }\n\n    // Precompute baseline distances\n    vector<int> d(M);\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        long long dx = x[u] - x[v];\n        long long dy = y[u] - y[v];\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = (int)round(dist);\n    }\n\n    DSU dsu;\n    vector<vector<int>> remaining_edges(N, vector<int>(N, 0));\n    \n    // Initialize remaining_edges matrix\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        remaining_edges[u][v]++;\n        remaining_edges[v][u]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            cout << \"0\" << endl;\n            continue;\n        }\n\n        // Get current edge count between components\n        int count = remaining_edges[ru][rv];\n        bool take = (count == 1) || (l_i <= 2 * d[i]);\n\n        if (take) {\n            cout << \"1\" << endl;\n            \n            if (dsu.unite(ru, rv)) {\n                int new_root = dsu.find(ru);\n                int old_root = (new_root == ru) ? rv : ru;\n                \n                // Clear the edge between ru and rv\n                remaining_edges[ru][rv] = 0;\n                remaining_edges[rv][ru] = 0;\n                \n                // Update matrix only for vertices that are roots\n                for (int j = 0; j < N; j++) {\n                    if (j == new_root || j == old_root) continue;\n                    int rj = dsu.find(j);\n                    if (rj == new_root) continue;\n                    \n                    remaining_edges[new_root][rj] += remaining_edges[old_root][j];\n                    remaining_edges[rj][new_root] = remaining_edges[new_root][rj];\n                    remaining_edges[old_root][j] = 0;\n                    remaining_edges[j][old_root] = 0;\n                }\n            }\n        } else {\n            cout << \"0\" << endl;\n            // Decrement remaining edge count\n            remaining_edges[ru][rv]--;\n            remaining_edges[rv][ru]--;\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\nusing namespace std;\n\nconst int dx4[4] = {-1, 1, 0, 0};\nconst int dy4[4] = {0, 0, -1, 1};\n\nint main() {\n    int N;\n    cin >> N;\n    vector<int> pet_x(N), pet_y(N), pet_type(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n        pet_x[i]--; \n        pet_y[i]--;\n    }\n\n    int M;\n    cin >> M;\n    vector<int> human_x(M), human_y(M);\n    for (int i = 0; i < M; i++) {\n        cin >> human_x[i] >> human_y[i];\n        human_x[i]--;\n        human_y[i]--;\n    }\n\n    bool blocked[30][30] = {false};\n\n    for (int turn = 0; turn < 300; turn++) {\n        vector<char> actions(M, '.');\n        \n        // First, collect all pet positions at the start of this turn\n        vector<pair<int, int>> pet_positions;\n        for (int j = 0; j < N; j++) {\n            pet_positions.push_back({pet_x[j], pet_y[j]});\n        }\n\n        // For each human, decide action\n        for (int i = 0; i < M; i++) {\n            int hx = human_x[i], hy = human_y[i];\n            \n            // Check if there's a pet too close - if so, try to move away\n            bool too_close = false;\n            int closest_pet_dist = 1000;\n            int pet_dir = -1;\n            for (int j = 0; j < N; j++) {\n                int dist = abs(hx - pet_x[j]) + abs(hy - pet_y[j]);\n                if (dist < closest_pet_dist) {\n                    closest_pet_dist = dist;\n                    // Find direction away from pet\n                    if (pet_x[j] < hx) pet_dir = 1; // move down\n                    else if (pet_x[j] > hx) pet_dir = 0; // move up\n                    else if (pet_y[j] < hy) pet_dir = 3; // move right\n                    else if (pet_y[j] > hy) pet_dir = 2; // move left\n                }\n                if (dist <= 2) {\n                    too_close = true;\n                }\n            }\n\n            if (too_close && pet_dir != -1) {\n                // Try to move away from the pet\n                int nx = hx + dx4[pet_dir];\n                int ny = hy + dy4[pet_dir];\n                if (nx >= 0 && nx < 30 && ny >= 0 && ny < 30 && !blocked[nx][ny]) {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (!has_pet) {\n                        if (pet_dir == 0) actions[i] = 'U';\n                        else if (pet_dir == 1) actions[i] = 'D';\n                        else if (pet_dir == 2) actions[i] = 'L';\n                        else if (pet_dir == 3) actions[i] = 'R';\n                        continue;\n                    }\n                }\n            }\n\n            // If no immediate danger, try to move toward center (14,14 in 0-indexed)\n            int target_x = 14, target_y = 14;\n            int best_dir = -1;\n            int best_score = -1000000;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = hx + dx4[d];\n                int ny = hy + dy4[d];\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                if (blocked[nx][ny]) continue;\n                \n                // Check if square has a pet\n                bool has_pet = false;\n                for (int j = 0; j < N; j++) {\n                    if (pet_x[j] == nx && pet_y[j] == ny) {\n                        has_pet = true;\n                        break;\n                    }\n                }\n                if (has_pet) continue;\n\n                // Calculate score: prefer moving toward center\n                int score = - (abs(nx - target_x) + abs(ny - target_y));\n                \n                // Bonus for being away from pets\n                int min_dist = 1000;\n                for (int j = 0; j < N; j++) {\n                    int dist = abs(nx - pet_x[j]) + abs(ny - pet_y[j]);\n                    if (dist < min_dist) min_dist = dist;\n                }\n                if (min_dist > 3) score += 1000;\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = d;\n                }\n            }\n            \n            if (best_dir != -1) {\n                actions[i] = (best_dir == 0) ? 'U' : (best_dir == 1) ? 'D' : (best_dir == 2) ? 'L' : 'R';\n            } else {\n                // If no good move, try to block if it's safe\n                for (int d = 0; d < 4; d++) {\n                    int bx = hx + dx4[d];\n                    int by = hy + dy4[d];\n                    if (bx < 0 || bx >= 30 || by < 0 || by >= 30) continue;\n                    if (blocked[bx][by]) continue;\n                    \n                    // Check if square is occupied\n                    bool occupied = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == bx && pet_y[j] == by) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    for (int j = 0; j < M; j++) {\n                        if (human_x[j] == bx && human_y[j] == by) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    if (occupied) continue;\n\n                    // Check all 4 adjacent squares for pets\n                    bool safe_to_block = true;\n                    for (int k = 0; k < 4; k++) {\n                        int nx = bx + dx4[k];\n                        int ny = by + dy4[k];\n                        if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                        for (int j = 0; j < N; j++) {\n                            if (pet_x[j] == nx && pet_y[j] == ny) {\n                                safe_to_block = false;\n                                break;\n                            }\n                        }\n                        if (!safe_to_block) break;\n                    }\n                    \n                    if (safe_to_block) {\n                        actions[i] = (d == 0) ? 'u' : (d == 1) ? 'd' : (d == 2) ? 'l' : 'r';\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Output actions\n        for (int i = 0; i < M; i++) {\n            cout << actions[i];\n        }\n        cout << endl;\n        cout.flush();\n\n        // Update grid with new blocks\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u' || actions[i] == 'd' || actions[i] == 'l' || actions[i] == 'r') {\n                int bx = human_x[i], by = human_y[i];\n                if (actions[i] == 'u') bx--;\n                else if (actions[i] == 'd') bx++;\n                else if (actions[i] == 'l') by--;\n                else if (actions[i] == 'r') by++;\n                if (bx >= 0 && bx < 30 && by >= 0 && by < 30) {\n                    blocked[bx][by] = true;\n                }\n            }\n        }\n\n        // Update human positions\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U' || actions[i] == 'D' || actions[i] == 'L' || actions[i] == 'R') {\n                int nx = human_x[i], ny = human_y[i];\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx >= 0 && nx < 30 && ny >= 0 && ny < 30 && !blocked[nx][ny]) {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (!has_pet) {\n                        human_x[i] = nx;\n                        human_y[i] = ny;\n                    }\n                }\n            }\n        }\n\n        // Update pet positions\n        for (int i = 0; i < N; i++) {\n            string move_str;\n            cin >> move_str;\n            if (move_str == \".\") continue;\n            for (char c : move_str) {\n                if (c == 'U') pet_x[i]--;\n                else if (c == 'D') pet_x[i]++;\n                else if (c == 'L') pet_y[i]--;\n                else if (c == 'R') pet_y[i]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <tuple>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    int s_i, s_j, t_i, t_j;\n    double p;\n    cin >> s_i >> s_j >> t_i >> t_j >> p;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n\n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n\n    vector<vector<int>> dist(20, vector<int>(20, INT_MAX));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move_char(20, vector<char>(20, ' '));\n\n    queue<pair<int, int>> q;\n    dist[s_i][s_j] = 0;\n    q.push({s_i, s_j});\n\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (i == t_i && j == t_j) break;\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 >= 20 || nj < 0 || nj >= 20) continue;\n\n            bool canMove = true;\n            if (d == 0) {\n                if (i == 0) canMove = false;\n                else if (v[i-1][j] == '1') canMove = false;\n            } else if (d == 1) {\n                if (i == 19) canMove = false;\n                else if (v[i][j] == '1') canMove = false;\n            } else if (d == 2) {\n                if (j == 0) canMove = false;\n                else if (h[i][j-1] == '1') canMove = false;\n            } else if (d == 3) {\n                if (j == 19) canMove = false;\n                else if (h[i][j] == '1') canMove = false;\n            }\n\n            if (canMove && dist[ni][nj] == INT_MAX) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent[ni][nj] = {i, j};\n                move_char[ni][nj] = dir_char[d];\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    string path = \"\";\n    int i = t_i, j = t_j;\n    while (i != s_i || j != s_j) {\n        path += move_char[i][j];\n        auto [pi, pj] = parent[i][j];\n        i = pi;\n        j = pj;\n    }\n    reverse(path.begin(), path.end());\n\n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n\n    int L0 = path.size();\n    int r = 200 / L0;\n    if (r < 1) r = 1;\n\n    string result = \"\";\n    for (char c : path) {\n        for (int i = 0; i < r; i++) {\n            result += c;\n        }\n    }\n\n    if (result.size() > 200) {\n        result = result.substr(0, 200);\n    }\n\n    cout << result << endl;\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Process 100 test cases\n    for (int tc = 0; tc < 100; tc++) {\n        // Read 30 lines of 30 characters\n        for (int i = 0; i < 30; i++) {\n            string line;\n            cin >> line;\n            // We don't actually use the input for this simple solution\n        }\n\n        // Output 900 zeros (one per tile)\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                cout << '0';\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <unordered_set>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nconst int MAX_N = 10;\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\n// Directions: U, D, L, R\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Cache for component computations\nvector<vector<int>> comp_id;\nvector<int> comp_size;\nint comp_counter = 0;\n\n// Hash function for board state\nstruct BoardHash {\n    size_t operator()(const vector<vector<int>>& b) const {\n        size_t h = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                h = h * 131 + b[i][j];\n            }\n        }\n        return h;\n    }\n};\n\n// Compute connected components with cycle detection\nvoid compute_components() {\n    comp_id.assign(N, vector<int>(N, -1));\n    comp_size.clear();\n    comp_counter = 0;\n    \n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            // BFS to find component\n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            comp_id[i][j] = comp_counter;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                size++;\n                \n                // Check all four directions\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0) continue;\n                    if (visited[nx][ny]) continue;\n                    \n                    // Check if there's a connection\n                    bool connected = false;\n                    if (d == 0 && (board[x][y] & 2) && (board[nx][ny] & 8)) connected = true; // U\n                    else if (d == 1 && (board[x][y] & 8) && (board[nx][ny] & 2)) connected = true; // D\n                    else if (d == 2 && (board[x][y] & 1) && (board[nx][ny] & 4)) connected = true; // L\n                    else if (d == 3 && (board[x][y] & 4) && (board[nx][ny] & 1)) connected = true; // R\n                    \n                    if (connected) {\n                        visited[nx][ny] = true;\n                        comp_id[nx][ny] = comp_counter;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            comp_size.push_back(size);\n            comp_counter++;\n        }\n    }\n}\n\n// Get the size of the largest tree (connected component without cycles)\nint get_largest_tree_size() {\n    compute_components();\n    \n    // For each component, check if it's a tree (connected, no cycles)\n    // A connected component with V vertices is a tree if it has exactly V-1 edges\n    vector<int> comp_edges(comp_counter, 0);\n    vector<bool> is_tree(comp_counter, true);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            int cid = comp_id[i][j];\n            \n            // Count edges from this tile\n            int edges = 0;\n            if (i > 0 && board[i-1][j] != 0 && (board[i][j] & 2) && (board[i-1][j] & 8)) edges++;\n            if (i < N-1 && board[i+1][j] != 0 && (board[i][j] & 8) && (board[i+1][j] & 2)) edges++;\n            if (j > 0 && board[i][j-1] != 0 && (board[i][j] & 1) && (board[i][j-1] & 4)) edges++;\n            if (j < N-1 && board[i][j+1] != 0 && (board[i][j] & 4) && (board[i][j+1] & 1)) edges++;\n            \n            comp_edges[cid] += edges;\n        }\n    }\n    \n    // Check if each component is a tree: edges = vertices - 1\n    int max_tree = 0;\n    for (int cid = 0; cid < comp_counter; cid++) {\n        if (comp_size[cid] == 0) continue;\n        if (comp_edges[cid] / 2 == comp_size[cid] - 1) { // Each edge counted twice\n            max_tree = max(max_tree, comp_size[cid]);\n        }\n    }\n    \n    return max_tree;\n}\n\n// Evaluate a move and return the resulting tree size\nint evaluate_move(int move, vector<vector<int>>& current_board, int ei, int ej) {\n    int ni = ei + di[move];\n    int nj = ej + dj[move];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return -1;\n    \n    swap(current_board[ei][ej], current_board[ni][nj]);\n    int score = get_largest_tree_size();\n    swap(current_board[ei][ej], current_board[ni][nj]); // backtrack\n    \n    return score;\n}\n\n// Lookahead search with limited depth\nint lookahead_search(int depth, vector<vector<int>>& current_board, int ei, int ej, string& best_seq, int current_best) {\n    if (depth == 0) {\n        int score = get_largest_tree_size();\n        if (score > current_best) {\n            current_best = score;\n        }\n        return current_best;\n    }\n    \n    for (int d = 0; d < 4; d++) {\n        int ni = ei + di[d];\n        int nj = ej + dj[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        \n        swap(current_board[ei][ej], current_board[ni][nj]);\n        int score = lookahead_search(depth-1, current_board, ni, nj, best_seq, current_best);\n        if (score > current_best) {\n            current_best = score;\n            best_seq = dir_char[d] + best_seq; // Note: this builds sequence in reverse\n        }\n        swap(current_board[ei][ej], current_board[ni][nj]);\n    }\n    \n    return current_best;\n}\n\nint main() {\n    auto start_time = high_resolution_clock::now();\n    \n    cin >> N >> T;\n    board.assign(N, vector<int>(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            char c = s[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = 10 + c - 'a';\n            }\n            if (board[i][j] == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int current_tree_size = get_largest_tree_size();\n    int target_size = N * N - 1;\n    \n    // If already optimal\n    if (current_tree_size == target_size) {\n        cout << result << endl;\n        return 0;\n    }\n    \n    // Main loop with time management\n    for (int step = 0; step < T; step++) {\n        auto current_time = high_resolution_clock::now();\n        auto elapsed = duration_cast<milliseconds>(current_time - start_time).count();\n        if (elapsed > 2800) break; // Leave margin for time limit\n        \n        // Try to find best move with lookahead\n        int best_score = -1;\n        int best_move = -1;\n        \n        // First, try immediate moves\n        for (int d = 0; d < 4; d++) {\n            int score = evaluate_move(d, board, empty_i, empty_j);\n            if (score > best_score) {\n                best_score = score;\n                best_move = d;\n            }\n        }\n        \n        // If we have time, try 2-step lookahead for promising moves\n        if (step < T - 2 && elapsed < 2500) {\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                swap(board[empty_i][empty_j], board[ni][nj]);\n                \n                // Try second moves\n                for (int d2 = 0; d2 < 4; d2++) {\n                    if (d2 == d) continue; // Don't immediately undo\n                    int score2 = evaluate_move(d2, board, ni, nj);\n                    if (score2 > best_score) {\n                        best_score = score2;\n                        best_move = d;\n                    }\n                }\n                \n                swap(board[empty_i][empty_j], board[ni][nj]);\n            }\n        }\n        \n        // If no improvement, try random moves to escape local optima\n        if (best_score <= current_tree_size && step > T/2) {\n            vector<int> valid_moves;\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    valid_moves.push_back(d);\n                }\n            }\n            if (!valid_moves.empty()) {\n                best_move = valid_moves[rand() % valid_moves.size()];\n                best_score = evaluate_move(best_move, board, empty_i, empty_j);\n            }\n        }\n        \n        // If still no good move, break\n        if (best_move == -1) break;\n        \n        // Execute the best move\n        int ni = empty_i + di[best_move];\n        int nj = empty_j + dj[best_move];\n        swap(board[empty_i][empty_j], board[ni][nj]);\n        empty_i = ni;\n        empty_j = nj;\n        result += dir_char[best_move];\n        \n        current_tree_size = best_score;\n        \n        // If we achieved full tree, we can break early\n        if (current_tree_size == target_size) {\n            // We'll continue to try to reduce moves, but break if time is short\n            if (duration_cast<milliseconds>(high_resolution_clock::now() - start_time).count() > 2500) {\n                break;\n            }\n        }\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Line {\n    Point p1, p2;\n};\n\n// Check if a line passes through a strawberry\nbool passes_through(const Line& l, const Point& s) {\n    ll dx = l.p2.x - l.p1.x;\n    ll dy = l.p2.y - l.p1.y;\n    ll cross = dx * (s.y - l.p1.y) - dy * (s.x - l.p1.x);\n    return cross == 0;\n}\n\n// Generate a simple line that splits strawberries by projection\nLine generate_split_line(ll dx, ll dy, ll C) {\n    // For simplicity, use a line that is perpendicular to the direction\n    // and passes through a point on the line dx*x + dy*y = C\n    \n    // We need two points on this line\n    // If dx != 0, we can use (C/dx, 0) and (0, C/dy)\n    // But we need integer coordinates\n    \n    // Use the direction vector and shift\n    // Line: (0, C) and (1, C + dx/dy) if dy != 0\n    if (dy != 0) {\n        // Use points (0, C) and (1, C + dx/dy)\n        // But we need integer coordinates\n        // Let's use (0, C) and (dy, C + dx)\n        return {{0, C}, {dy, C + dx}};\n    } else {\n        // dy == 0, so dx != 0\n        // Use (C, 0) and (C, 1)\n        return {{C, 0}, {C, 1}};\n    }\n}\n\n// Alternative: generate line from two points on the line dx*x + dy*y = C\nLine generate_line_alternative(ll dx, ll dy, ll C) {\n    // Find two points with integer coordinates\n    // If dx != 0 and dy != 0\n    ll x1, y1, x2, y2;\n    \n    if (dx != 0 && dy != 0) {\n        // Try to find small integer solutions\n        // Use (0, C) if dy divides C\n        if (C % dy == 0) {\n            y1 = C / dy;\n            x1 = 0;\n        } else {\n            // Use (C, 0) if dx divides C\n            if (C % dx == 0) {\n                x1 = C / dx;\n                y1 = 0;\n            } else {\n                // Use extended Euclidean to find a solution\n                // But for simplicity, use (0, C) and (dy, C + dx)\n                y1 = 0;\n                x1 = 0; // This might not be on the line\n                // Let's use (0, C) anyway and adjust\n                // Actually (0, C) is on the line only if dy*y = C, i.e., y = C/dy\n                // So we need to use the correct point\n                // Let's use (0, C/dy) if C is divisible by dy\n                // If not, we can use (C/dx, 0) if C is divisible by dx\n                // If neither, we can't represent with integer coordinates easily\n                // In this case, we'll use a different approach\n                // Use (0, 0) and (dy, -dx) which is perpendicular to (dx, dy)\n                // But shifted by C is tricky\n                // For now, use the first approach and hope it works\n                return {{0, 0}, {dy, -dx}};\n            }\n        }\n    } else if (dx == 0) {\n        // Vertical line: x = C\n        return {{C, 0}, {C, 1}};\n    } else { // dy == 0\n        // Horizontal line: y = C\n        return {{0, C}, {1, C}};\n    }\n    \n    // Second point: (x1 + dy, y1 - dx)\n    x2 = x1 + dy;\n    y2 = y1 - dx;\n    \n    return {{x1, y1}, {x2, y2}};\n}\n\nint main() {\n    srand(time(0));\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Simple greedy approach: keep splitting pieces until we run out of cuts\n    vector<Line> lines;\n    vector<vector<int>> pieces;\n    pieces.push_back(vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        pieces[0][i] = i;\n    }\n\n    for (int cut = 0; cut < K; cut++) {\n        // Find the largest piece that can be split\n        int best_idx = -1;\n        int best_size = 0;\n        for (int i = 0; i < pieces.size(); i++) {\n            if (pieces[i].size() > best_size) {\n                best_size = pieces[i].size();\n                best_idx = i;\n            }\n        }\n        \n        if (best_idx == -1 || best_size <= 1) {\n            break;\n        }\n        \n        // Try to find a valid split\n        vector<int> S = pieces[best_idx];\n        bool found = false;\n        Line best_line;\n        vector<int> best_S1, best_S2;\n        \n        // Try 50 random directions\n        for (int attempt = 0; attempt < 50 && !found; attempt++) {\n            ll dx = rand() % 2001 - 1000;\n            ll dy = rand() % 2001 - 1000;\n            if (dx == 0 && dy == 0) continue;\n            \n            // Compute projections for all strawberries\n            vector<pair<ll, int>> proj_all(N);\n            for (int i = 0; i < N; i++) {\n                proj_all[i].first = dx * strawberries[i].x + dy * strawberries[i].y;\n                proj_all[i].second = i;\n            }\n            sort(proj_all.begin(), proj_all.end());\n            \n            // Compute projections for S\n            vector<ll> proj_S;\n            for (int idx : S) {\n                proj_S.push_back(dx * strawberries[idx].x + dy * strawberries[idx].y);\n            }\n            sort(proj_S.begin(), proj_S.end());\n            \n            // Find a gap in S that is not in all strawberries\n            for (int i = 0; i < (int)proj_S.size() - 1; i++) {\n                if (proj_S[i] < proj_S[i+1]) {\n                    ll C = proj_S[i] + 1; // Use the midpoint between consecutive projections\n                    // Check if C is not in proj_all\n                    bool in_all = false;\n                    for (const auto& p : proj_all) {\n                        if (p.first == C) {\n                            in_all = true;\n                            break;\n                        }\n                    }\n                    if (in_all) continue;\n                    \n                    // Split S\n                    vector<int> S1, S2;\n                    for (int idx : S) {\n                        ll proj = dx * strawberries[idx].x + dy * strawberries[idx].y;\n                        if (proj < C) {\n                            S1.push_back(idx);\n                        } else if (proj > C) {\n                            S2.push_back(idx);\n                        }\n                    }\n                    if (S1.empty() || S2.empty()) continue;\n                    \n                    // Generate line\n                    Line line = generate_line_alternative(dx, dy, C);\n                    \n                    // Check coordinates range\n                    const ll MAX_VAL = 1000000000;\n                    if (abs(line.p1.x) > MAX_VAL || abs(line.p1.y) > MAX_VAL || \n                        abs(line.p2.x) > MAX_VAL || abs(line.p2.y) > MAX_VAL) {\n                        continue;\n                    }\n                    \n                    // Check if line passes through any strawberry\n                    bool valid = true;\n                    for (int i = 0; i < N; i++) {\n                        if (passes_through(line, strawberries[i])) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                    if (!valid) continue;\n                    \n                    // Use this split\n                    best_line = line;\n                    best_S1 = S1;\n                    best_S2 = S2;\n                    found = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!found) {\n            // Try simpler splits: use the median projection\n            for (int attempt = 0; attempt < 10 && !found; attempt++) {\n                ll dx = rand() % 2001 - 1000;\n                ll dy = rand() % 2001 - 1000;\n                if (dx == 0 && dy == 0) continue;\n                \n                vector<ll> proj_S;\n                for (int idx : S) {\n                    proj_S.push_back(dx * strawberries[idx].x + dy * strawberries[idx].y);\n                }\n                sort(proj_S.begin(), proj_S.end());\n                \n                // Use median as split\n                ll C = proj_S[proj_S.size()/2];\n                vector<int> S1, S2;\n                for (int idx : S) {\n                    ll proj = dx * strawberries[idx].x + dy * strawberries[idx].y;\n                    if (proj < C) {\n                        S1.push_back(idx);\n                    } else if (proj > C) {\n                        S2.push_back(idx);\n                    }\n                }\n                if (S1.empty() || S2.empty()) continue;\n                \n                Line line = generate_line_alternative(dx, dy, C);\n                \n                // Check coordinates range\n                const ll MAX_VAL = 1000000000;\n                if (abs(line.p1.x) > MAX_VAL || abs(line.p1.y) > MAX_VAL || \n                    abs(line.p2.x) > MAX_VAL || abs(line.p2.y) > MAX_VAL) {\n                    continue;\n                }\n                \n                bool valid = true;\n                for (int i = 0; i < N; i++) {\n                    if (passes_through(line, strawberries[i])) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (!valid) continue;\n                \n                best_line = line;\n                best_S1 = S1;\n                best_S2 = S2;\n                found = true;\n                break;\n            }\n        }\n        \n        if (!found) {\n            break;\n        }\n        \n        // Apply split\n        lines.push_back(best_line);\n        pieces.erase(pieces.begin() + best_idx);\n        pieces.push_back(best_S1);\n        pieces.push_back(best_S2);\n    }\n\n    // Output\n    cout << lines.size() << endl;\n    for (const Line& line : lines) {\n        cout << line.p1.x << \" \" << line.p1.y << \" \" << line.p2.x << \" \" << line.p2.y << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <unordered_set>\n#include <map>\n#include <random>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nusing Point = pair<int, int>;\nusing Segment = pair<Point, Point>;\n\nstruct Candidate {\n    Point new_dot;\n    vector<Point> existing;\n    int type;\n    int weight;\n    int gap_size;\n};\n\nSegment make_segment(Point a, Point b) {\n    if (a < b) return {a, b};\n    return {b, a};\n}\n\nint main() {\n    auto start = high_resolution_clock::now();\n    int N, M;\n    cin >> N >> M;\n    vector<Point> initial_dots;\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> row_set(N);\n    vector<set<int>> col_set(N);\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initial_dots.push_back({x, y});\n        grid[x][y] = true;\n        row_set[y].insert(x);\n        col_set[x].insert(y);\n    }\n\n    int c = (N-1)/2;\n    auto weight_func = [c](int x, int y) {\n        int dx = x - c;\n        int dy = y - c;\n        return dx*dx + dy*dy + 1;\n    };\n\n    set<Segment> drawn_segments;\n    vector<vector<int>> operations;\n\n    const double TIME_LIMIT = 4.8;\n    int K_top = 250;\n    int consecutive_failures = 0;\n\n    for (int iter = 0; iter < 100000; iter++) {\n        auto now = high_resolution_clock::now();\n        auto elapsed = duration_cast<milliseconds>(now - start).count() / 1000.0;\n        if (elapsed > TIME_LIMIT) break;\n        if (consecutive_failures > 100) break;\n\n        vector<Candidate> candidates;\n        unordered_set<long long> added_new_dot;\n\n        // Axis-aligned rectangles - consider gaps up to 30\n        for (int y = 0; y < N; y++) {\n            if (row_set[y].size() < 2) continue;\n            vector<int> xs(row_set[y].begin(), row_set[y].end());\n            sort(xs.begin(), xs.end());\n            for (int i = 0; i < xs.size(); i++) {\n                for (int j = i+1; j < xs.size(); j++) {\n                    int x1 = xs[i], x2 = xs[j];\n                    int gap = x2 - x1;\n                    if (gap > 30) break;\n                    for (int y1 : col_set[x1]) {\n                        if (y1 == y) continue;\n                        if (x2 < N && !grid[x2][y1]) {\n                            long long key = (long long)x2 * 1000 + y1;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x2, y1);\n                                candidates.push_back({{x2,y1}, {{x1,y}, {x2,y}, {x1,y1}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                            }\n                        }\n                    }\n                    for (int y1 : col_set[x2]) {\n                        if (y1 == y) continue;\n                        if (x1 >= 0 && !grid[x1][y1]) {\n                            long long key = (long long)x1 * 1000 + y1;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x1, y1);\n                                candidates.push_back({{x1,y1}, {{x1,y}, {x2,y}, {x2,y1}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            if (col_set[x].size() < 2) continue;\n            vector<int> ys(col_set[x].begin(), col_set[x].end());\n            sort(ys.begin(), ys.end());\n            for (int i = 0; i < ys.size(); i++) {\n                for (int j = i+1; j < ys.size(); j++) {\n                    int y1 = ys[i], y2 = ys[j];\n                    int gap = y2 - y1;\n                    if (gap > 30) break;\n                    for (int x1 : row_set[y1]) {\n                        if (x1 == x) continue;\n                        if (y2 < N && !grid[x1][y2]) {\n                            long long key = (long long)x1 * 1000 + y2;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x1, y2);\n                                candidates.push_back({{x1,y2}, {{x,y1}, {x,y2}, {x1,y1}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                            }\n                        }\n                    }\n                    for (int x1 : row_set[y2]) {\n                        if (x1 == x) continue;\n                        if (y1 >= 0 && !grid[x1][y1]) {\n                            long long key = (long long)x1 * 1000 + y1;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x1, y1);\n                                candidates.push_back({{x1,y1}, {{x,y1}, {x,y2}, {x1,y2}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // 45-degree squares - consider a=1 to 6\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y]) continue;\n                long long key = (long long)x * 1000 + y;\n                if (added_new_dot.find(key) != added_new_dot.end()) continue;\n                int w = weight_func(x, y);\n                for (int a = 1; a <= 6; a++) {\n                    bool found = false;\n                    // Orientation 0: new dot at (x,y), existing at (x+a,y-a), (x,y-2a), (x-a,y-a)\n                    if (x+a < N && x-a >= 0 && y-2*a >= 0 && y-a >= 0) {\n                        if (grid[x+a][y-a] && grid[x][y-2*a] && grid[x-a][y-a]) {\n                            candidates.push_back({{x,y}, {{x+a,y-a}, {x,y-2*a}, {x-a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                    // Orientation 1: new dot at (x,y), existing at (x+a,y+a), (x+2*a,y), (x+a,y-a)\n                    if (!found && x+2*a < N && x+a >= 0 && y+a < N && y-a >= 0) {\n                        if (grid[x+a][y+a] && grid[x+2*a][y] && grid[x+a][y-a]) {\n                            candidates.push_back({{x,y}, {{x+a,y+a}, {x+2*a,y}, {x+a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                    // Orientation 2: new dot at (x,y), existing at (x-a,y-a), (x,y-2a), (x+a,y-a)\n                    if (!found && x-a >= 0 && x+a < N && y-2*a >= 0 && y-a >= 0) {\n                        if (grid[x-a][y-a] && grid[x][y-2*a] && grid[x+a][y-a]) {\n                            candidates.push_back({{x,y}, {{x-a,y-a}, {x,y-2*a}, {x+a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                    // Orientation 3: new dot at (x,y), existing at (x-a,y+a), (x-2*a,y), (x-a,y-a)\n                    if (!found && x-2*a >= 0 && x-a >= 0 && y+a < N && y-a >= 0) {\n                        if (grid[x-a][y+a] && grid[x-2*a][y] && grid[x-a][y-a]) {\n                            candidates.push_back({{x,y}, {{x-a,y+a}, {x-2*a,y}, {x-a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                }\n            }\n        }\n\n        if (candidates.empty()) {\n            consecutive_failures++;\n            continue;\n        }\n\n        // Sort by weight and gap size (larger gaps/squares first)\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            if (a.weight != b.weight) return a.weight > b.weight;\n            return a.gap_size > b.gap_size;\n        });\n\n        if (candidates.size() > K_top) {\n            candidates.resize(K_top);\n        }\n\n        random_device rd;\n        mt19937 g(rd());\n        shuffle(candidates.begin(), candidates.end(), g);\n\n        bool found_valid = false;\n        for (const Candidate& cand : candidates) {\n            Point new_dot = cand.new_dot;\n            vector<Point> existing = cand.existing;\n            int type = cand.type;\n\n            set<Point> corners = {new_dot, existing[0], existing[1], existing[2]};\n\n            // Condition 2: Check perimeter for other dots\n            bool condition2_ok = true;\n            vector<Point> perimeter_points;\n\n            if (type == 0) {\n                int x_min = min({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int x_max = max({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int y_min = min({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                int y_max = max({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                \n                for (int x = x_min; x <= x_max; x++) {\n                    perimeter_points.push_back({x, y_min});\n                    perimeter_points.push_back({x, y_max});\n                }\n                for (int y = y_min+1; y < y_max; y++) {\n                    perimeter_points.push_back({x_min, y});\n                    perimeter_points.push_back({x_max, y});\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                \n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = max(abs(dx), abs(dy));\n                    if (steps == 0) continue;\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k <= steps; k++) {\n                        perimeter_points.push_back(current);\n                        current.first += sx;\n                        current.second += sy;\n                    }\n                }\n            }\n\n            for (const Point& p : perimeter_points) {\n                if (corners.find(p) == corners.end() && grid[p.first][p.second]) {\n                    condition2_ok = false;\n                    break;\n                }\n            }\n            if (!condition2_ok) continue;\n\n            // Condition 3: Check segment overlap\n            bool condition3_ok = true;\n            vector<Segment> new_segments;\n\n            if (type == 0) {\n                int x_min = min({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int x_max = max({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int y_min = min({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                int y_max = max({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                \n                for (int x = x_min; x < x_max; x++) {\n                    new_segments.push_back(make_segment({x, y_min}, {x+1, y_min}));\n                    new_segments.push_back(make_segment({x, y_max}, {x+1, y_max}));\n                }\n                for (int y = y_min; y < y_max; y++) {\n                    new_segments.push_back(make_segment({x_min, y}, {x_min, y+1}));\n                    new_segments.push_back(make_segment({x_max, y}, {x_max, y+1}));\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = max(abs(dx), abs(dy));\n                    if (steps == 0) continue;\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k < steps; k++) {\n                        Point next = {current.first + sx, current.second + sy};\n                        new_segments.push_back(make_segment(current, next));\n                        current = next;\n                    }\n                }\n            }\n\n            for (const Segment& seg : new_segments) {\n                if (drawn_segments.find(seg) != drawn_segments.end()) {\n                    condition3_ok = false;\n                    break;\n                }\n            }\n            if (!condition3_ok) continue;\n\n            // Valid move found\n            for (const Segment& seg : new_segments) {\n                drawn_segments.insert(seg);\n            }\n            grid[new_dot.first][new_dot.second] = true;\n            row_set[new_dot.second].insert(new_dot.first);\n            col_set[new_dot.first].insert(new_dot.second);\n\n            vector<int> op;\n            if (type == 0) {\n                Point same_x, same_y, opposite;\n                for (const Point& p : existing) {\n                    if (p.first == new_dot.first) same_x = p;\n                    else if (p.second == new_dot.second) same_y = p;\n                    else opposite = p;\n                }\n                op = {new_dot.first, new_dot.second, same_y.first, same_y.second, \n                      opposite.first, opposite.second, same_x.first, same_x.second};\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                int idx = 0;\n                while (corners_vec[idx] != new_dot) idx++;\n                for (int i = 0; i < 4; i++) {\n                    Point p = corners_vec[(idx+i)%4];\n                    op.push_back(p.first);\n                    op.push_back(p.second);\n                }\n            }\n            operations.push_back(op);\n\n            found_valid = true;\n            consecutive_failures = 0;\n            break;\n        }\n\n        if (!found_valid) {\n            consecutive_failures++;\n        }\n    }\n\n    cout << operations.size() << endl;\n    for (const vector<int>& op : operations) {\n        for (int i = 0; i < op.size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\n// Simulate tilting the grid in the given direction\nvector<vector<int>> tilt_grid(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> new_grid(10, vector<int>(10, 0));\n    if (dir == 'F') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 9; i >= 0; i--) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 9;\n            for (int candy : candies) {\n                new_grid[idx--][j] = candy;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 0;\n            for (int candy : candies) {\n                new_grid[idx++][j] = candy;\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 0;\n            for (int candy : candies) {\n                new_grid[i][idx++] = candy;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 9; j >= 0; j--) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 9;\n            for (int candy : candies) {\n                new_grid[i][idx--] = candy;\n            }\n        }\n    }\n    return new_grid;\n}\n\n// Compute sum of squares of connected components\nint compute_components(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dx[4] = {1, -1, 0, 0};\n    int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0 && !visited[i][j]) {\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int flavor = grid[i][j];\n                int size = 0;\n\n                while (!q.empty()) {\n                    auto [x, y] = q.front();\n                    q.pop();\n                    size++;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x + dx[d];\n                        int ny = y + dy[d];\n                        if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && \n                            !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\n// Enhanced scoring with simple strategic bonuses\nint enhanced_score(const vector<vector<int>>& grid, int current_flavor) {\n    int base_score = compute_components(grid);\n    \n    // Simple zone-based bonus\n    int zone_bonus = 0;\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0) {\n                int flavor = grid[i][j];\n                bool in_zone = false;\n                // Flavor 1: Top-Left\n                if (flavor == 1 && i < 5 && j < 5) in_zone = true;\n                // Flavor 2: Top-Right\n                if (flavor == 2 && i < 5 && j >= 5) in_zone = true;\n                // Flavor 3: Bottom\n                if (flavor == 3 && i >= 5) in_zone = true;\n                \n                if (in_zone) {\n                    zone_bonus += 10;\n                }\n                \n                // Bonus for each neighbor of same flavor\n                int dx[4] = {1, -1, 0, 0};\n                int dy[4] = {0, 0, 1, -1};\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 < 10 && nj >= 0 && nj < 10 && grid[ni][nj] == flavor) {\n                        zone_bonus += 3;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Penalty for isolated candies\n    int penalty = 0;\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int dx[4] = {1, -1, 0, 0};\n    int dy[4] = {0, 0, 1, -1};\n    \n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0 && !visited[i][j]) {\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int flavor = grid[i][j];\n                int size = 0;\n                \n                while (!q.empty()) {\n                    auto [x, y] = q.front();\n                    q.pop();\n                    size++;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x + dx[d];\n                        int ny = y + dy[d];\n                        if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && \n                            !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                if (size == 1) {\n                    penalty += 10;\n                }\n            }\n        }\n    }\n    \n    // Bonus for current flavor clustering\n    int current_bonus = 0;\n    if (current_flavor != 0) {\n        int count = 0;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == current_flavor) count++;\n            }\n        }\n        if (count >= 2) {\n            current_bonus = count * 5;\n        }\n    }\n    \n    return base_score * 100 + zone_bonus + current_bonus - penalty;\n}\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell\n        int count = 0;\n        int i0 = -1, j0 = -1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == 0) {\n                    count++;\n                    if (count == p) {\n                        i0 = i;\n                        j0 = j;\n                        break;\n                    }\n                }\n            }\n            if (i0 != -1) break;\n        }\n\n        // Place the candy\n        grid[i0][j0] = flavors[t];\n\n        // If it's the last candy, we don't need to tilt\n        if (t == 99) {\n            break;\n        }\n\n        // Try all directions and choose the best\n        char best_dir = 'F';\n        int best_score = -1;\n        string dirs = \"FBLR\";\n        \n        for (char d : dirs) {\n            vector<vector<int>> temp_grid = grid;\n            vector<vector<int>> tilted = tilt_grid(temp_grid, d);\n            int score = enhanced_score(tilted, flavors[t]);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        cout << best_dir << endl;\n\n        // Apply the best tilt to our grid state\n        grid = tilt_grid(grid, best_dir);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\nusing namespace std;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // More refined N selection based on M and epsilon\n    int N;\n    if (M <= 15 && epsilon <= 0.05) {\n        N = 20;\n    } else if (M <= 25 && epsilon <= 0.1) {\n        N = 30;\n    } else if (M <= 40 && epsilon <= 0.15) {\n        N = 50;\n    } else if (M <= 60 && epsilon <= 0.25) {\n        N = 70;\n    } else {\n        N = 100;\n    }\n\n    const int T = N * (N - 1) / 2;\n    int g = T / (M - 1);\n    if (g < 1) g = 1;\n\n    // Precompute prototype degree sequences with optimized edge assignment\n    vector<vector<int>> proto_degrees(M, vector<int>(N, 0));\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        \n        // More balanced edge assignment to maximize degree sequence distinctiveness\n        vector<int> deg(N, 0);\n        if (edge_count > 0) {\n            // Distribute edges to create distinct degree profiles\n            int remaining = edge_count;\n            int current_vertex = 0;\n            while (remaining > 0) {\n                for (int j = current_vertex + 1; j < N && remaining > 0; j++) {\n                    if (deg[current_vertex] < N - 1) {\n                        deg[current_vertex]++;\n                        deg[j]++;\n                        remaining--;\n                    }\n                }\n                current_vertex = (current_vertex + 1) % N;\n            }\n        }\n        sort(deg.begin(), deg.end());\n        proto_degrees[k] = deg;\n    }\n\n    // Precompute expected degree sequences after noise\n    vector<vector<double>> proto_expected(M, vector<double>(N, 0));\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < N; i++) {\n            proto_expected[k][i] = proto_degrees[k][i] * (1 - 2 * epsilon) + (N - 1) * epsilon;\n        }\n    }\n\n    // Output graphs\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        string s = \"\";\n        int count = 0;\n        // Use the same edge assignment as in degree sequence calculation\n        vector<int> deg(N, 0);\n        if (edge_count > 0) {\n            int remaining = edge_count;\n            int current_vertex = 0;\n            while (remaining > 0) {\n                for (int j = current_vertex + 1; j < N && remaining > 0; j++) {\n                    if (deg[current_vertex] < N - 1) {\n                        deg[current_vertex]++;\n                        deg[j]++;\n                        remaining--;\n                    }\n                }\n                current_vertex = (current_vertex + 1) % N;\n            }\n        }\n        // Convert degree assignment to edge string\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                // Check if this edge was assigned in our degree calculation\n                bool edge_exists = false;\n                if (deg[i] > 0 && deg[j] > 0) {\n                    // We need to reconstruct the edge existence from degrees\n                    // This is a simplification - in practice, we should store the edge matrix\n                    // For now, we'll use a heuristic: if both degrees are positive, assume edge exists\n                    // But this might not be accurate\n                    // Instead, let's generate edges in the same order as degree calculation\n                    // We'll recreate the edge assignment\n                    edge_exists = (i < j && deg[i] > 0 && deg[j] > 0);\n                }\n                s += edge_exists ? '1' : '0';\n                count++;\n            }\n        }\n        // Actually, let's generate edges properly based on our degree assignment\n        // We need to reconstruct the edge string from the degree assignment\n        // Since we know the degree sequence, we can try to reconstruct a graph with that degree sequence\n        // But that's complex. Instead, let's use a simpler method: assign edges in canonical order up to edge_count\n        s = \"\";\n        int assigned = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (assigned < edge_count) {\n                    s += '1';\n                    assigned++;\n                } else {\n                    s += '0';\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    // Process queries\n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        vector<int> obs_deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (s[idx] == '1') {\n                    obs_deg[i]++;\n                    obs_deg[j]++;\n                }\n                idx++;\n            }\n        }\n        sort(obs_deg.begin(), obs_deg.end());\n\n        // Use degree sequence method with noise-adjusted expected values\n        double best_dist = 1e18;\n        int best_k = 0;\n        for (int k = 0; k < M; k++) {\n            double dist = 0.0;\n            for (int i = 0; i < N; i++) {\n                double diff = obs_deg[i] - proto_expected[k][i];\n                dist += diff * diff;\n            }\n            // Add small regularization to break ties\n            dist += 1e-6 * k;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_k = k;\n            }\n        }\n        cout << best_k << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long LL;\ntypedef long double LD;\n\nstruct Edge {\n    int to;\n    LL w;\n    int id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<vector<Edge>> adj(N);\n    vector<LL> edge_weight(M);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v;\n        LL w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edge_weight[i] = w;\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n\n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Compute edge betweenness with efficient implementation\n    vector<LD> betweenness(M, 0.0);\n    \n    // Use all vertices for betweenness for accuracy\n    for (int s = 0; s < N; s++) {\n        vector<LL> dist(N, LLONG_MAX);\n        vector<LL> sigma(N, 0);\n        vector<vector<pair<int, int>>> pred(N);\n        \n        // Dijkstra\n        priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<>> pq;\n        dist[s] = 0;\n        sigma[s] = 1;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            for (const auto& e : adj[u]) {\n                LL nd = dist[u] + e.w;\n                if (nd < dist[e.to]) {\n                    dist[e.to] = nd;\n                    sigma[e.to] = sigma[u];\n                    pred[e.to].clear();\n                    pred[e.to].push_back({u, e.id});\n                    pq.push({nd, e.to});\n                } else if (nd == dist[e.to]) {\n                    sigma[e.to] += sigma[u];\n                    pred[e.to].push_back({u, e.id});\n                }\n            }\n        }\n        \n        // Back-propagation\n        vector<LD> delta(N, 0.0);\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n        \n        for (int v : order) {\n            if (dist[v] == LLONG_MAX || v == s) continue;\n            for (auto [u, eid] : pred[v]) {\n                if (sigma[v] == 0) continue;\n                LD contrib = (LD)sigma[u] / sigma[v] * (1.0 + delta[v]);\n                delta[u] += contrib;\n                betweenness[eid] += contrib;\n            }\n        }\n    }\n\n    // Create edge list with cost = betweenness * weight\n    vector<pair<LD, int>> edges;\n    for (int i = 0; i < M; i++) {\n        edges.push_back({betweenness[i] * (LD)edge_weight[i], i});\n    }\n    \n    // Sort by cost descending\n    sort(edges.rbegin(), edges.rend());\n\n    // Assignment strategy: minimize maximum daily cost\n    vector<LD> day_cost(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<int> ans(M, -1);\n    \n    // Phase 1: Greedy assignment\n    for (auto& [cost, eid] : edges) {\n        int best_day = -1;\n        LD min_cost = 1e30;\n        \n        for (int d = 0; d < D; d++) {\n            if (day_count[d] < K) {\n                // Prefer days with lower cost\n                if (day_cost[d] < min_cost) {\n                    min_cost = day_cost[d];\n                    best_day = d;\n                }\n            }\n        }\n        \n        if (best_day == -1) {\n            // Emergency fallback\n            for (int d = 0; d < D; d++) {\n                if (day_count[d] < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n            if (best_day == -1) best_day = 0;\n        }\n        \n        ans[eid] = best_day;\n        day_cost[best_day] += cost;\n        day_count[best_day]++;\n    }\n\n    // Phase 2: Local search to reduce maximum daily cost\n    for (int iter = 0; iter < 30; iter++) {\n        // Find current bottleneck day\n        LD max_cost = 0;\n        int max_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_cost[d] > max_cost) {\n                max_cost = day_cost[d];\n                max_day = d;\n            }\n        }\n        \n        if (max_day == -1) break;\n        \n        // Try to move edges from max_day to reduce its cost\n        bool improved = false;\n        for (int e = 0; e < M; e++) {\n            if (ans[e] != max_day) continue;\n            \n            LD e_cost = betweenness[e] * (LD)edge_weight[e];\n            int best_target = -1;\n            LD best_improvement = 0;\n            \n            for (int d = 0; d < D; d++) {\n                if (d == max_day || day_count[d] >= K) continue;\n                \n                // Calculate improvement if we move edge e from max_day to d\n                LD current_gap = max_cost - day_cost[d];\n                LD improvement = e_cost - current_gap;\n                \n                // Also consider load balancing\n                if (day_cost[d] + e_cost < max_cost) {\n                    improvement += (max_cost - (day_cost[d] + e_cost)) * 0.3;\n                }\n                \n                if (improvement > best_improvement) {\n                    best_improvement = improvement;\n                    best_target = d;\n                }\n            }\n            \n            if (best_target != -1) {\n                // Apply move\n                day_cost[max_day] -= e_cost;\n                day_cost[best_target] += e_cost;\n                day_count[max_day]--;\n                day_count[best_target]++;\n                ans[e] = best_target;\n                improved = true;\n                break;\n            }\n        }\n        \n        if (!improved) break;\n    }\n\n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i) cout << \" \";\n        cout << ans[i] + 1;\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> is_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\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                bool in1 = (f1[z][x] == '1' && r1[z][y] == '1');\n                bool in2 = (f2[z][x] == '1' && r2[z][y] == '1');\n                if (in1 && in2) {\n                    is_common[x][y][z] = true;\n                } else if (in1) {\n                    is_only1[x][y][z] = true;\n                } else if (in2) {\n                    is_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<int>>> block1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> block2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    int next_block_id = 1;\n    vector<int> dx = {1, -1, 0, 0, 0, 0};\n    vector<int> dy = {0, 0, 1, -1, 0, 0};\n    vector<int> dz = {0, 0, 0, 0, 1, -1};\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 (is_common[x][y][z] && !visited[x][y][z]) {\n                    queue<tuple<int, int, int>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    block1[x][y][z] = next_block_id;\n                    block2[x][y][z] = next_block_id;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D) {\n                                if (is_common[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                    visited[nx][ny][nz] = true;\n                                    block1[nx][ny][nz] = next_block_id;\n                                    block2[nx][ny][nz] = next_block_id;\n                                    q.push({nx, ny, nz});\n                                }\n                            }\n                        }\n                    }\n                    next_block_id++;\n                }\n            }\n        }\n    }\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 (is_only1[x][y][z]) {\n                    block1[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n                if (is_only2[x][y][z]) {\n                    block2[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n            }\n        }\n    }\n\n    cout << next_block_id - 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 << block1[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 << block2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstring>\n#include <random>\n\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nconst double INF = 1e18;\nconst int MAXN = 100;\nconst int MAXM = 300;\nconst int MAXK = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nvector<pii> edges;\nint w[MAXM];\ndouble resident_x[MAXK], resident_y[MAXK];\n\nvector<pair<int, int>> adj[MAXN];\ndouble dist_2d[MAXN][MAXN];\nint parent_2d[MAXN][MAXN];\n\nmap<pii, int> edge_index_map;\n\ndouble euclid(double x1, double y1, double x2, double y2) {\n    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));\n}\n\nvoid dijkstra(int src) {\n    for (int i = 0; i < N; i++) {\n        dist_2d[src][i] = INF;\n        parent_2d[src][i] = -1;\n    }\n    dist_2d[src][src] = 0;\n    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n    pq.push({0, src});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n        if (d != dist_2d[src][u]) continue;\n        for (auto &edge : adj[u]) {\n            int v = edge.first;\n            int weight = edge.second;\n            double new_d = d + weight;\n            if (new_d < dist_2d[src][v]) {\n                dist_2d[src][v] = new_d;\n                parent_2d[src][v] = u;\n                pq.push({new_d, v});\n            }\n        }\n    }\n}\n\nvector<int> get_path(int src, int dest) {\n    vector<int> path;\n    if (dist_2d[src][dest] >= INF) return path;\n    int cur = dest;\n    while (cur != src) {\n        path.push_back(cur);\n        cur = parent_2d[src][cur];\n    }\n    path.push_back(src);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstruct Edge {\n    int u, v;\n    double weight;\n    bool operator<(const Edge& other) const {\n        return weight < other.weight;\n    }\n};\n\nvector<int> parent_kruskal;\n\nint find_set(int v) {\n    if (v == parent_kruskal[v]) return v;\n    return parent_kruskal[v] = find_set(parent_kruskal[v]);\n}\n\nbool union_sets(int a, int b) {\n    a = find_set(a);\n    b = find_set(b);\n    if (a == b) return false;\n    parent_kruskal[b] = a;\n    return true;\n}\n\nvoid build_MST_on_T(const vector<int>& T_list, vector<pii>& MST_edges) {\n    int t_size = T_list.size();\n    map<int, int> comp;\n    for (int i = 0; i < t_size; i++) {\n        comp[T_list[i]] = i;\n    }\n\n    vector<Edge> edges_complete;\n    for (int i = 0; i < t_size; i++) {\n        for (int j = i+1; j < t_size; j++) {\n            int u = T_list[i];\n            int v = T_list[j];\n            double d = dist_2d[u][v];\n            edges_complete.push_back({u, v, d});\n        }\n    }\n\n    sort(edges_complete.begin(), edges_complete.end());\n\n    parent_kruskal.resize(t_size);\n    for (int i = 0; i < t_size; i++) parent_kruskal[i] = i;\n\n    MST_edges.clear();\n    for (const Edge& e : edges_complete) {\n        int u_comp = comp[e.u];\n        int v_comp = comp[e.v];\n        if (union_sets(u_comp, v_comp)) {\n            MST_edges.push_back({e.u, e.v});\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> K;\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    for (int j = 0; j < M; j++) {\n        int u, v, weight;\n        cin >> u >> v >> weight;\n        u--; v--;\n        edges.push_back({u, v});\n        w[j] = weight;\n        adj[u].push_back({v, weight});\n        adj[v].push_back({u, weight});\n        int a = min(u, v);\n        int b = max(u, v);\n        edge_index_map[{a, b}] = j;\n    }\n    for (int k = 0; k < K; k++) {\n        cin >> resident_x[k] >> resident_y[k];\n    }\n\n    // Precompute all-pairs shortest paths\n    for (int i = 0; i < N; i++) {\n        dijkstra(i);\n    }\n\n    // Find closest node for each resident\n    vector<int> best_node(K);\n    vector<double> min_dist(K);\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best = -1;\n        for (int i = 0; i < N; i++) {\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d < min_d) {\n                min_d = d;\n                best = i;\n            }\n        }\n        best_node[k] = best;\n        min_dist[k] = min_d;\n    }\n\n    // Node selection with cost-benefit analysis\n    vector<int> T_list;\n    vector<bool> inT(N, false);\n    vector<double> d_T(K);\n    \n    T_list.push_back(0);\n    inT[0] = true;\n\n    for (int k = 0; k < K; k++) {\n        d_T[k] = euclid(resident_x[k], resident_y[k], x[0], y[0]);\n    }\n\n    set<int> uncovered;\n    for (int k = 0; k < K; k++) {\n        uncovered.insert(k);\n    }\n\n    while (!uncovered.empty()) {\n        int k0 = -1;\n        double max_d = -1;\n        for (int k : uncovered) {\n            if (d_T[k] > max_d) {\n                max_d = d_T[k];\n                k0 = k;\n            }\n        }\n\n        if (d_T[k0] <= 5000) {\n            uncovered.erase(k0);\n            continue;\n        }\n\n        int best_i = -1;\n        double best_benefit = -1e18;\n        \n        for (int i = 0; i < N; i++) {\n            if (inT[i]) continue;\n            \n            int count_covered = 0;\n            double total_reduction = 0;\n            for (int k : uncovered) {\n                double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n                if (d <= 5000) {\n                    count_covered++;\n                    total_reduction += (d_T[k] * d_T[k] - d * d);\n                }\n            }\n            \n            if (count_covered == 0) continue;\n            \n            double min_edge_cost = INF;\n            for (int existing : T_list) {\n                min_edge_cost = min(min_edge_cost, dist_2d[i][existing]);\n            }\n            \n            double benefit = total_reduction - min_edge_cost;\n            if (benefit > best_benefit) {\n                best_benefit = benefit;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) {\n            best_i = best_node[k0];\n        }\n        \n        if (!inT[best_i]) {\n            T_list.push_back(best_i);\n            inT[best_i] = true;\n            for (int k = 0; k < K; k++) {\n                double d = euclid(resident_x[k], resident_y[k], x[best_i], y[best_i]);\n                if (d < d_T[k]) {\n                    d_T[k] = d;\n                }\n            }\n        }\n        \n        vector<int> to_remove;\n        for (int k : uncovered) {\n            if (d_T[k] <= 5000) {\n                to_remove.push_back(k);\n            }\n        }\n        for (int k : to_remove) {\n            uncovered.erase(k);\n        }\n    }\n\n    vector<pii> MST_edges;\n    if (T_list.size() > 1) {\n        build_MST_on_T(T_list, MST_edges);\n    }\n\n    set<int> activated_edges;\n    for (auto &e : MST_edges) {\n        int u = e.first;\n        int v = e.second;\n        vector<int> path = get_path(u, v);\n        for (int idx = 0; idx < (int)path.size()-1; idx++) {\n            int a = path[idx];\n            int b = path[idx+1];\n            int aa = min(a, b);\n            int bb = max(a, b);\n            auto key = make_pair(aa, bb);\n            if (edge_index_map.find(key) != edge_index_map.end()) {\n                int j = edge_index_map[key];\n                activated_edges.insert(j);\n            }\n        }\n    }\n\n    vector<bool> inV_prime(N, false);\n    vector<vector<int>> adj_steiner(N);\n    for (int j : activated_edges) {\n        int u = edges[j].first;\n        int v = edges[j].second;\n        adj_steiner[u].push_back(v);\n        adj_steiner[v].push_back(u);\n    }\n    queue<int> q;\n    q.push(0);\n    inV_prime[0] = true;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj_steiner[u]) {\n            if (!inV_prime[v]) {\n                inV_prime[v] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    vector<int> V_prime;\n    for (int i = 0; i < N; i++) {\n        if (inV_prime[i]) {\n            V_prime.push_back(i);\n        }\n    }\n\n    // Precompute distances from residents to nodes in V_prime\n    vector<vector<double>> dist_res_node(K, vector<double>(N, 0.0));\n    for (int k = 0; k < K; k++) {\n        for (int i : V_prime) {\n            dist_res_node[k][i] = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n        }\n    }\n\n    // Initial assignment\n    vector<int> assign(K, -1);\n    vector<vector<int>> residents(N);\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best_i = -1;\n        for (int i : V_prime) {\n            double d = dist_res_node[k][i];\n            if (d < min_d) {\n                min_d = d;\n                best_i = i;\n            }\n        }\n        assign[k] = best_i;\n        residents[best_i].push_back(k);\n    }\n\n    // Statistics for efficient reassignment\n    vector<double> max1(N, 0.0);\n    vector<int> count_max1(N, 0);\n    vector<double> max2(N, 0.0);\n\n    for (int i : V_prime) {\n        if (residents[i].empty()) {\n            max1[i] = 0;\n            count_max1[i] = 0;\n            max2[i] = 0;\n            continue;\n        }\n        double m1 = 0, m2 = 0;\n        int cnt = 0;\n        for (int k : residents[i]) {\n            double d = dist_res_node[k][i];\n            if (d > m1) {\n                m2 = m1;\n                m1 = d;\n                cnt = 1;\n            } else if (d == m1) {\n                cnt++;\n            } else if (d > m2) {\n                m2 = d;\n            }\n        }\n        max1[i] = m1;\n        count_max1[i] = cnt;\n        max2[i] = m2;\n    }\n\n    // Enhanced reassignment\n    int iter = 0;\n    bool improved = true;\n    while (improved && iter < 50) {\n        improved = false;\n        double best_reduction = 0;\n        int best_k = -1, best_j = -1, best_i = -1;\n\n        for (int k = 0; k < K; k++) {\n            int i = assign[k];\n            for (int j : V_prime) {\n                if (j == i) continue;\n                double d_i = dist_res_node[k][i];\n                double d_j = dist_res_node[k][j];\n                \n                double new_max_i;\n                if (d_i == max1[i]) {\n                    if (count_max1[i] > 1) {\n                        new_max_i = max1[i];\n                    } else {\n                        new_max_i = max2[i];\n                    }\n                } else {\n                    new_max_i = max1[i];\n                }\n                \n                double new_max_j = max(max1[j], d_j);\n                \n                double reduction = max1[i]*max1[i] + max1[j]*max1[j] - (new_max_i*new_max_i + new_max_j*new_max_j);\n                \n                if (reduction > best_reduction) {\n                    best_reduction = reduction;\n                    best_k = k;\n                    best_j = j;\n                    best_i = i;\n                }\n            }\n        }\n\n        if (best_reduction > 1e-9) {\n            residents[best_i].erase(remove(residents[best_i].begin(), residents[best_i].end(), best_k), residents[best_i].end());\n            residents[best_j].push_back(best_k);\n            assign[best_k] = best_j;\n\n            for (int node : {best_i, best_j}) {\n                if (residents[node].empty()) {\n                    max1[node] = 0;\n                    count_max1[node] = 0;\n                    max2[node] = 0;\n                } else {\n                    double m1 = 0, m2 = 0;\n                    int cnt = 0;\n                    for (int k : residents[node]) {\n                        double d = dist_res_node[k][node];\n                        if (d > m1) {\n                            m2 = m1;\n                            m1 = d;\n                            cnt = 1;\n                        } else if (d == m1) {\n                            cnt++;\n                        } else if (d > m2) {\n                            m2 = d;\n                        }\n                    }\n                    max1[node] = m1;\n                    count_max1[node] = cnt;\n                    max2[node] = m2;\n                }\n            }\n\n            improved = true;\n            iter++;\n        }\n    }\n\n    // Set output strengths\n    vector<int> P(N, 0);\n    for (int i : V_prime) {\n        if (max1[i] > 0) {\n            P[i] = ceil(max1[i]);\n            if (P[i] > 5000) P[i] = 5000;\n        }\n    }\n\n    // Set edge activation\n    vector<int> B(M, 0);\n    for (int j : activated_edges) {\n        B[j] = 1;\n    }\n\n    // Output\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << endl;\n\n    for (int j = 0; j < M; j++) {\n        if (j > 0) cout << \" \";\n        cout << B[j];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N = 30;\n    vector<vector<int>> grid(N);\n    for (int i = 0; i < N; i++) {\n        grid[i].resize(i+1);\n        for (int j = 0; j <= i; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n    priority_queue<tuple<int, int, int>> pq;\n\n    auto check_and_push = [&](int x, int y) {\n        if (x < 0 || x >= N-1 || y < 0 || y > x) return;\n        if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n            pq.push({grid[x][y], x, y});\n        }\n    };\n\n    // Initial push of all violating nodes\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            check_and_push(x, y);\n        }\n    }\n\n    while (!pq.empty() && swaps.size() < 10000) {\n        auto [val, x, y] = pq.top();\n        pq.pop();\n        \n        // Check if this node still violates the condition\n        if (grid[x][y] <= grid[x+1][y] && grid[x][y] <= grid[x+1][y+1]) {\n            continue;\n        }\n\n        // Find the smaller child\n        int min_x = x+1;\n        int min_y = (grid[x+1][y] < grid[x+1][y+1]) ? y : y+1;\n        \n        // Swap\n        swap(grid[x][y], grid[min_x][min_y]);\n        swaps.push_back({x, y, min_x, min_y});\n\n        // Push affected nodes\n        check_and_push(x, y);          // The node that moved up\n        check_and_push(min_x, min_y);   // The node that moved down\n        check_and_push(x-1, y-1);       // Left parent of the moved up node\n        check_and_push(x-1, y);         // Right parent of the moved up node\n    }\n\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <utility>\nusing namespace std;\n\nconst int MAX_D = 9;\nconst int entrance_i = 0;\nconst int entrance_j = 4;\nint dx[4] = {1, -1, 0, 0};\nint dy[4] = {0, 0, 1, -1};\n\nint main() {\n    int D, N;\n    cin >> D >> N;\n    bool obstacle[MAX_D][MAX_D] = {false};\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N;\n    bool occupied[MAX_D][MAX_D] = {false};\n    int container_number[MAX_D][MAX_D];\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            container_number[i][j] = -1;\n        }\n    }\n\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n\n        vector<vector<int>> dist(MAX_D, vector<int>(MAX_D, -1));\n        queue<pair<int, int>> q;\n        dist[entrance_i][entrance_j] = 0;\n        q.push({entrance_i, entrance_j});\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && !occupied[ni][nj] && dist[ni][nj] == -1) {\n                        dist[ni][nj] = dist[i][j] + 1;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> available;\n        for (int i = 0; i < MAX_D; i++) {\n            for (int j = 0; j < MAX_D; j++) {\n                if (dist[i][j] != -1 && !(i == entrance_i && j == entrance_j)) {\n                    available.push_back({i, j});\n                }\n            }\n        }\n\n        sort(available.begin(), available.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            if (dist[a.first][a.second] != dist[b.first][b.second]) {\n                return dist[a.first][a.second] < dist[b.first][b.second];\n            }\n            if (a.first != b.first) {\n                return a.first < b.first;\n            }\n            return a.second < b.second;\n        });\n\n        if (available.empty()) {\n            continue;\n        }\n\n        int k = (t * available.size()) / M;\n        auto chosen = available[k];\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n\n        occupied[chosen.first][chosen.second] = true;\n        container_number[chosen.first][chosen.second] = t;\n    }\n\n    vector<vector<bool>> empty(MAX_D, vector<bool>(MAX_D, false));\n    empty[entrance_i][entrance_j] = true;\n\n    vector<pair<int, int>> containers;\n    for (int i = 0; i < MAX_D; i++) {\n        for (int j = 0; j < MAX_D; j++) {\n            if (occupied[i][j]) {\n                containers.push_back({i, j});\n            }\n        }\n    }\n\n    vector<pair<int, int>> removal_order;\n\n    while (!containers.empty()) {\n        vector<vector<bool>> visited(MAX_D, vector<bool>(MAX_D, false));\n        queue<pair<int, int>> q;\n        q.push({entrance_i, entrance_j});\n        visited[entrance_i][entrance_j] = true;\n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (!obstacle[ni][nj] && empty[ni][nj] && !visited[ni][nj]) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        vector<int> removable_indices;\n        for (int idx = 0; idx < containers.size(); idx++) {\n            auto [i, j] = containers[idx];\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < MAX_D && nj >= 0 && nj < MAX_D) {\n                    if (visited[ni][nj]) {\n                        removable_indices.push_back(idx);\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (removable_indices.empty()) {\n            break;\n        }\n\n        int min_num = 1000000;\n        int best_idx = -1;\n        for (int idx : removable_indices) {\n            auto [i, j] = containers[idx];\n            int num = container_number[i][j];\n            if (num < min_num) {\n                min_num = num;\n                best_idx = idx;\n            }\n        }\n\n        auto coord = containers[best_idx];\n        removal_order.push_back(coord);\n        empty[coord.first][coord.second] = true;\n        swap(containers[best_idx], containers.back());\n        containers.pop_back();\n    }\n\n    for (auto [i, j] : removal_order) {\n        cout << i << \" \" << j << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c;\n            cin >> c;\n            cout << c;\n            if (j < n-1) cout << \" \";\n        }\n        cout << endl;\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n#include <cmath>\n#include <iomanip>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Phase 1: Robust weight estimation using insertion sort with refinement\n    vector<int> order;\n    int queries_used = 0;\n    \n    // Build initial order with binary search insertion\n    for (int i = 0; i < N; i++) {\n        int low = 0, high = order.size();\n        while (low < high && queries_used < Q) {\n            int mid = (low + high) / 2;\n            cout << \"1 1 \" << i << \" \" << order[mid] << endl;\n            cout.flush();\n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \">\") {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        order.insert(order.begin() + low, i);\n    }\n    \n    // Refine the order using remaining queries\n    // Use a more sophisticated approach: compare items that are likely to be out of order\n    while (queries_used < Q) {\n        bool found = false;\n        // Try to find two adjacent items that might be in wrong order\n        for (int i = 0; i < (int)order.size() - 1 && queries_used < Q; i++) {\n            // Compare order[i] and order[i+1]\n            cout << \"1 1 \" << order[i] << \" \" << order[i+1] << endl;\n            cout.flush();\n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \"<\") {\n                // order[i] is lighter than order[i+1], so swap\n                swap(order[i], order[i+1]);\n                found = true;\n            }\n        }\n        \n        // If no swaps, try random pairs\n        if (!found && queries_used < Q) {\n            // Compare random items that are not adjacent\n            int i = rand() % N;\n            int j = rand() % N;\n            if (i != j && queries_used < Q) {\n                cout << \"1 1 \" << order[i] << \" \" << order[j] << endl;\n                cout.flush();\n                string res;\n                cin >> res;\n                queries_used++;\n                \n                // Update order based on result\n                if (res == \">\" && i < j) {\n                    // order[i] is heavier, should come before order[j]\n                    // But we need to find their positions\n                    auto it_i = find(order.begin(), order.end(), order[i]);\n                    auto it_j = find(order.begin(), order.end(), order[j]);\n                    if (it_i > it_j) {\n                        swap(*it_i, *it_j);\n                    }\n                } else if (res == \"<\" && i > j) {\n                    auto it_i = find(order.begin(), order.end(), order[i]);\n                    auto it_j = find(order.begin(), order.end(), order[j]);\n                    if (it_i < it_j) {\n                        swap(*it_i, *it_j);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Try multiple assignment strategies and pick the best\n    vector<int> best_assignment;\n    double best_variance = 1e18;\n    \n    // Strategy 1: Simple greedy by order\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            int min_set = 0;\n            for (int d = 1; d < D; d++) {\n                if (set_totals[d] < set_totals[min_set]) {\n                    min_set = d;\n                }\n            }\n            assignment[item] = min_set;\n            set_totals[min_set] += (N - i); // Weight estimate\n        }\n        \n        // Calculate variance\n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 2: Round-robin assignment\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            assignment[item] = i % D;\n            set_totals[i % D] += (N - i);\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 3: Alternate assignment (heaviest to smallest set, then lightest to largest set)\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            if (i % 2 == 0) {\n                // Heaviest items: assign to smallest set\n                int min_set = 0;\n                for (int d = 1; d < D; d++) {\n                    if (set_totals[d] < set_totals[min_set]) {\n                        min_set = d;\n                    }\n                }\n                assignment[item] = min_set;\n                set_totals[min_set] += (N - i);\n            } else {\n                // Lightest items: assign to largest set\n                int max_set = 0;\n                for (int d = 1; d < D; d++) {\n                    if (set_totals[d] > set_totals[max_set]) {\n                        max_set = d;\n                    }\n                }\n                assignment[item] = max_set;\n                set_totals[max_set] += (N - i);\n            }\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 4: Use the sorted order but with weighted assignment\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        // Use exponential weights: heaviest items get much higher weight\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            double weight = pow(2.0, (N - i) / (N / 4.0)); // Exponential weighting\n            int min_set = 0;\n            for (int d = 1; d < D; d++) {\n                if (set_totals[d] < set_totals[min_set]) {\n                    min_set = d;\n                }\n            }\n            assignment[item] = min_set;\n            set_totals[min_set] += weight;\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Output the best assignment found\n    for (int i = 0; i < N; i++) {\n        cout << best_assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cout.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    int per_stack = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < per_stack; ++j) {\n            int x;\n            cin >> x;\n            stacks[i].push_back(x);\n        }\n    }\n\n    vector<int> stack_of(n + 1, -1);\n    vector<int> idx_in_stack(n + 1, -1);\n\n    auto recompute = [&]() {\n        fill(stack_of.begin(), stack_of.end(), -1);\n        fill(idx_in_stack.begin(), idx_in_stack.end(), -1);\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                int box = stacks[i][j];\n                stack_of[box] = i;\n                idx_in_stack[box] = j;\n            }\n        }\n    };\n\n    vector<pair<int, int>> ops;\n\n    for (int v = 1; v <= n; ++v) {\n        recompute();\n        int s = stack_of[v];\n        int i = idx_in_stack[v];\n\n        if (i == (int)stacks[s].size() - 1) {\n            ops.emplace_back(v, 0);\n            stacks[s].pop_back();\n            continue;\n        }\n\n        int B = stacks[s][i + 1];\n        int candidate = -1;\n        int min_size = 1000;\n\n        // Find the stack with the smallest number of boxes (excluding current stack)\n        for (int d = 0; d < m; ++d) {\n            if (d == s) continue;\n            if (stacks[d].size() < min_size) {\n                min_size = stacks[d].size();\n                candidate = d;\n            }\n        }\n\n        // If no candidate found (shouldn't happen), choose any other stack\n        if (candidate == -1) {\n            for (int d = 0; d < m; ++d) {\n                if (d != s) {\n                    candidate = d;\n                    break;\n                }\n            }\n        }\n\n        // Move the entire group above v to candidate stack\n        for (int j = i + 1; j < (int)stacks[s].size(); ++j) {\n            stacks[candidate].push_back(stacks[s][j]);\n        }\n        stacks[s].resize(i + 1);\n        ops.emplace_back(B, candidate + 1);\n\n        // Carry out v\n        ops.emplace_back(v, 0);\n        stacks[s].pop_back();\n    }\n\n    for (auto &p : ops) {\n        cout << p.first << \" \" << p.second << \"\\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;\nvector<vector<bool>> visited;\nstring moves = \"\";\n\n// Direction vectors: right, down, left, up\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'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    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check walls based on direction\n    if (dir == 0) { // right\n        return v[i][j] == '0';\n    } else if (dir == 1) { // down\n        return h[i][j] == '0';\n    } else if (dir == 2) { // left\n        return j > 0 && v[i][j-1] == '0';\n    } else { // up\n        return i > 0 && h[i-1][j] == '0';\n    }\n}\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    \n    // Collect all possible moves to unvisited squares\n    vector<tuple<int, int, int>> candidates; // (d_value, new_i, new_j)\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n            !visited[ni][nj] && can_move(i, j, dir)) {\n            candidates.emplace_back(d[ni][nj], ni, nj);\n        }\n    }\n    \n    // Sort by susceptibility in descending order - visit high-susceptibility squares first\n    sort(candidates.begin(), candidates.end(), [](const tuple<int,int,int>& a, const tuple<int,int,int>& b) {\n        return get<0>(a) > get<0>(b);\n    });\n    \n    for (auto& candidate : candidates) {\n        int new_d = get<0>(candidate);\n        int ni = get<1>(candidate);\n        int nj = get<2>(candidate);\n        \n        // Determine direction\n        int dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (i + di[d] == ni && j + dj[d] == nj) {\n                dir = d;\n                break;\n            }\n        }\n        \n        // Move to the new square\n        moves += dir_char[dir];\n        dfs(ni, nj);\n        \n        // Move back\n        moves += dir_char[(dir + 2) % 4];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    visited.assign(N, vector<bool>(N, false));\n    \n    dfs(0, 0);\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 15;\nconst int NN = GRID_SIZE * GRID_SIZE;\nconst int INF = 1e9;\n\nvector<int> pos[26];  // positions (linear index) for each letter\n\ninline int row(int idx) { return idx / GRID_SIZE; }\ninline int col(int idx) { return idx % GRID_SIZE; }\n\n// Manhattan distance transform: out[v] = min_u (cur[u] + dist(u, v))\nvoid dist_transform(const vector<int>& cur, vector<int>& out) {\n    int val[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j)\n            val[i][j] = cur[i * GRID_SIZE + j];\n\n    int tmp[GRID_SIZE][GRID_SIZE];\n    // horizontal pass\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        // left to right\n        tmp[i][0] = val[i][0];\n        for (int j = 1; j < GRID_SIZE; ++j) {\n            int a = val[i][j];\n            int b = tmp[i][j-1] + 1;\n            tmp[i][j] = a < b ? a : b;\n        }\n        // right to left\n        for (int j = GRID_SIZE - 2; j >= 0; --j) {\n            int b = tmp[i][j+1] + 1;\n            if (b < tmp[i][j]) tmp[i][j] = b;\n        }\n    }\n\n    // vertical pass\n    for (int j = 0; j < GRID_SIZE; ++j) {\n        // top to bottom\n        out[0 * GRID_SIZE + j] = tmp[0][j];\n        for (int i = 1; i < GRID_SIZE; ++i) {\n            int a = tmp[i][j];\n            int b = out[(i-1) * GRID_SIZE + j] + 1;\n            out[i * GRID_SIZE + j] = a < b ? a : b;\n        }\n        // bottom to top\n        for (int i = GRID_SIZE - 2; i >= 0; --i) {\n            int b = out[(i+1) * GRID_SIZE + j] + 1;\n            if (b < out[i * GRID_SIZE + j]) out[i * GRID_SIZE + j] = b;\n        }\n    }\n}\n\n// Compute minimal additional cost to type X from current distribution dp\nint compute_cost(const vector<int>& dp, const string& X,\n                 vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    int ans = INF;\n    for (int v : pos[X.back() - 'A'])\n        if (cur[v] < ans) ans = cur[v];\n    return ans;\n}\n\n// Extend dp by typing X, returning the new distribution\nvector<int> extend_dp(const vector<int>& dp, const string& X,\n                      vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    return cur;\n}\n\n// Reconstruct the optimal sequence of squares for typing X\nvector<int> reconstruct_path(const vector<int>& dp, const string& X) {\n    int L = X.size();\n    vector<vector<int>> cost(L + 1, vector<int>(NN, INF));\n    vector<vector<int>> prev(L + 1, vector<int>(NN, -1));\n\n    // pos 0\n    for (int u = 0; u < NN; ++u) cost[0][u] = dp[u];\n\n    for (int p = 0; p < L; ++p) {\n        char c = X[p];\n        for (int v : pos[c - 'A']) {\n            for (int u = 0; u < NN; ++u) {\n                if (cost[p][u] == INF) continue;\n                int d = abs(row(u) - row(v)) + abs(col(u) - col(v));\n                int new_cost = cost[p][u] + d + 1;\n                if (new_cost < cost[p+1][v]) {\n                    cost[p+1][v] = new_cost;\n                    prev[p+1][v] = u;\n                }\n            }\n        }\n    }\n\n    // find best end\n    int best_v = -1, best_cost = INF;\n    for (int v : pos[X.back() - 'A']) {\n        if (cost[L][v] < best_cost) {\n            best_cost = cost[L][v];\n            best_v = v;\n        }\n    }\n\n    // backtrack\n    vector<int> path(L);\n    int cur_v = best_v;\n    for (int p = L; p >= 1; --p) {\n        path[p-1] = cur_v;\n        cur_v = prev[p][cur_v];\n    }\n    return path;\n}\n\n// Compute maximum overlap (0..4) between suffix of S and prefix of tk\nint compute_overlap(const string& S, const string& tk) {\n    int slen = S.size();\n    int max_possible = min(4, slen);\n    for (int l = max_possible; l >= 1; --l) {\n        if (S.compare(slen - l, l, tk, 0, l) == 0)\n            return l;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_input, M;\n    cin >> N_input >> M;\n    int si, sj;\n    cin >> si >> sj;\n\n    // read grid\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            char c = row[j];\n            pos[c - 'A'].push_back(i * GRID_SIZE + j);\n        }\n    }\n\n    // read target strings\n    vector<string> t(M);\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    // initial state\n    vector<int> dp(NN, INF);\n    int start_idx = si * GRID_SIZE + sj;\n    dp[start_idx] = 0;\n\n    string S = \"\";\n    vector<pair<int, int>> ops;\n    vector<bool> covered(M, false);\n\n    // buffers for DP\n    vector<int> cur_buf(NN), minDist_buf(NN), next_buf(NN);\n\n    while (true) {\n        // check if all covered\n        bool all_covered = true;\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k]) {\n                all_covered = false;\n                break;\n            }\n        }\n        if (all_covered) break;\n\n        int best_k = -1;\n        int best_cost_val = INF;\n        string best_X;\n\n        // evaluate all uncovered t_k\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n            const string& tk = t[k];\n            int overlap = compute_overlap(S, tk);\n            string X = tk.substr(overlap);\n            if (X.empty()) {   // already covered\n                covered[k] = true;\n                continue;\n            }\n            int cost = compute_cost(dp, X, cur_buf, minDist_buf, next_buf);\n            if (cost < best_cost_val) {\n                best_cost_val = cost;\n                best_k = k;\n                best_X = X;\n            }\n        }\n\n        if (best_k == -1) break;  // nothing left to type\n\n        // reconstruct the optimal path for best_X\n        vector<int> path = reconstruct_path(dp, best_X);\n        for (int idx : path) {\n            ops.push_back({row(idx), col(idx)});\n        }\n\n        // update dp and S\n        dp = extend_dp(dp, best_X, cur_buf, minDist_buf, next_buf);\n        S += best_X;\n\n        // update covered set\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k] && S.find(t[k]) != string::npos)\n                covered[k] = true;\n        }\n    }\n\n    // output operations\n    for (auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    vector<vector<pair<int, int>>> polyominoes(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        vector<pair<int, int>> poly(d);\n        for (int i = 0; i < d; i++) {\n            cin >> poly[i].first >> poly[i].second;\n        }\n        polyominoes[k] = poly;\n    }\n\n    vector<pair<int, int>> has_oil;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int val;\n            cin >> val;\n            if (val > 0) {\n                has_oil.push_back({i, j});\n            }\n        }\n    }\n\n    cout << \"a \" << has_oil.size();\n    for (auto &p : has_oil) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl;\n    cout.flush();\n\n    int result;\n    cin >> result;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> A(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < N; i++) {\n            cin >> A[d][i];\n        }\n    }\n\n    vector<int> H(D);\n\n    for (int d = 0; d < D; d++) {\n        if (d == 0) {\n            int best_H = 1;\n            int best_value = 1e9;\n            for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                int total_width = 0;\n                for (int i = 0; i < N; i++) {\n                    total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                }\n                if (total_width <= W) {\n                    int value = total_width + N * H_candidate;\n                    if (value < best_value) {\n                        best_value = value;\n                        best_H = H_candidate;\n                    }\n                }\n            }\n            H[d] = best_H;\n        } else {\n            int H_prev = H[d-1];\n            int total_width = 0;\n            for (int i = 0; i < N; i++) {\n                total_width += (A[d][i] + H_prev - 1) / H_prev;\n            }\n            if (total_width <= W) {\n                H[d] = H_prev;\n            } else {\n                int best_H = 1;\n                int best_value = 1e9;\n                for (int H_candidate = 1; H_candidate <= W; H_candidate++) {\n                    int total_width = 0;\n                    for (int i = 0; i < N; i++) {\n                        total_width += (A[d][i] + H_candidate - 1) / H_candidate;\n                    }\n                    if (total_width <= W) {\n                        int value = total_width + N * H_candidate;\n                        if (value < best_value) {\n                            best_value = value;\n                            best_H = H_candidate;\n                        }\n                    }\n                }\n                H[d] = best_H;\n            }\n        }\n    }\n\n    for (int d = 0; d < D; d++) {\n        int top, bottom;\n        if (d == 0) {\n            top = 0;\n            bottom = H[d];\n        } else {\n            if (H[d] <= H[d-1]) {\n                top = H[d-1] - H[d];\n                bottom = H[d-1];\n            } else {\n                top = 0;\n                bottom = H[d];\n            }\n        }\n        int left = 0;\n        for (int i = 0; i < N; i++) {\n            int width = (A[d][i] + H[d] - 1) / H[d];\n            int right = left + width;\n            cout << top << \" \" << left << \" \" << bottom << \" \" << right << endl;\n            left = right;\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <climits>\n\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    int rem[9][9];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> rem[i][j];\n            rem[i][j] %= MOD;\n        }\n    }\n\n    int s[20][3][3];\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n\n    for (int step = 0; step < K; step++) {\n        long long best_change = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= 6; p++) {\n                for (int q = 0; q <= 6; q++) {\n                    long long change = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int r = rem[p+i][q+j];\n                            int s_val = s[m][i][j];\n                            if (r + s_val < MOD) {\n                                change += s_val;\n                            } else {\n                                change += s_val - MOD;\n                            }\n                        }\n                    }\n                    if (change > best_change) {\n                        best_change = change;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_change <= 0) {\n            break;\n        }\n\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int &r = rem[best_p+i][best_q+j];\n                int s_val = s[best_m][i][j];\n                if (r + s_val < MOD) {\n                    r += s_val;\n                } else {\n                    r = r + s_val - MOD;\n                }\n            }\n        }\n\n        ops.push_back(make_tuple(best_m, best_p, best_q));\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto op : ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\n\nstruct Crane {\n    int x, y;\n    int carrying; // -1 if not carrying, else container number\n};\n\nint grid[MAX_N][MAX_N]; // -1: empty, else container number\nCrane cranes[MAX_N];\nint placed[MAX_N]; // number of containers placed at each receiving gate\nint current_target; // next container to dispatch\n\nvoid init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        placed[i] = 0;\n    }\n    for (int i = 0; i < N; i++) {\n        cranes[i] = {i, 0, -1};\n    }\n    current_target = 0;\n}\n\n// Move towards target position with bounds checking\nchar move_towards(int x, int y, int target_x, int target_y) {\n    if (x < target_x) return 'D';\n    if (x > target_x) return 'U';\n    if (y < target_y) return 'R';\n    if (y > target_y) return 'L';\n    return '.';\n}\n\nint main() {\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    init();\n\n    vector<string> actions_per_crane(N, \"\");\n    int total_containers = N * N;\n\n    for (int turn = 0; turn < MAX_TURNS && current_target < total_containers; turn++) {\n        // Step 1: Container arrival\n        for (int i = 0; i < N; i++) {\n            bool crane_at_gate = false;\n            for (int k = 0; k < N; k++) {\n                if (cranes[k].x == i && cranes[k].y == 0) {\n                    crane_at_gate = true;\n                    break;\n                }\n            }\n            if (placed[i] < N && grid[i][0] == -1 && !crane_at_gate) {\n                grid[i][0] = A[i][placed[i]];\n                placed[i]++;\n            }\n        }\n\n        // Prepare for crane actions\n        Crane next_cranes[MAX_N];\n        for (int i = 0; i < N; i++) {\n            next_cranes[i] = cranes[i];\n        }\n        int next_grid[MAX_N][MAX_N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                next_grid[i][j] = grid[i][j];\n            }\n        }\n\n        // For collision detection\n        int intended_x[MAX_N], intended_y[MAX_N];\n        for (int i = 0; i < N; i++) {\n            intended_x[i] = cranes[i].x;\n            intended_y[i] = cranes[i].y;\n        }\n\n        // Process each crane in order\n        for (int idx = 0; idx < N; idx++) {\n            char action = '.';\n            Crane& crane = cranes[idx];\n            int x = crane.x;\n            int y = crane.y;\n            int carrying = crane.carrying;\n\n            if (idx == 0) { // Large crane\n                if (carrying != -1) {\n                    // Carrying a container, move to dispatch gate of its row\n                    int target_row = carrying / N;\n                    if (x == target_row && y == N-1) {\n                        // Only release if it's the current target\n                        if (carrying == current_target) {\n                            action = 'Q';\n                        } else {\n                            // Not the current target, move to wait position\n                            if (x != 0 || y != N-1) {\n                                action = move_towards(x, y, 0, N-1);\n                            }\n                        }\n                    } else {\n                        action = move_towards(x, y, target_row, N-1);\n                    }\n                } else {\n                    // Not carrying, look for the current target container\n                    int target_row = current_target / N;\n                    \n                    // Check if current target is at its receiving gate\n                    if (grid[target_row][0] == current_target) {\n                        if (x == target_row && y == 0) {\n                            action = 'P';\n                        } else {\n                            action = move_towards(x, y, target_row, 0);\n                        }\n                    } else {\n                        // Move to a central waiting position\n                        if (x != 0 || y != N-1) {\n                            action = move_towards(x, y, 0, N-1);\n                        }\n                    }\n                }\n            } else { // Small cranes\n                // Move to the rightmost column and stay there\n                if (y < N-1) {\n                    action = move_towards(x, y, x, N-1);\n                }\n            }\n\n            // Compute intended next position\n            int nx = x, ny = y;\n            if (action == 'U') nx--;\n            else if (action == 'D') nx++;\n            else if (action == 'L') ny--;\n            else if (action == 'R') ny++;\n            \n            // Validate bounds and container restrictions\n            bool valid = true;\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) {\n                valid = false;\n            } else {\n                // For small cranes carrying containers, check destination for containers\n                if (idx >= 1 && carrying != -1 && next_grid[nx][ny] != -1) {\n                    valid = false;\n                }\n            }\n            \n            if (!valid) {\n                action = '.';\n                nx = x;\n                ny = y;\n            }\n            \n            // Apply action to next state\n            if (action == 'P') {\n                if (carrying == -1 && next_grid[x][y] != -1) {\n                    next_cranes[idx].carrying = next_grid[x][y];\n                    next_grid[x][y] = -1;\n                } else {\n                    action = '.';\n                }\n            } else if (action == 'Q') {\n                if (carrying != -1 && next_grid[x][y] == -1) {\n                    next_grid[x][y] = carrying;\n                    next_cranes[idx].carrying = -1;\n                } else {\n                    action = '.';\n                }\n            } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                next_cranes[idx].x = nx;\n                next_cranes[idx].y = ny;\n            }\n            \n            actions_per_crane[idx] += action;\n        }\n\n        // Collision detection and resolution\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                bool conflict = false;\n                // Same position\n                if (next_cranes[i].x == next_cranes[j].x && next_cranes[i].y == next_cranes[j].y) {\n                    conflict = true;\n                }\n                // Swapping positions\n                if (next_cranes[i].x == cranes[j].x && next_cranes[i].y == cranes[j].y &&\n                    next_cranes[j].x == cranes[i].x && next_cranes[j].y == cranes[i].y) {\n                    conflict = true;\n                }\n                \n                if (conflict) {\n                    // Revert the action for the crane with lower priority\n                    if (i == 0) { // Large crane has priority\n                        // Revert crane j\n                        actions_per_crane[j].pop_back();\n                        actions_per_crane[j] += '.';\n                        next_cranes[j] = cranes[j];\n                    } else {\n                        // Revert crane i\n                        actions_per_crane[i].pop_back();\n                        actions_per_crane[i] += '.';\n                        next_cranes[i] = cranes[i];\n                    }\n                }\n            }\n        }\n\n        // Update global state\n        for (int i = 0; i < N; i++) {\n            cranes[i] = next_cranes[i];\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                grid[i][j] = next_grid[i][j];\n            }\n        }\n\n        // Step 3: Dispatch containers at dispatch gates\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                if (grid[i][N-1] == current_target) {\n                    current_target++;\n                }\n                grid[i][N-1] = -1;\n            }\n        }\n    }\n\n    // Output actions\n    for (int i = 0; i < N; i++) {\n        cout << actions_per_crane[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(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    vector<tuple<int, int, int>> surp;\n    vector<tuple<int, int, int>> def;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                surp.push_back(make_tuple(i, j, grid[i][j]));\n            } else if (grid[i][j] < 0) {\n                def.push_back(make_tuple(i, j, -grid[i][j]));\n            }\n        }\n    }\n\n    int cur_i = 0, cur_j = 0;\n    vector<string> ops;\n\n    auto move_to = [&](int target_i, int target_j) {\n        while (cur_i < target_i) {\n            ops.push_back(\"D\");\n            cur_i++;\n        }\n        while (cur_i > target_i) {\n            ops.push_back(\"U\");\n            cur_i--;\n        }\n        while (cur_j < target_j) {\n            ops.push_back(\"R\");\n            cur_j++;\n        }\n        while (cur_j > target_j) {\n            ops.push_back(\"L\");\n            cur_j--;\n        }\n    };\n\n    while (!surp.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < surp.size(); idx++) {\n            auto [i, j, amt] = surp[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = surp[best_idx];\n        move_to(i, j);\n        ops.push_back(\"+\" + to_string(amt));\n        surp.erase(surp.begin() + best_idx);\n    }\n\n    while (!def.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < def.size(); idx++) {\n            auto [i, j, amt] = def[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = def[best_idx];\n        move_to(i, j);\n        ops.push_back(\"-\" + to_string(amt));\n        def.erase(def.begin() + best_idx);\n    }\n\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n    int grid_size = N * N;\n\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n\n    // Initialize random number generator\n    mt19937 rng(12345);\n    \n    // Precompute maximum values for each criterion\n    vector<int> max_vals(M, 0);\n    for (int l = 0; l < M; l++) {\n        for (int i = 0; i < seed_count; i++) {\n            max_vals[l] = max(max_vals[l], seeds[i][l]);\n        }\n    }\n    \n    // Target sum to aim for\n    long long target_sum = 0;\n    for (int l = 0; l < M; l++) {\n        target_sum += max_vals[l];\n    }\n\n    // Grid directions\n    vector<int> di = {-1, 1, 0, 0};\n    vector<int> dj = {0, 0, -1, 1};\n\n    for (int t = 0; t < T; t++) {\n        // 1. ADVANCED SEED SELECTION\n        // Calculate total values and criterion-wise strengths\n        vector<int> total(seed_count, 0);\n        vector<vector<int>> criterion_strength(M, vector<int>(seed_count));\n        for (int i = 0; i < seed_count; i++) {\n            for (int l = 0; l < M; l++) {\n                total[i] += seeds[i][l];\n                criterion_strength[l][i] = seeds[i][l];\n            }\n        }\n\n        // Sort seeds by total value\n        vector<int> indices(seed_count);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(), [&](int i, int j) { \n            if (total[i] != total[j]) return total[i] > total[j];\n            return i < j;\n        });\n\n        // Select seeds using a hybrid approach\n        vector<int> selected_indices;\n        set<int> selected_set;\n        \n        // Strategy: Select seeds that are good in different criteria\n        // Phase 1: Top seeds by total value (50% of grid)\n        for (int i = 0; i < grid_size / 2 && i < seed_count; i++) {\n            if (selected_set.count(indices[i]) == 0) {\n                selected_indices.push_back(indices[i]);\n                selected_set.insert(indices[i]);\n            }\n        }\n        \n        // Phase 2: Seeds that are strong in specific criteria (25% of grid)\n        for (int l = 0; l < M && selected_indices.size() < grid_size * 3 / 4; l++) {\n            // Find top seeds for this criterion\n            vector<int> candidates;\n            for (int i = 0; i < seed_count; i++) {\n                if (selected_set.count(i) == 0) {\n                    candidates.push_back(i);\n                }\n            }\n            sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                return criterion_strength[l][a] > criterion_strength[l][b];\n            });\n            for (int i = 0; i < min(2, (int)candidates.size()) && selected_indices.size() < grid_size * 3 / 4; i++) {\n                selected_indices.push_back(candidates[i]);\n                selected_set.insert(candidates[i]);\n            }\n        }\n        \n        // Phase 3: Fill remaining with seeds that have high variance (diverse profiles)\n        vector<pair<double, int>> variance_seeds;\n        for (int i = 0; i < seed_count; i++) {\n            if (selected_set.count(i)) continue;\n            // Calculate variance of the seed's values\n            double mean = total[i] / (double)M;\n            double variance = 0;\n            for (int l = 0; l < M; l++) {\n                variance += (seeds[i][l] - mean) * (seeds[i][l] - mean);\n            }\n            variance /= M;\n            variance_seeds.push_back({variance, i});\n        }\n        sort(variance_seeds.begin(), variance_seeds.end(), greater<pair<double, int>>());\n        for (auto [var, idx] : variance_seeds) {\n            if (selected_indices.size() >= grid_size) break;\n            if (selected_set.count(idx) == 0) {\n                selected_indices.push_back(idx);\n                selected_set.insert(idx);\n            }\n        }\n\n        // 2. SMART GRID ASSIGNMENT\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Precompute potential value of pairs\n        auto pair_potential = [&](int a, int b) {\n            long long potential = 0;\n            for (int l = 0; l < M; l++) {\n                // Expected value if we could always take the max\n                potential += max(seeds[a][l], seeds[b][l]);\n                // Add a bonus for complementarity (how well they cover different criteria)\n                if (seeds[a][l] > 0 && seeds[b][l] > 0) {\n                    potential += min(seeds[a][l], seeds[b][l]) * 0.1;\n                }\n            }\n            return potential;\n        };\n\n        // Precompute \"goodness\" of each seed\n        vector<double> seed_goodness(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            if (selected_set.count(i) == 0) continue;\n            // Goodness is based on total value and diversity\n            double goodness = total[i];\n            double mean = total[i] / (double)M;\n            double variance = 0;\n            for (int l = 0; l < M; l++) {\n                variance += (seeds[i][l] - mean) * (seeds[i][l] - mean);\n            }\n            goodness += sqrt(variance) * 0.5; // Reward diversity\n            seed_goodness[i] = goodness;\n        }\n\n        // Assignment strategy: Place good seeds in the center, and pair complementary seeds\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cells.push_back({i, j});\n            }\n        }\n        \n        // Sort cells by number of neighbors (center first)\n        sort(cells.begin(), cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            int na = 0, nb = 0;\n            for (int d = 0; d < 4; d++) {\n                int ai = a.first + di[d], aj = a.second + dj[d];\n                if (ai >= 0 && ai < N && aj >= 0 && aj < N) na++;\n                int bi = b.first + di[d], bj = b.second + dj[d];\n                if (bi >= 0 && bi < N && bj >= 0 && bj < N) nb++;\n            }\n            if (na != nb) return na > nb;\n            return a < b;\n        });\n\n        // Greedy assignment with lookahead\n        for (auto [i, j] : cells) {\n            int best_seed = -1;\n            double best_score = -1e18;\n            \n            // Try each unused seed\n            for (int seed_idx : selected_indices) {\n                if (used[seed_idx]) continue;\n                \n                // Calculate score for placing this seed here\n                double score = seed_goodness[seed_idx];\n                int neighbor_count = 0;\n                \n                // Consider existing neighbors\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor = grid[ni][nj];\n                        double pair_score = pair_potential(seed_idx, neighbor);\n                        score += pair_score;\n                        neighbor_count++;\n                    }\n                }\n                \n                // If no neighbors, use the seed's own potential\n                if (neighbor_count == 0) {\n                    score += seed_goodness[seed_idx];\n                }\n                \n                // Add small exploration factor that decreases over time\n                double exploration = max(0.0, 1.0 - (double)t / T) * 5.0;\n                score += exploration * (rng() % 100);\n                \n                // Penalty for seeds that are too similar to existing neighbors\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor = grid[ni][nj];\n                        // Calculate similarity (lower is better)\n                        double similarity = 0;\n                        for (int l = 0; l < M; l++) {\n                            similarity += abs(seeds[seed_idx][l] - seeds[neighbor][l]);\n                        }\n                        score -= similarity * 0.01; // Small penalty for similarity\n                    }\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_seed = seed_idx;\n                }\n            }\n            \n            if (best_seed != -1) {\n                grid[i][j] = best_seed;\n                used[best_seed] = true;\n            }\n        }\n\n        // 3. OUTPUT\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // 4. READ NEW SEEDS\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n        \n        // 5. ADAPTIVE STRATEGY\n        // Check if we're making progress\n        int current_max = 0;\n        for (int i = 0; i < seed_count; i++) {\n            int sum = 0;\n            for (int l = 0; l < M; l++) sum += seeds[i][l];\n            current_max = max(current_max, sum);\n        }\n        \n        // If we're close to target, we can adjust parameters for more aggressive optimization\n        if (current_max > target_sum * 0.9) {\n            // Increase exploration in future iterations\n            // This is handled implicitly by the decreasing exploration factor\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <queue>\n#include <map>\n#include <set>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nPoint get_grab_pos(Point s, char dir, int d) {\n    if (dir == 'R') return Point(s.x - d, s.y);\n    if (dir == 'L') return Point(s.x + d, s.y);\n    if (dir == 'D') return Point(s.x, s.y - d);\n    if (dir == 'U') return Point(s.x, s.y + d);\n    return Point();\n}\n\nPoint get_release_pos(Point t, char dir, int d) {\n    if (dir == 'R') return Point(t.x - d, t.y);\n    if (dir == 'L') return Point(t.x + d, t.y);\n    if (dir == 'D') return Point(t.x, t.y - d);\n    if (dir == 'U') return Point(t.x, t.y + d);\n    return Point();\n}\n\nbool is_valid(Point p, int N) {\n    return p.x >= 0 && p.x < N && p.y >= 0 && p.y < N;\n}\n\nvector<char> get_path(Point from, Point to) {\n    vector<char> path;\n    int x = from.x;\n    int y = from.y;\n    while (x != to.x) {\n        if (x < to.x) {\n            path.push_back('R');\n            x++;\n        } else {\n            path.push_back('L');\n            x--;\n        }\n    }\n    while (y != to.y) {\n        if (y < to.y) {\n            path.push_back('D');\n            y++;\n        } else {\n            path.push_back('U');\n            y--;\n        }\n    }\n    return path;\n}\n\nstring create_turn(char movement, int leaf_index, char direction, bool grab, int V) {\n    string s(2 * V, '.');\n    s[0] = movement;\n    if (leaf_index != -1) {\n        s[leaf_index] = direction;\n        if (grab) {\n            s[V + leaf_index] = 'P';\n        }\n    }\n    return s;\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\n    vector<string> S(N), T(N);\n    for (int i = 0; i < N; i++) cin >> S[i];\n    for (int i = 0; i < N; i++) cin >> T[i];\n\n    vector<Point> initial_positions;\n    vector<Point> target_positions;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (S[i][j] == '1') initial_positions.push_back(Point(i, j));\n            if (T[i][j] == '1') target_positions.push_back(Point(i, j));\n        }\n    }\n\n    vector<pair<Point, Point>> pairs;\n    vector<bool> assigned(M, false);\n\n    for (int i = 0; i < M; i++) {\n        Point s = initial_positions[i];\n        int best_j = -1;\n        int best_dist = 1e9;\n        for (int j = 0; j < M; j++) {\n            if (assigned[j]) continue;\n            int dist = manhattan(s, target_positions[j]);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_j = j;\n            }\n        }\n        assigned[best_j] = true;\n        pairs.push_back({s, target_positions[best_j]});\n    }\n\n    Point current_root(N / 2, N / 2);\n    vector<string> turns;\n\n    vector<pair<Point, Point>> remaining = pairs;\n\n    while (!remaining.empty()) {\n        int best_cost = 1e9;\n        int best_index = -1;\n        int best_leaf = -1;\n        char best_grab_dir = ' ';\n        char best_release_dir = ' ';\n        Point best_grab_pos, best_release_pos;\n\n        for (int i = 0; i < remaining.size(); i++) {\n            Point s = remaining[i].first;\n            Point t = remaining[i].second;\n            for (int leaf = 1; leaf < V; leaf++) {\n                int d = leaf;\n                for (char grab_dir : {'L', 'R', 'U', 'D'}) {\n                    Point grab_pos = get_grab_pos(s, grab_dir, d);\n                    if (!is_valid(grab_pos, N)) continue;\n                    for (char release_dir : {'L', 'R', 'U', 'D'}) {\n                        Point release_pos = get_release_pos(t, release_dir, d);\n                        if (!is_valid(release_pos, N)) continue;\n                        int cost = manhattan(current_root, grab_pos) + manhattan(grab_pos, release_pos);\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_index = i;\n                            best_leaf = leaf;\n                            best_grab_dir = grab_dir;\n                            best_release_dir = release_dir;\n                            best_grab_pos = grab_pos;\n                            best_release_pos = release_pos;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_index == -1) {\n            break;\n        }\n\n        vector<char> path1 = get_path(current_root, best_grab_pos);\n        if (path1.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_grab_dir, true, V));\n        } else {\n            for (int j = 0; j < path1.size(); j++) {\n                bool grab = (j == path1.size() - 1);\n                turns.push_back(create_turn(path1[j], best_leaf, best_grab_dir, grab, V));\n            }\n        }\n        current_root = best_grab_pos;\n\n        vector<char> path2 = get_path(best_grab_pos, best_release_pos);\n        if (path2.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_release_dir, true, V));\n        } else {\n            for (int j = 0; j < path2.size(); j++) {\n                bool release = (j == path2.size() - 1);\n                turns.push_back(create_turn(path2[j], best_leaf, best_release_dir, release, V));\n            }\n        }\n        current_root = best_release_pos;\n\n        remaining.erase(remaining.begin() + best_index);\n    }\n\n    cout << V << endl;\n    for (int i = 1; i < V; i++) {\n        cout << 0 << \" \" << i << endl;\n    }\n    cout << N/2 << \" \" << N/2 << endl;\n\n    for (const string& turn : turns) {\n        cout << turn << endl;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct Point {\n    int x, y, weight;\n};\n\nclass SegmentTree {\npublic:\n    int n;\n    vector<int> sum;\n    vector<int> max_prefix;\n    vector<int> max_suffix;\n    vector<int> max_sum;\n\n    SegmentTree(int size) {\n        n = size;\n        sum.resize(4 * n, 0);\n        max_prefix.resize(4 * n, 0);\n        max_suffix.resize(4 * n, 0);\n        max_sum.resize(4 * n, 0);\n    }\n\n    void update(int idx, int val, int node = 1, int left = 0, int right = -1) {\n        if (right == -1) right = n - 1;\n        if (left == right) {\n            sum[node] += val;\n            max_prefix[node] = sum[node];\n            max_suffix[node] = sum[node];\n            max_sum[node] = sum[node];\n            return;\n        }\n        int mid = (left + right) / 2;\n        if (idx <= mid) {\n            update(idx, val, 2 * node, left, mid);\n        } else {\n            update(idx, val, 2 * node + 1, mid + 1, right);\n        }\n        sum[node] = sum[2 * node] + sum[2 * node + 1];\n        max_prefix[node] = max(max_prefix[2 * node], sum[2 * node] + max_prefix[2 * node + 1]);\n        max_suffix[node] = max(max_suffix[2 * node + 1], sum[2 * node + 1] + max_suffix[2 * node]);\n        max_sum[node] = max({max_sum[2 * node], max_sum[2 * node + 1], max_suffix[2 * node] + max_prefix[2 * node + 1]});\n    }\n\n    int query() {\n        return max_sum[1];\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    srand(time(0));\n\n    int N;\n    cin >> N;\n    vector<Point> points;\n    set<pair<int, int>> point_set;\n    \n    for (int i = 0; i < 2 * N; i++) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 0});\n        point_set.insert({x, y});\n    }\n\n    for (int i = 0; i < N; i++) {\n        points[i].weight = 1;\n    }\n    for (int i = N; i < 2 * N; i++) {\n        points[i].weight = -1;\n    }\n\n    // Get unique x-coordinates and sort\n    set<int> x_set;\n    for (auto& p : points) {\n        x_set.insert(p.x);\n    }\n    vector<int> unique_x(x_set.begin(), x_set.end());\n    sort(unique_x.begin(), unique_x.end());\n    int total_x = unique_x.size();\n\n    // Group points by x\n    map<int, vector<Point>> points_by_x;\n    for (auto& p : points) {\n        points_by_x[p.x].push_back(p);\n    }\n\n    // Get unique y-coordinates and mapping\n    set<int> y_set;\n    for (auto& p : points) {\n        y_set.insert(p.y);\n    }\n    vector<int> unique_y(y_set.begin(), y_set.end());\n    sort(unique_y.begin(), unique_y.end());\n    map<int, int> y_to_idx;\n    for (int i = 0; i < unique_y.size(); i++) {\n        y_to_idx[unique_y[i]] = i;\n    }\n    int m = unique_y.size();\n\n    // Select candidate x1: first 250, last 250, and 25 evenly spaced\n    vector<int> candidate_x1;\n    int num_take = min(250, total_x);\n    for (int i = 0; i < num_take; i++) {\n        candidate_x1.push_back(unique_x[i]);\n    }\n    for (int i = max(0, total_x - num_take); i < total_x; i++) {\n        candidate_x1.push_back(unique_x[i]);\n    }\n    for (int i = 1; i <= 25; i++) {\n        int idx = total_x * i / 26;\n        if (idx < total_x) {\n            candidate_x1.push_back(unique_x[idx]);\n        }\n    }\n    sort(candidate_x1.begin(), candidate_x1.end());\n    candidate_x1.erase(unique(candidate_x1.begin(), candidate_x1.end()), candidate_x1.end());\n\n    int best_score = -1e9;\n    int best_x1 = 0, best_x2 = 0;\n\n    for (int x1 : candidate_x1) {\n        SegmentTree seg(m);\n        for (int x2 : unique_x) {\n            if (x2 < x1) continue;\n            for (auto& p : points_by_x[x2]) {\n                int idx = y_to_idx[p.y];\n                seg.update(idx, p.weight);\n            }\n            int current_score = seg.query();\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_x1 = x1;\n                best_x2 = x2;\n            }\n        }\n    }\n\n    if (best_score < 0) {\n        while (true) {\n            int x = rand() % 100000;\n            int y = rand() % 100000;\n            if (point_set.find({x, y}) == point_set.end() &&\n                point_set.find({x, y+1}) == point_set.end() &&\n                point_set.find({x+1, y}) == point_set.end() &&\n                point_set.find({x+1, y+1}) == point_set.end()) {\n                cout << 4 << endl;\n                cout << x << \" \" << y << endl;\n                cout << x << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y << endl;\n                break;\n            }\n        }\n    } else {\n        vector<int> y_weights(m, 0);\n        for (int x = best_x1; x <= best_x2; x++) {\n            if (points_by_x.find(x) != points_by_x.end()) {\n                for (auto& p : points_by_x[x]) {\n                    int idx = y_to_idx[p.y];\n                    y_weights[idx] += p.weight;\n                }\n            }\n        }\n\n        int best_sum = 0;\n        int current_sum = 0;\n        int best_start = 0, best_end = 0;\n        int current_start = 0;\n\n        for (int i = 0; i < m; i++) {\n            current_sum += y_weights[i];\n            if (current_sum > best_sum) {\n                best_sum = current_sum;\n                best_start = current_start;\n                best_end = i;\n            }\n            if (current_sum < 0) {\n                current_sum = 0;\n                current_start = i + 1;\n            }\n        }\n\n        if (best_sum <= 0) {\n            while (true) {\n                int x = rand() % 100000;\n                int y = rand() % 100000;\n                if (point_set.find({x, y}) == point_set.end() &&\n                    point_set.find({x, y+1}) == point_set.end() &&\n                    point_set.find({x+1, y}) == point_set.end() &&\n                    point_set.find({x+1, y+1}) == point_set.end()) {\n                    cout << 4 << endl;\n                    cout << x << \" \" << y << endl;\n                    cout << x << \" \" << y+1 << endl;\n                    cout << x+1 << \" \" << y+1 << endl;\n                    cout << x+1 << \" \" << y << endl;\n                    break;\n                }\n            }\n        } else {\n            int y1 = unique_y[best_start];\n            int y2 = unique_y[best_end];\n            cout << 4 << endl;\n            cout << best_x1 << \" \" << y1 << endl;\n            cout << best_x1 << \" \" << y2 << endl;\n            cout << best_x2 << \" \" << y2 << endl;\n            cout << best_x2 << \" \" << y1 << endl;\n        }\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Rectangle {\n    int id;\n    double w_est, h_est;\n    double w_var, h_var;\n    double w_obs, h_obs;\n};\n\nstruct Placement {\n    int id;\n    int rotated;\n    char direction;\n    int reference;\n};\n\nstruct PlacedRect {\n    int id;\n    double x, y, w, h;\n};\n\nclass EnhancedPacker {\nprivate:\n    vector<Rectangle> rects;\n    double sigma;\n    int N, T;\n    mt19937 rng;\n    \n    // Improved Bayesian estimation\n    void updateEstimates(int turn, double W_meas, double H_meas, const vector<Placement>& placement) {\n        if (placement.empty()) return;\n        \n        // Calculate expected vs measured\n        double exp_W = 0, exp_H = 0;\n        vector<PlacedRect> simulated;\n        fastSimulate(placement, simulated, exp_W, exp_H);\n        \n        if (exp_W < 1e-6 || exp_H < 1e-6) return;\n        \n        double err_W = W_meas - exp_W;\n        double err_H = H_meas - exp_H;\n        \n        // Only update if error is significant (more than 1 sigma)\n        if (abs(err_W) < sigma && abs(err_H) < sigma) return;\n        \n        // Update each rectangle proportionally to its contribution\n        for (const auto& p : placement) {\n            Rectangle& rect = rects[p.id];\n            \n            // Expected contribution of this rectangle to dimensions\n            double rect_w = p.rotated ? rect.h_est : rect.w_est;\n            double rect_h = p.rotated ? rect.w_est : rect.h_est;\n            \n            // Simple scaling factor based on error direction\n            double w_factor = 1.0, h_factor = 1.0;\n            if (err_W > 0) w_factor += 0.02 * (rect_w / exp_W);\n            if (err_H > 0) h_factor += 0.02 * (rect_h / exp_H);\n            \n            // Damped update with variance-aware damping\n            double damping = 0.05 / (1.0 + (rect.w_var + rect.h_var) / (sigma * sigma));\n            rect.w_est = rect.w_est * (1 - damping) + rect.w_est * w_factor * damping;\n            rect.h_est = rect.h_est * (1 - damping) + rect.h_est * h_factor * damping;\n            \n            // Update variance (simplified Kalman update)\n            double meas_var = sigma * sigma;\n            rect.w_var = 1.0 / (1.0 / rect.w_var + 1.0 / meas_var);\n            rect.h_var = 1.0 / (1.0 / rect.h_var + 1.0 / meas_var);\n            \n            // Clamp\n            rect.w_est = max(1.0, min(1e9, rect.w_est));\n            rect.h_est = max(1.0, min(1e9, rect.h_est));\n        }\n    }\n    \n    // Fast simulation with simplified overlap check\n    void fastSimulate(const vector<Placement>& placement, vector<PlacedRect>& placed, double& W, double& H) {\n        placed.clear();\n        W = 0; H = 0;\n        \n        for (const auto& p : placement) {\n            const Rectangle& rect = rects[p.id];\n            double w = p.rotated ? rect.h_est : rect.w_est;\n            double h = p.rotated ? rect.w_est : rect.h_est;\n            \n            double x = 0, y = 0;\n            \n            if (p.direction == 'U') {\n                if (p.reference != -1) {\n                    for (const auto& r : placed) {\n                        if (r.id == p.reference) { x = r.x + r.w; break; }\n                    }\n                }\n                // Find highest y that doesn't cause overlap\n                y = 0;\n                for (const auto& r : placed) {\n                    if (x < r.x + r.w && x + w > r.x) {\n                        y = max(y, r.y + r.h);\n                    }\n                }\n            } else {\n                if (p.reference != -1) {\n                    for (const auto& r : placed) {\n                        if (r.id == p.reference) { y = r.y + r.h; break; }\n                    }\n                }\n                // Find leftmost x that doesn't cause overlap\n                x = 0;\n                for (const auto& r : placed) {\n                    if (y < r.y + r.h && y + h > r.y) {\n                        x = max(x, r.x + r.w);\n                    }\n                }\n            }\n            \n            placed.push_back({p.id, x, y, w, h});\n            W = max(W, x + w);\n            H = max(H, y + h);\n        }\n    }\n    \n    // Enhanced greedy construction\n    vector<Placement> constructSolution(int turn) {\n        vector<Placement> solution;\n        solution.reserve(N);\n        \n        // Precompute suffix sum for penalty\n        vector<double> suffix_sum(N + 1, 0);\n        for (int i = N - 1; i >= 0; i--) {\n            suffix_sum[i] = suffix_sum[i + 1] + rects[i].w_est + rects[i].h_est;\n        }\n        \n        // Strategy selection based on turn\n        bool aggressive = (turn < T / 3);\n        bool thorough = (turn > T * 2 / 3);\n        \n        for (int i = 0; i < N; i++) {\n            const Rectangle& rect = rects[i];\n            double best_score = 1e18;\n            Placement best_placement;\n            bool found = false;\n            \n            // Try multiple configurations\n            for (int rot = 0; rot < 2; rot++) {\n                for (char dir : {'U', 'L'}) {\n                    // Try reference to -1 and to last placed\n                    vector<int> refs = {-1};\n                    if (!solution.empty()) {\n                        refs.push_back(solution.back().id);\n                        // Try a random previous rectangle for variety\n                        if (turn > 5) {\n                            refs.push_back(solution[rng() % solution.size()].id);\n                        }\n                    }\n                    \n                    for (int ref : refs) {\n                        Placement candidate = {i, rot, dir, ref};\n                        \n                        // Quick evaluation\n                        vector<Placement> temp = solution;\n                        temp.push_back(candidate);\n                        \n                        double new_W, new_H;\n                        vector<PlacedRect> new_placed;\n                        fastSimulate(temp, new_placed, new_W, new_H);\n                        \n                        double current_W = 0, current_H = 0;\n                        if (!solution.empty()) {\n                            vector<PlacedRect> cur_placed;\n                            fastSimulate(solution, cur_placed, current_W, current_H);\n                        }\n                        \n                        double current_score = current_W + current_H + suffix_sum[i];\n                        double new_score = new_W + new_H + suffix_sum[i + 1];\n                        \n                        // Score with bonus for early turns or small improvement\n                        double score = new_score;\n                        if (aggressive) score *= 0.95; // Favor inclusion in early turns\n                        if (thorough) score *= 1.02; // Be more selective in late turns\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            best_placement = candidate;\n                            found = true;\n                        }\n                    }\n                }\n            }\n            \n            // Decision to include\n            double current_W = 0, current_H = 0;\n            if (!solution.empty()) {\n                vector<PlacedRect> cur_placed;\n                fastSimulate(solution, cur_placed, current_W, current_H);\n            }\n            double current_total = current_W + current_H + suffix_sum[i];\n            double new_total = best_score;\n            \n            // Include if beneficial, or if we need more rectangles\n            bool should_include = found && (\n                new_total <= current_total * (aggressive ? 1.1 : 1.01) ||\n                (solution.size() < max(3, N / 4) && aggressive) ||\n                (i < 5)\n            );\n            \n            if (should_include) {\n                solution.push_back(best_placement);\n            }\n        }\n        \n        return solution;\n    }\n    \n    vector<Placement> validateOutput(vector<Placement> solution) {\n        if (solution.empty()) return solution;\n        \n        // Ensure ascending order\n        sort(solution.begin(), solution.end(), [](const Placement& a, const Placement& b) {\n            return a.id < b.id;\n        });\n        \n        // Remove duplicates\n        vector<Placement> unique;\n        vector<bool> seen(N, false);\n        for (const auto& p : solution) {\n            if (!seen[p.id]) {\n                unique.push_back(p);\n                seen[p.id] = true;\n            }\n        }\n        \n        // Fix references\n        for (size_t i = 0; i < unique.size(); i++) {\n            if (unique[i].reference != -1) {\n                bool found = false;\n                for (size_t j = 0; j < i; j++) {\n                    if (unique[j].id == unique[i].reference) {\n                        found = true; break;\n                    }\n                }\n                if (!found) unique[i].reference = -1;\n            }\n        }\n        \n        return unique;\n    }\n\npublic:\n    EnhancedPacker(int n, int t, double s, const vector<pair<double, double>>& observed) \n        : N(n), T(t), sigma(s), rng(12345 + n * 13) {\n        rects.resize(N);\n        for (int i = 0; i < N; i++) {\n            rects[i].id = i;\n            rects[i].w_obs = observed[i].first;\n            rects[i].h_obs = observed[i].second;\n            // Initialize with observed values plus small noise\n            normal_distribution<double> dist(0, sigma * 0.02);\n            rects[i].w_est = observed[i].first + dist(rng);\n            rects[i].h_est = observed[i].second + dist(rng);\n            rects[i].w_var = sigma * sigma;\n            rects[i].h_var = sigma * sigma;\n            \n            rects[i].w_est = max(1.0, min(1e9, rects[i].w_est));\n            rects[i].h_est = max(1.0, min(1e9, rects[i].h_est));\n        }\n    }\n    \n    vector<Placement> solve(int turn, double W_meas, double H_meas, const vector<Placement>& last_placement) {\n        if (turn > 0) {\n            updateEstimates(turn, W_meas, H_meas, last_placement);\n        }\n        \n        vector<Placement> solution = constructSolution(turn);\n        solution = validateOutput(solution);\n        \n        // Fallback to simple packing if empty\n        if (solution.empty()) {\n            for (int i = 0; i < N; i++) {\n                solution.push_back({i, 0, 'U', (i == 0) ? -1 : i - 1});\n            }\n        }\n        \n        return solution;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<double, double>> observed(N);\n    for (int i = 0; i < N; i++) {\n        cin >> observed[i].first >> observed[i].second;\n    }\n    \n    EnhancedPacker packer(N, T, sigma, observed);\n    \n    vector<Placement> last_placement;\n    \n    for (int turn = 0; turn < T; turn++) {\n        double W_meas = 0, H_meas = 0;\n        if (turn > 0) cin >> W_meas >> H_meas;\n        \n        vector<Placement> placement = packer.solve(turn, W_meas, H_meas, last_placement);\n        \n        cout << placement.size() << \"\\n\";\n        for (const auto& p : placement) {\n            cout << p.id << \" \" << p.rotated << \" \" << p.direction << \" \" << p.reference << \"\\n\";\n        }\n        cout.flush();\n        \n        last_placement = placement;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n\n    void read_input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; ++i) cin >> A[i];\n        adj.assign(N, {});\n        for (int i = 0; i < M; ++i) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        // read and ignore coordinates\n        for (int i = 0; i < N; ++i) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n\n    vector<int> solve() {\n        // Try multiple strategies with safe improvements\n        vector<int> best_parent;\n        long long best_score = -1;\n        \n        // Strategy 1: High beauty roots with safe improvement\n        {\n            auto parent1 = build_with_high_roots();\n            improve_safe(parent1);\n            long long score1 = compute_score(parent1);\n            if (score1 > best_score) {\n                best_score = score1;\n                best_parent = parent1;\n            }\n        }\n        \n        // Strategy 2: Descending beauty with safe improvement\n        {\n            auto parent2 = build_bfs_descending();\n            improve_safe(parent2);\n            long long score2 = compute_score(parent2);\n            if (score2 > best_score) {\n                best_score = score2;\n                best_parent = parent2;\n            }\n        }\n        \n        // Strategy 3: Ascending beauty with safe improvement\n        {\n            auto parent3 = build_bfs_ascending();\n            improve_safe(parent3);\n            long long score3 = compute_score(parent3);\n            if (score3 > best_score) {\n                best_score = score3;\n                best_parent = parent3;\n            }\n        }\n        \n        // Strategy 4: Try a hybrid approach\n        {\n            auto parent4 = build_hybrid();\n            improve_safe(parent4);\n            long long score4 = compute_score(parent4);\n            if (score4 > best_score) {\n                best_score = score4;\n                best_parent = parent4;\n            }\n        }\n        \n        return best_parent;\n    }\n\n    vector<int> build_with_high_roots() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n        \n        int num_roots = max(1, N / 5);\n        for (int i = 0; i < num_roots; ++i) {\n            int root = vertices[i];\n            if (assigned[root]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({root, 0});\n            assigned[root] = true;\n            parent[root] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] > A[b];\n                });\n                \n                for (int v : neighbors) {\n                    if (!assigned[v]) {\n                        assigned[v] = true;\n                        parent[v] = u;\n                        if (d + 1 < H) {\n                            q.push({v, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_bfs_descending() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] > A[b];\n                });\n                \n                for (int w : neighbors) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_bfs_ascending() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] < A[b];\n        });\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] < A[b];\n                });\n                \n                for (int w : neighbors) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_hybrid() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        \n        // Mix of strategies: start with high beauty, then fill gaps\n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n        \n        // First pass: build trees from top 10% vertices\n        for (int i = 0; i < N / 10; ++i) {\n            int v = vertices[i];\n            if (assigned[v]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w] && A[w] >= A[v] / 2) { // Prefer high beauty neighbors\n                        assigned[w] = true;\n                        parent[w] = u;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Second pass: cover remaining vertices\n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            // Find best parent among assigned neighbors\n            int best_parent = -1;\n            int best_depth = -1;\n            \n            for (int u : adj[v]) {\n                if (assigned[u]) {\n                    // Need to compute depth of u\n                    int depth_u = 0;\n                    int cur = u;\n                    while (parent[cur] != -1) {\n                        depth_u++;\n                        cur = parent[cur];\n                    }\n                    \n                    if (depth_u < H - 1 && depth_u > best_depth) {\n                        best_depth = depth_u;\n                        best_parent = u;\n                    }\n                }\n            }\n            \n            if (best_parent != -1) {\n                assigned[v] = true;\n                parent[v] = best_parent;\n            } else {\n                // Make it a root\n                assigned[v] = true;\n                parent[v] = -1;\n            }\n        }\n        \n        return parent;\n    }\n\n    void improve_safe(vector<int>& parent) {\n        const int MAX_ITER = 10;\n        vector<int> depth(N, 0);\n        vector<vector<int>> children(N);\n        \n        for (int iter = 0; iter < MAX_ITER; ++iter) {\n            // Rebuild depth and children\n            fill(depth.begin(), depth.end(), 0);\n            for (int i = 0; i < N; ++i) children[i].clear();\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] != -1) {\n                    children[parent[v]].push_back(v);\n                }\n            }\n            \n            function<void(int)> compute_depth = [&](int v) {\n                for (int c : children[v]) {\n                    depth[c] = depth[v] + 1;\n                    compute_depth(c);\n                }\n            };\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) {\n                    compute_depth(v);\n                }\n            }\n            \n            // Compute subtree info\n            vector<int> subtree_sum(N, 0);\n            vector<int> max_depth(N, 0);\n            \n            function<void(int)> dfs = [&](int v) {\n                subtree_sum[v] = A[v];\n                max_depth[v] = 0;\n                for (int c : children[v]) {\n                    dfs(c);\n                    subtree_sum[v] += subtree_sum[c];\n                    max_depth[v] = max(max_depth[v], max_depth[c] + 1);\n                }\n            };\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) {\n                    dfs(v);\n                }\n            }\n            \n            bool changed = false;\n            \n            // Only try moving subtrees to neighbors - safe operation\n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) continue;\n                \n                int best_u = -1;\n                long long best_gain = 0;\n                \n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    \n                    // Check if u is already in v's subtree (would create cycle)\n                    bool in_subtree = false;\n                    function<void(int)> check_cycle = [&](int x) {\n                        if (x == u) { in_subtree = true; return; }\n                        for (int c : children[x]) check_cycle(c);\n                    };\n                    check_cycle(v);\n                    if (in_subtree) continue;\n                    \n                    // Compute depth of u\n                    int depth_u = 0;\n                    int cur = u;\n                    while (parent[cur] != -1) {\n                        depth_u++;\n                        cur = parent[cur];\n                    }\n                    \n                    int new_depth = depth_u + 1;\n                    if (new_depth > H) continue;\n                    if (new_depth + max_depth[v] > H) continue;\n                    \n                    int delta = new_depth - depth[v];\n                    if (delta <= 0) continue;\n                    \n                    long long gain = (long long)delta * subtree_sum[v];\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_u = u;\n                    }\n                }\n                \n                if (best_u != -1) {\n                    // Perform the move\n                    int old_parent = parent[v];\n                    \n                    // Update children list\n                    auto& old_children = children[old_parent];\n                    old_children.erase(remove(old_children.begin(), old_children.end(), v), old_children.end());\n                    children[best_u].push_back(v);\n                    \n                    // Update parent\n                    parent[v] = best_u;\n                    \n                    // Update depths\n                    int delta = (depth[best_u] + 1) - depth[v];\n                    function<void(int)> update_depths = [&](int x) {\n                        depth[x] += delta;\n                        for (int c : children[x]) update_depths(c);\n                    };\n                    update_depths(v);\n                    \n                    changed = true;\n                    break; // Restart with updated state\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n\n    long long compute_score(const vector<int>& parent) {\n        vector<int> depth(N, 0);\n        vector<vector<int>> children(N);\n        \n        for (int v = 0; v < N; ++v) {\n            if (parent[v] != -1) {\n                children[parent[v]].push_back(v);\n            }\n        }\n        \n        function<void(int)> compute_depth = [&](int v) {\n            for (int c : children[v]) {\n                depth[c] = depth[v] + 1;\n                compute_depth(c);\n            }\n        };\n        \n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                compute_depth(v);\n            }\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; ++v) {\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver solver;\n    solver.read_input();\n    vector<int> result = solver.solve();\n\n    for (int i = 0; i < (int)result.size(); ++i) {\n        if (i > 0) cout << ' ';\n        cout << result[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>> operations;\n    const int MAX_OPERATIONS = 4 * N * N;\n\n    while (operations.size() < MAX_OPERATIONS) {\n        bool hasOni = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    hasOni = true;\n                    break;\n                }\n            }\n            if (hasOni) break;\n        }\n        if (!hasOni) break;\n\n        bool removed = false;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == 'x') {\n                operations.push_back({'L', i});\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[i][N-1] == 'x') {\n                operations.push_back({'R', i});\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == 'x') {\n                operations.push_back({'U', j});\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[N-1][j] == 'x') {\n                operations.push_back({'D', j});\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        int best_dist = 1000000;\n        char best_dir = 0;\n        int best_index = -1;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == '.') {\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        if (j < best_dist) {\n                            best_dist = j;\n                            best_dir = 'L';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][N-1] == '.') {\n                for (int j = N-1; j >= 0; j--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - j;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'R';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == '.') {\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        if (i < best_dist) {\n                            best_dist = i;\n                            best_dir = 'U';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[N-1][j] == '.') {\n                for (int i = N-1; i >= 0; i--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - i;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'D';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (best_index != -1) {\n            operations.push_back({best_dir, best_index});\n            if (best_dir == 'L') {\n                int i = best_index;\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n            } else if (best_dir == 'R') {\n                int i = best_index;\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n            } else if (best_dir == 'U') {\n                int j = best_index;\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n            } else if (best_dir == 'D') {\n                int j = best_index;\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n            }\n        } else {\n            break;\n        }\n    }\n\n    for (auto op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, L;\n    cin >> N >> L;\n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    // Identify employees with significantly high targets\n    vector<int> high_targets;\n    for (int i = 0; i < N; i++) {\n        if (T[i] > 6000) {\n            high_targets.push_back(i);\n        }\n    }\n\n    // Start with the simple cyclic assignment\n    vector<pair<int, int>> assignments(N);\n    for (int i = 0; i < N; i++) {\n        assignments[i] = {(i + 1) % N, (i + 2) % N};\n    }\n\n    // For high-target employees, modify the second transition to point to another high-target employee\n    // This creates a \"shortcut\" that increases their visit frequency\n    if (high_targets.size() >= 2) {\n        for (int i = 0; i < high_targets.size(); i++) {\n            int emp = high_targets[i];\n            int other = high_targets[(i + 1) % high_targets.size()];\n            assignments[emp].second = other;\n        }\n    }\n\n    // Output the assignments\n    for (int i = 0; i < N; i++) {\n        cout << assignments[i].first << \" \" << assignments[i].second << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cmath>\n#include <queue>\n\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> cx, cy;\nvector<int> lx, rx, ly, ry;\nint queries_used = 0;\n\nvector<pair<int, int>> do_query(vector<int> cities) {\n    sort(cities.begin(), cities.end());\n    cout << \"? \" << cities.size();\n    for (int c : cities) {\n        cout << \" \" << c;\n    }\n    cout << endl;\n    vector<pair<int, int>> edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.push_back(make_pair(a, b));\n    }\n    queries_used++;\n    return edges;\n}\n\nvector<pair<int, int>> build_tree(vector<int> cities) {\n    int n = cities.size();\n    if (n == 1) {\n        return {};\n    }\n    if (n == 2) {\n        return {make_pair(cities[0], cities[1])};\n    }\n    if (n <= L) {\n        if (queries_used < Q) {\n            return do_query(cities);\n        } else {\n            vector<pair<int, int>> edges;\n            for (int i = 0; i < n - 1; i++) {\n                edges.push_back(make_pair(cities[i], cities[i + 1]));\n            }\n            return edges;\n        }\n    } else {\n        int mid = n / 2;\n        vector<int> A(cities.begin(), cities.begin() + mid);\n        vector<int> B(cities.begin() + mid, cities.end());\n\n        if (A.size() < 2) {\n            A.push_back(B[0]);\n            B.erase(B.begin());\n        }\n        if (B.size() < 2) {\n            B.push_back(A.back());\n            A.pop_back();\n        }\n\n        vector<pair<int, int>> treeA = build_tree(A);\n        vector<pair<int, int>> treeB = build_tree(B);\n\n        vector<pair<int, int>> edges_connect;\n        if (queries_used < Q) {\n            int k = min((int)A.size(), L / 2);\n            int l = L - k;\n            if (l > (int)B.size()) {\n                l = B.size();\n                k = L - l;\n            }\n            vector<int> S;\n            for (int i = A.size() - k; i < A.size(); i++) {\n                S.push_back(A[i]);\n            }\n            for (int i = 0; i < l; i++) {\n                S.push_back(B[i]);\n            }\n            vector<pair<int, int>> edges_S = do_query(S);\n            set<int> setA(A.begin(), A.end());\n            set<int> setB(B.begin(), B.end());\n            pair<int, int> connect_edge = make_pair(-1, -1);\n            for (auto& e : edges_S) {\n                int u = e.first, v = e.second;\n                if ((setA.count(u) && setB.count(v)) || (setA.count(v) && setB.count(u))) {\n                    connect_edge = e;\n                    break;\n                }\n            }\n            if (connect_edge.first == -1) {\n                connect_edge = make_pair(A.back(), B[0]);\n            }\n            edges_connect.push_back(connect_edge);\n        } else {\n            edges_connect.push_back(make_pair(A.back(), B[0]));\n        }\n\n        vector<pair<int, int>> result;\n        result.reserve(treeA.size() + treeB.size() + edges_connect.size());\n        result.insert(result.end(), treeA.begin(), treeA.end());\n        result.insert(result.end(), treeB.begin(), treeB.end());\n        result.insert(result.end(), edges_connect.begin(), edges_connect.end());\n        return result;\n    }\n}\n\n// Improved grouping: sort by (x+y) to better capture spatial proximity\nvector<int> get_sorted_indices() {\n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        int di = cx[i] + cy[i];\n        int dj = cx[j] + cy[j];\n        if (di != dj) return di < dj;\n        if (cx[i] != cx[j]) return cx[i] < cx[j];\n        return cy[i] < cy[j];\n    });\n    return indices;\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> G[i];\n    }\n    lx.resize(N);\n    rx.resize(N);\n    ly.resize(N);\n    ry.resize(N);\n    cx.resize(N);\n    cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2;\n        cy[i] = (ly[i] + ry[i]) / 2;\n    }\n\n    vector<int> indices = get_sorted_indices();\n\n    vector<vector<int>> groups(M);\n    int start = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i] = vector<int>(indices.begin() + start, indices.begin() + start + G[i]);\n        start += G[i];\n    }\n\n    vector<vector<pair<int, int>>> group_edges(M);\n    for (int i = 0; i < M; i++) {\n        group_edges[i] = build_tree(groups[i]);\n    }\n\n    // Optional: improve edges if we have spare queries\n    // We'll try to find shorter edges by querying sets of cities that are close in the sorted order\n    // But we need to be careful not to exceed Q\n    // For simplicity, we'll skip this step to avoid complexity\n\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < groups[i].size(); j++) {\n            if (j) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nbool can_slide(int r, int c, int tr, int tc, const vector<vector<bool>>& block, int N) {\n    if (r == tr) {\n        if (c < tc) {\n            for (int j = c+1; j <= tc; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc+1 < N) {\n                if (!block[r][tc+1]) return false;\n            }\n            return true;\n        } else if (c > tc) {\n            for (int j = tc; j < c; j++) {\n                if (block[r][j]) return false;\n            }\n            if (tc-1 >= 0) {\n                if (!block[r][tc-1]) return false;\n            }\n            return true;\n        }\n    } else if (c == tc) {\n        if (r < tr) {\n            for (int i = r+1; i <= tr; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr+1 < N) {\n                if (!block[tr+1][c]) return false;\n            }\n            return true;\n        } else if (r > tr) {\n            for (int i = tr; i < r; i++) {\n                if (block[i][c]) return false;\n            }\n            if (tr-1 >= 0) {\n                if (!block[tr-1][c]) return false;\n            }\n            return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.push_back({r, c});\n    }\n\n    vector<vector<bool>> block(N, vector<bool>(N, false));\n    int r = r0, c = c0;\n    vector<string> actions;\n\n    for (int idx = 0; idx < M; idx++) {\n        int tr = targets[idx].first;\n        int tc = targets[idx].second;\n\n        while (r != tr || c != tc) {\n            // Check if we can use a direct slide\n            if (can_slide(r, c, tr, tc, block, N)) {\n                if (r == tr) {\n                    if (c < tc) {\n                        actions.push_back(\"S R\");\n                        c = tc;\n                    } else {\n                        actions.push_back(\"S L\");\n                        c = tc;\n                    }\n                } else if (c == tc) {\n                    if (r < tr) {\n                        actions.push_back(\"S D\");\n                        r = tr;\n                    } else {\n                        actions.push_back(\"S U\");\n                        r = tr;\n                    }\n                }\n                continue;\n            }\n\n            int cost_manhattan = abs(r - tr) + abs(c - tc);\n            int best_cost = cost_manhattan;\n            vector<string> best_actions;\n\n            // Check boundary approaches only for corner targets and when not aligned\n            if (tr == 0 && tc == 0 && r > 0 && c > 0) {\n                int cost = r + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < r; i++) best_actions.push_back(\"M U\");\n                    best_actions.push_back(\"S L\");\n                }\n            } else if (tr == 0 && tc == N-1 && r > 0 && c < N-1) {\n                int cost = r + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < r; i++) best_actions.push_back(\"M U\");\n                    best_actions.push_back(\"S R\");\n                }\n            } else if (tr == N-1 && tc == 0 && r < N-1 && c > 0) {\n                int cost = (N-1 - r) + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < N-1 - r; i++) best_actions.push_back(\"M D\");\n                    best_actions.push_back(\"S L\");\n                }\n            } else if (tr == N-1 && tc == N-1 && r < N-1 && c < N-1) {\n                int cost = (N-1 - r) + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_actions.clear();\n                    for (int i = 0; i < N-1 - r; i++) best_actions.push_back(\"M D\");\n                    best_actions.push_back(\"S R\");\n                }\n            }\n\n            if (best_cost < cost_manhattan) {\n                for (const string& action : best_actions) {\n                    actions.push_back(action);\n                    if (action == \"M U\") r--;\n                    else if (action == \"M D\") r++;\n                    else if (action == \"M L\") c--;\n                    else if (action == \"M R\") c++;\n                    else if (action == \"S R\") c = tc;\n                    else if (action == \"S L\") c = tc;\n                    else if (action == \"S U\") r = tr;\n                    else if (action == \"S D\") r = tr;\n                }\n                continue;\n            }\n\n            // Step-by-step moves\n            int dr = tr - r;\n            int dc = tc - c;\n            int adr = abs(dr);\n            int adc = abs(dc);\n\n            if (adr > adc) {\n                if (dr > 0) {\n                    actions.push_back(\"M D\");\n                    r++;\n                } else {\n                    actions.push_back(\"M U\");\n                    r--;\n                }\n            } else if (adc > adr) {\n                if (dc > 0) {\n                    actions.push_back(\"M R\");\n                    c++;\n                } else {\n                    actions.push_back(\"M L\");\n                    c--;\n                }\n            } else {\n                if (tr == N-1 || tr == 0) {\n                    if (dr > 0) {\n                        actions.push_back(\"M D\");\n                        r++;\n                    } else if (dr < 0) {\n                        actions.push_back(\"M U\");\n                        r--;\n                    } else {\n                        if (dc > 0) {\n                            actions.push_back(\"M R\");\n                            c++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            c--;\n                        }\n                    }\n                } else if (tc == N-1 || tc == 0) {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else if (dc < 0) {\n                        actions.push_back(\"M L\");\n                        c--;\n                    } else {\n                        if (dr > 0) {\n                            actions.push_back(\"M D\");\n                            r++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            r--;\n                        }\n                    }\n                } else {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        c--;\n                    }\n                }\n            }\n        }\n    }\n\n    for (const string& action : actions) {\n        cout << action << endl;\n    }\n\n    return 0;\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n;\n    cin >> n;\n\n    vector<Company> companies(n);\n    for (int i = 0; i < n; i++) {\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n\n    // Sort by desired area descending, then by minimum distance to boundaries ascending\n    sort(companies.begin(), companies.end(), [](const Company& a, const Company& b) {\n        if (a.r != b.r) return a.r > b.r;\n        int da = min({a.x, a.y, 9999 - a.x, 9999 - a.y});\n        int db = min({b.x, b.y, 9999 - b.x, 9999 - b.y});\n        return da < db;\n    });\n\n    vector<Rect> assigned_rects;\n\n    for (int i = 0; i < n; i++) {\n        int L = companies[i].x;\n        int R = companies[i].x + 1;\n        int T = companies[i].y;\n        int B = companies[i].y + 1;\n\n        auto conflict_strip = [&](int x1, int x2, int y1, int y2) -> bool {\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                int xj = companies[j].x;\n                int yj = companies[j].y;\n                if (x1 <= xj && xj < x2 && y1 <= yj && yj < y2) {\n                    return true;\n                }\n            }\n            for (const auto& rect : assigned_rects) {\n                if (x1 < rect.c && rect.a < x2 && y1 < rect.d && rect.b < y2) {\n                    return true;\n                }\n            }\n            return false;\n        };\n\n        bool expanded = true;\n        while (expanded) {\n            expanded = false;\n            if (L > 0 && !conflict_strip(L-1, L, T, B)) {\n                L--;\n                expanded = true;\n            }\n            if (R < 10000 && !conflict_strip(R, R+1, T, B)) {\n                R++;\n                expanded = true;\n            }\n            if (T > 0 && !conflict_strip(L, R, T-1, T)) {\n                T--;\n                expanded = true;\n            }\n            if (B < 10000 && !conflict_strip(L, R, B, B+1)) {\n                B++;\n                expanded = true;\n            }\n        }\n\n        int max_w = R - L;\n        int max_h = B - T;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - companies[i].r);\n\n        // For very small areas, ensure we consider the minimum possible area\n        if (companies[i].r == 1) {\n            best_w = 1;\n            best_h = 1;\n        } else {\n            for (int w = 1; w <= max_w; w++) {\n                int left_min = max(L, companies[i].x - w + 1);\n                int left_max = min(companies[i].x, R - w);\n                if (left_min > left_max) continue;\n\n                int h0 = companies[i].r / w;\n                int h1 = (companies[i].r + w - 1) / w;\n                // Check a range of heights around the ideal values\n                vector<int> candidates;\n                for (int h = max(1, h0 - 2); h <= min(max_h, h0 + 2); h++) candidates.push_back(h);\n                for (int h = max(1, h1 - 2); h <= min(max_h, h1 + 2); h++) candidates.push_back(h);\n                sort(candidates.begin(), candidates.end());\n                candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n\n                for (int h : candidates) {\n                    if (h < 1 || h > max_h) continue;\n                    int top_min = max(T, companies[i].y - h + 1);\n                    int top_max = min(companies[i].y, B - h);\n                    if (top_min > top_max) continue;\n\n                    int area = w * h;\n                    int diff = abs(area - companies[i].r);\n                    if (diff < best_diff) {\n                        best_diff = diff;\n                        best_w = w;\n                        best_h = h;\n                    }\n                }\n            }\n        }\n\n        int left = max(L, companies[i].x - best_w + 1);\n        int top = max(T, companies[i].y - best_h + 1);\n        cout << left << \" \" << top << \" \" << left + best_w << \" \" << top + best_h << \"\\n\";\n\n        assigned_rects.push_back({left, top, left+best_w, top+best_h});\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cmath>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nstruct Candidate {\n    int score;\n    int ni;\n    int nj;\n    int tid;\n    double heuristic;\n};\n\nint main() {\n    int si, sj;\n    cin >> si >> sj;\n    vector<vector<int>> t(50, vector<int>(50));\n    vector<vector<int>> p(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[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        }\n    }\n    \n    set<int> visitedTiles;\n    visitedTiles.insert(t[si][sj]);\n    \n    int i = si, j = sj;\n    string path = \"\";\n    int steps = 0;\n    int tiles_visited = 1;\n    \n    // Precompute tile statistics\n    vector<int> tileMax(3000, 0);\n    vector<int> tileSum(3000, 0);\n    vector<int> tileCount(3000, 0);\n    vector<set<int>> tileNeighbors(3000);\n    vector<double> tileDensity(3000, 0.0);\n    vector<double> tilePotential(3000, 0.0);\n    \n    // First pass: basic statistics\n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            int tid = t[i][j];\n            tileMax[tid] = max(tileMax[tid], p[i][j]);\n            tileSum[tid] += p[i][j];\n            tileCount[tid]++;\n        }\n    }\n    \n    // Second pass: density and neighbors\n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            int tid = t[i][j];\n            // Direct neighbors\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 < 50 && nj >= 0 && nj < 50) {\n                    int ntid = t[ni][nj];\n                    if (ntid != tid) {\n                        tileNeighbors[tid].insert(ntid);\n                    }\n                }\n            }\n            // Local density (3x3 area)\n            double sum = 0;\n            int count = 0;\n            for (int di = -1; di <= 1; di++) {\n                for (int dj = -1; dj <= 1; dj++) {\n                    int ni = i + di;\n                    int nj = j + dj;\n                    if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                        sum += p[ni][nj];\n                        count++;\n                    }\n                }\n            }\n            tileDensity[tid] = (count > 0) ? sum / count : 0;\n        }\n    }\n    \n    // Third pass: tile potential (average of neighbor max values)\n    for (int tid = 0; tid < 3000; tid++) {\n        if (tileCount[tid] == 0) continue;\n        double total = 0;\n        for (int ntid : tileNeighbors[tid]) {\n            total += tileMax[ntid];\n        }\n        tilePotential[tid] = (tileNeighbors[tid].empty()) ? 0 : total / tileNeighbors[tid].size();\n    }\n    \n    while (true) {\n        vector<Candidate> candidates;\n        \n        // Collect all valid moves\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 >= 50 || nj < 0 || nj >= 50) continue;\n            int tid = t[ni][nj];\n            if (visitedTiles.find(tid) != visitedTiles.end()) continue;\n            \n            // Optimized multi-factor heuristic with adjusted weights\n            double immediate = p[ni][nj];\n            double tile_potential = tileMax[tid] * 0.45 + (tileSum[tid] / (double)tileCount[tid]) * 0.35;\n            double local_density = tileDensity[tid];\n            \n            // Connectivity and future potential\n            int unvisited_neighbors = 0;\n            double neighbor_potential = 0;\n            for (int ntid : tileNeighbors[tid]) {\n                if (visitedTiles.find(ntid) == visitedTiles.end()) {\n                    unvisited_neighbors++;\n                    neighbor_potential += tilePotential[ntid] * 0.06;\n                }\n            }\n            \n            // Distance penalty with dynamic adjustment\n            double distance_from_start = sqrt((ni - si) * (ni - si) + (nj - sj) * (nj - sj));\n            double distance_penalty = distance_from_start * (0.015 + steps * 0.0003);\n            \n            // Dynamic weight based on progress\n            double progress = (double)tiles_visited / 100.0;\n            double weight = max(0.1, 0.7 - progress * 0.4);\n            \n            // Final heuristic calculation\n            double heuristic = immediate + \n                             weight * tile_potential + \n                             (0.15 + progress * 0.1) * local_density +\n                             0.15 * unvisited_neighbors +\n                             0.06 * neighbor_potential -\n                             distance_penalty;\n            \n            candidates.push_back({p[ni][nj], ni, nj, tid, heuristic});\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort candidates by heuristic\n        sort(candidates.begin(), candidates.end(), [](const Candidate& a, const Candidate& b) {\n            return a.heuristic > b.heuristic;\n        });\n        \n        // Adaptive candidate selection with wider exploration\n        int keep = min(15, (int)candidates.size());\n        if (steps < 5) keep = min(8, keep);\n        else if (steps < 15) keep = min(10, keep);\n        else if (steps > 40) keep = min(8, keep);\n        \n        int best_ni = -1, best_nj = -1;\n        double best_score = -1;\n        \n        // Optimized dynamic discount factors with less discount\n        double base_discount = max(0.3, 0.9 - steps * 0.005 - tiles_visited * 0.001);\n        double discount1 = base_discount;\n        double discount2 = base_discount * 0.7;\n        double discount3 = base_discount * 0.5;\n        \n        // 4-step lookahead with enhanced pruning\n        for (int idx = 0; idx < keep; idx++) {\n            auto& cand = candidates[idx];\n            set<int> temp_visited = visitedTiles;\n            temp_visited.insert(cand.tid);\n            \n            double total_score = cand.score;\n            \n            // First lookahead step (second move)\n            for (int d1 = 0; d1 < 4; d1++) {\n                int ni1 = cand.ni + dx[d1];\n                int nj1 = cand.nj + dy[d1];\n                if (ni1 < 0 || ni1 >= 50 || nj1 < 0 || nj1 >= 50) continue;\n                if (ni1 == i && nj1 == j) continue;\n                int tid1 = t[ni1][nj1];\n                if (temp_visited.find(tid1) != temp_visited.end()) continue;\n                \n                int score1 = p[ni1][nj1];\n                set<int> temp_visited2 = temp_visited;\n                temp_visited2.insert(tid1);\n                \n                int best_score2 = 0;\n                // Second lookahead step (third move)\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int ni2 = ni1 + dx[d2];\n                    int nj2 = nj1 + dy[d2];\n                    if (ni2 < 0 || ni2 >= 50 || nj2 < 0 || nj2 >= 50) continue;\n                    if (ni2 == cand.ni && nj2 == cand.nj) continue;\n                    int tid2 = t[ni2][nj2];\n                    if (temp_visited2.find(tid2) != temp_visited2.end()) continue;\n                    \n                    int score2 = p[ni2][nj2];\n                    // Future potential estimation with higher weight\n                    double future_value = tileMax[tid2] * 0.2 + (tileSum[tid2]/(double)tileCount[tid2]) * 0.15;\n                    int adjusted_score2 = score2 + future_value;\n                    \n                    // Third lookahead step (fourth move) - only the best one\n                    int best_score3 = 0;\n                    for (int d3 = 0; d3 < 4; d3++) {\n                        int ni3 = ni2 + dx[d3];\n                        int nj3 = nj2 + dy[d3];\n                        if (ni3 < 0 || ni3 >= 50 || nj3 < 0 || nj3 >= 50) continue;\n                        if (ni3 == ni1 && nj3 == nj1) continue;\n                        int tid3 = t[ni3][nj3];\n                        if (temp_visited2.find(tid3) != temp_visited2.end()) continue;\n                        \n                        int score3 = p[ni3][nj3];\n                        if (score3 > best_score3) best_score3 = score3;\n                    }\n                    \n                    adjusted_score2 += best_score3 * discount3;\n                    \n                    if (adjusted_score2 > best_score2) best_score2 = adjusted_score2;\n                }\n                \n                total_score += score1 * discount1 + best_score2 * discount2;\n            }\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_ni = cand.ni;\n                best_nj = cand.nj;\n            }\n        }\n        \n        // Fallback to best immediate candidate if lookahead failed\n        if (best_ni == -1) {\n            best_ni = candidates[0].ni;\n            best_nj = candidates[0].nj;\n        }\n        \n        // Convert to direction\n        int di = best_ni - i;\n        int dj = best_nj - j;\n        if (di == -1) path += 'U';\n        else if (di == 1) path += 'D';\n        else if (dj == -1) path += 'L';\n        else if (dj == 1) path += 'R';\n        \n        visitedTiles.insert(t[best_ni][best_nj]);\n        i = best_ni;\n        j = best_nj;\n        steps++;\n        tiles_visited++;\n    }\n    \n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <string>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nconst double low_bound = 1000.0;\nconst double high_bound = 9000.0;\n\ndouble H_est[30][29];\ndouble V_est[29][30];\nint H_count[30][29];\nint V_count[29][30];\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\ndouble get_edge_weight(int i, int j, int ni, int nj) {\n    if (ni == i-1 && nj == j) return V_est[i-1][j];\n    if (ni == i+1 && nj == j) return V_est[i][j];\n    if (ni == i && nj == j-1) return H_est[i][j-1];\n    if (ni == i && nj == j+1) return H_est[i][j];\n    return 1e18;\n}\n\nvoid update_edge(int i, int j, int ni, int nj, double delta) {\n    if (ni == i-1 && nj == j) {\n        V_est[i-1][j] += delta;\n        V_est[i-1][j] = max(low_bound, min(high_bound, V_est[i-1][j]));\n        V_count[i-1][j]++;\n    } else if (ni == i+1 && nj == j) {\n        V_est[i][j] += delta;\n        V_est[i][j] = max(low_bound, min(high_bound, V_est[i][j]));\n        V_count[i][j]++;\n    } else if (ni == i && nj == j-1) {\n        H_est[i][j-1] += delta;\n        H_est[i][j-1] = max(low_bound, min(high_bound, H_est[i][j-1]));\n        H_count[i][j-1]++;\n    } else if (ni == i && nj == j+1) {\n        H_est[i][j] += delta;\n        H_est[i][j] = max(low_bound, min(high_bound, H_est[i][j]));\n        H_count[i][j]++;\n    }\n}\n\nstring dijkstra(int si, int sj, int ti, int tj, double &est_length, int query_idx, bool force_exploration) {\n    vector<vector<double>> dist(30, vector<double>(30, 1e18));\n    vector<vector<pair<int, int>>> parent(30, vector<pair<int, int>>(30, {-1, -1}));\n    \n    auto manhattan = [](int i, int j, int ti, int tj) {\n        return abs(i - ti) + abs(j - tj);\n    };\n    \n    priority_queue<tuple<double, double, int, int>, \n                   vector<tuple<double, double, int, int>>, \n                   greater<tuple<double, double, int, int>>> pq;\n    \n    dist[si][sj] = 0.0;\n    pq.push(make_tuple(0.0, manhattan(si, sj, ti, tj), si, sj));\n\n    while (!pq.empty()) {\n        auto [d, h, i, j] = pq.top();\n        pq.pop();\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n            \n            double w = get_edge_weight(i, j, ni, nj);\n            \n            // Enhanced exploration strategy\n            double exploration = 0.0;\n            if (query_idx < 50 || force_exploration) {\n                int edge_count = 0;\n                if (ni == i-1) edge_count = V_count[ni][nj];\n                else if (ni == i+1) edge_count = V_count[i][nj];\n                else if (nj == j-1) edge_count = H_count[i][nj];\n                else if (nj == j+1) edge_count = H_count[i][j];\n                \n                if (edge_count < 2) {\n                    exploration = 450.0; // More aggressive\n                } else if (edge_count < 4) {\n                    exploration = 150.0;\n                }\n            }\n            \n            if (dist[ni][nj] > dist[i][j] + w + exploration) {\n                dist[ni][nj] = dist[i][j] + w + exploration;\n                parent[ni][nj] = make_pair(i, j);\n                pq.push(make_tuple(dist[ni][nj], manhattan(ni, nj, ti, tj), ni, nj));\n            }\n        }\n    }\n\n    vector<pair<int, int>> path_nodes;\n    int i = ti, j = tj;\n    while (i != si || j != sj) {\n        path_nodes.push_back({i, j});\n        auto p = parent[i][j];\n        i = p.first;\n        j = p.second;\n    }\n    path_nodes.push_back({si, sj});\n    reverse(path_nodes.begin(), path_nodes.end());\n\n    string path_str = \"\";\n    est_length = 0.0;\n    for (int idx = 0; idx < path_nodes.size()-1; idx++) {\n        int i1 = path_nodes[idx].first;\n        int j1 = path_nodes[idx].second;\n        int i2 = path_nodes[idx+1].first;\n        int j2 = path_nodes[idx+1].second;\n        char move;\n        if (i2 == i1-1) move = 'U';\n        else if (i2 == i1+1) move = 'D';\n        else if (j2 == j1-1) move = 'L';\n        else if (j2 == j1+1) move = 'R';\n        path_str += move;\n        est_length += get_edge_weight(i1, j1, i2, j2);\n    }\n\n    return path_str;\n}\n\nint main() {\n    // Initialize\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 29; j++) {\n            H_est[i][j] = 5000.0;\n            H_count[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 30; j++) {\n            V_est[i][j] = 5000.0;\n            V_count[i][j] = 0;\n        }\n    }\n\n    int si, sj, ti, tj;\n    double error_history[5] = {0.0, 0.0, 0.0, 0.0, 0.0};\n    int error_idx = 0;\n    int boost_counter = 0;\n    \n    for (int k = 0; k < 1000; k++) {\n        cin >> si >> sj >> ti >> tj;\n        \n        // More sensitive force exploration trigger\n        bool force_exploration = false;\n        if (k > 50) {\n            int poor_count = 0;\n            for (int i = 0; i < 5; i++) {\n                if (abs(error_history[i]) > 10000) poor_count++;\n            }\n            if (poor_count >= 2) {\n                force_exploration = true;\n                boost_counter = 20; // Longer boost\n            }\n        }\n        \n        if (boost_counter > 0) {\n            force_exploration = true;\n            boost_counter--;\n        }\n        \n        double est_length;\n        string path = dijkstra(si, sj, ti, tj, est_length, k, force_exploration);\n        cout << path << endl;\n        cout.flush();\n\n        long long F;\n        cin >> F;\n\n        int n = path.size();\n        if (n == 0) continue;\n\n        double error = static_cast<double>(F) - est_length;\n        \n        // Store error in history\n        error_history[error_idx] = error;\n        error_idx = (error_idx + 1) % 5;\n        \n        // Aggressive learning rate with higher multipliers\n        double base_alpha;\n        if (k < 20) {\n            base_alpha = 0.70;\n        } else if (k < 50) {\n            base_alpha = 0.55;\n        } else if (k < 100) {\n            base_alpha = 0.45;\n        } else if (k < 180) {\n            base_alpha = 0.35;\n        } else if (k < 320) {\n            base_alpha = 0.28;\n        } else if (k < 500) {\n            base_alpha = 0.20;\n        } else if (k < 700) {\n            base_alpha = 0.12;\n        } else {\n            base_alpha = 0.07;\n        }\n        \n        double abs_error = abs(error);\n        \n        // More aggressive error response\n        if (abs_error > 30000) {\n            base_alpha *= 3.5;\n        } else if (abs_error > 20000) {\n            base_alpha *= 3.0;\n        } else if (abs_error > 12000) {\n            base_alpha *= 2.5;\n        } else if (abs_error > 6000) {\n            base_alpha *= 2.0;\n        } else if (abs_error > 3000) {\n            base_alpha *= 1.5;\n        }\n        \n        if (force_exploration) {\n            base_alpha *= 2.5;\n        }\n        \n        // Faster consistency detection\n        if (k >= 30) {\n            int same_sign = 0;\n            int last_sign = (error_history[0] > 0) ? 1 : -1;\n            for (int i = 1; i < 5; i++) {\n                if (error_history[i] != 0) {\n                    int sign = (error_history[i] > 0) ? 1 : -1;\n                    if (sign == last_sign) same_sign++;\n                }\n            }\n            if (same_sign >= 2) {\n                base_alpha *= 2.0;\n            }\n        }\n        \n        // Very wide bounds\n        base_alpha = max(0.06, min(0.75, base_alpha));\n        \n        int cur_i = si, cur_j = sj;\n        for (char move : path) {\n            int next_i = cur_i, next_j = cur_j;\n            if (move == 'U') next_i--;\n            else if (move == 'D') next_i++;\n            else if (move == 'L') next_j--;\n            else if (move == 'R') next_j++;\n\n            int count = 0;\n            if (next_i == cur_i-1) count = V_count[cur_i-1][cur_j];\n            else if (next_i == cur_i+1) count = V_count[cur_i][cur_j];\n            else if (next_j == cur_j-1) count = H_count[cur_i][cur_j-1];\n            else if (next_j == cur_j+1) count = H_count[cur_i][cur_j];\n            \n            // Confidence factor\n            double confidence = 1.0 / (1.0 + 0.06 * count);\n            \n            // Edge contribution weighting\n            double edge_weight = get_edge_weight(cur_i, cur_j, next_i, next_j);\n            double weight_factor = edge_weight / est_length;\n            \n            double delta = (error * weight_factor) * base_alpha * confidence;\n            \n            // High cap but allow large corrections\n            if (abs(delta) > 12000.0) {\n                delta = (delta > 0) ? 12000.0 : -12000.0;\n            }\n            \n            update_edge(cur_i, cur_j, next_i, next_j, delta);\n\n            cur_i = next_i;\n            cur_j = next_j;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <map>\n#include <set>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <tuple>\n\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct StringInfo {\n    string s;\n    int id;\n    int len;\n    double weight;\n    set<char> unique_chars;\n};\n\nstruct PlacementScore {\n    int string_id;\n    int score;\n    bool operator<(const PlacementScore& other) const {\n        return score > other.score; // For min-heap\n    }\n};\n\n// Check if a string is a subsequence\nbool is_covered(const vector<string>& mat, const string& str, int N) {\n    int L = str.size();\n    // Horizontal\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 < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    // Vertical\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    return false;\n}\n\n// Count possible placements for a string\nint count_possible_placements(const vector<string>& mat, const string& str, int N) {\n    int count = 0;\n    int L = str.size();\n    // Horizontal\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 < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) count++;\n        }\n    }\n    // Vertical\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) count++;\n        }\n    }\n    return count;\n}\n\n// Try to place a string with specific character preference\nbool try_place_with_pref(vector<string>& mat, const string& str, int N, char pref) {\n    int L = str.size();\n    // Try horizontal\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool ok = true;\n            char chosen = '.';\n            for (int p = 0; p < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n                if (mat[i][col] == '.') {\n                    if (chosen == '.') chosen = str[p];\n                    else if (chosen != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok && chosen != '.' && chosen == pref) {\n                for (int p = 0; p < L; ++p) {\n                    int col = (j + p) % N;\n                    mat[i][col] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    // Try vertical\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            char chosen = '.';\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n                if (mat[row][j] == '.') {\n                    if (chosen == '.') chosen = str[p];\n                    else if (chosen != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n            }\n            if (ok && chosen != '.' && chosen == pref) {\n                for (int p = 0; p < L; ++p) {\n                    int row = (i + p) % N;\n                    mat[row][j] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Try to place a string horizontally\nbool try_place_horizontal(vector<string>& mat, const string& str, int N) {\n    int L = str.size();\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 < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < L; ++p) {\n                    int col = (j + p) % N;\n                    mat[i][col] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Try to place a string vertically\nbool try_place_vertical(vector<string>& mat, const string& str, int N) {\n    int L = str.size();\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int p = 0; p < L; ++p) {\n                    int row = (i + p) % N;\n                    mat[row][j] = str[p];\n                }\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Try to place with both directions\nbool try_place(vector<string>& mat, const string& str, int N, bool horizontal_first = true) {\n    if (horizontal_first) {\n        if (try_place_horizontal(mat, str, N)) return true;\n        if (try_place_vertical(mat, str, N)) return true;\n    } else {\n        if (try_place_vertical(mat, str, N)) return true;\n        if (try_place_horizontal(mat, str, N)) return true;\n    }\n    return false;\n}\n\n// Check if string can be placed without conflicts (returns position)\nbool can_place_no_conflict(const vector<string>& mat, const string& str, int N, int& r, int& c, bool& horizontal) {\n    int L = str.size();\n    // Try horizontal\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 < L; ++p) {\n                int col = (j + p) % N;\n                if (mat[i][col] != '.' && mat[i][col] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                r = i;\n                c = j;\n                horizontal = true;\n                return true;\n            }\n        }\n    }\n    // Try vertical\n    for (int j = 0; j < N; ++j) {\n        for (int i = 0; i < N; ++i) {\n            bool ok = true;\n            for (int p = 0; p < L; ++p) {\n                int row = (i + p) % N;\n                if (mat[row][j] != '.' && mat[row][j] != str[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                r = i;\n                c = j;\n                horizontal = false;\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Place string at position\nvoid place_at(vector<string>& mat, const string& str, int N, int r, int c, bool horizontal) {\n    int L = str.size();\n    if (horizontal) {\n        for (int p = 0; p < L; ++p) {\n            int col = (c + p) % N;\n            mat[r][col] = str[p];\n        }\n    } else {\n        for (int p = 0; p < L; ++p) {\n            int row = (r + p) % N;\n            mat[row][c] = str[p];\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> raw_strings(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> raw_strings[i];\n    }\n    \n    // Analyze strings\n    vector<StringInfo> strings(M);\n    map<char, int> global_char_freq;\n    \n    for (int i = 0; i < M; ++i) {\n        strings[i].s = raw_strings[i];\n        strings[i].id = i;\n        strings[i].len = raw_strings[i].size();\n        \n        for (char c : raw_strings[i]) {\n            global_char_freq[c]++;\n            strings[i].unique_chars.insert(c);\n        }\n        \n        double rarity = 0;\n        for (char c : strings[i].unique_chars) {\n            rarity += 1.0 / (global_char_freq[c] + 1);\n        }\n        strings[i].weight = strings[i].len * 10 + rarity;\n    }\n    \n    // Find the most frequent character overall\n    char most_frequent = 'A';\n    int max_freq = -1;\n    for (auto& p : global_char_freq) {\n        if (p.second > max_freq) {\n            max_freq = p.second;\n            most_frequent = p.first;\n        }\n    }\n    \n    // Generate multiple order strategies\n    vector<vector<int>> orders;\n    \n    // Order 1: Length descending\n    vector<int> o1(M);\n    iota(o1.begin(), o1.end(), 0);\n    sort(o1.begin(), o1.end(), [&](int a, int b) { return strings[a].len > strings[b].len; });\n    orders.push_back(o1);\n    \n    // Order 2: Weight descending\n    vector<int> o2(M);\n    iota(o2.begin(), o2.end(), 0);\n    sort(o2.begin(), o2.end(), [&](int a, int b) { return strings[a].weight > strings[b].weight; });\n    orders.push_back(o2);\n    \n    // Order 3: Length ascending\n    vector<int> o3(M);\n    iota(o3.begin(), o3.end(), 0);\n    sort(o3.begin(), o3.end(), [&](int a, int b) { return strings[a].len < strings[b].len; });\n    orders.push_back(o3);\n    \n    // Order 4: Random shuffle\n    vector<int> o4(M);\n    iota(o4.begin(), o4.end(), 0);\n    shuffle(o4.begin(), o4.end(), rng);\n    orders.push_back(o4);\n    \n    // Order 5: Rarity based\n    vector<int> o5(M);\n    iota(o5.begin(), o5.end(), 0);\n    sort(o5.begin(), o5.end(), [&](int a, int b) {\n        double ra = 0, rb = 0;\n        for (char c : strings[a].unique_chars) ra += 1.0 / (global_char_freq[c] + 1);\n        for (char c : strings[b].unique_chars) rb += 1.0 / (global_char_freq[c] + 1);\n        return ra > rb;\n    });\n    orders.push_back(o5);\n    \n    // Order 6: Unique characters ascending\n    vector<int> o6(M);\n    iota(o6.begin(), o6.end(), 0);\n    sort(o6.begin(), o6.end(), [&](int a, int b) {\n        return strings[a].unique_chars.size() < strings[b].unique_chars.size();\n    });\n    orders.push_back(o6);\n    \n    // Order 7: Mixed - length then rarity\n    vector<int> o7(M);\n    iota(o7.begin(), o7.end(), 0);\n    sort(o7.begin(), o7.end(), [&](int a, int b) {\n        if (strings[a].len != strings[b].len) {\n            return strings[a].len > strings[b].len;\n        }\n        double ra = 0, rb = 0;\n        for (char c : strings[a].unique_chars) ra += 1.0 / (global_char_freq[c] + 1);\n        for (char c : strings[b].unique_chars) rb += 1.0 / (global_char_freq[c] + 1);\n        return ra > rb;\n    });\n    orders.push_back(o7);\n    \n    // Order 8: Character frequency based\n    vector<int> o8(M);\n    iota(o8.begin(), o8.end(), 0);\n    sort(o8.begin(), o8.end(), [&](int a, int b) {\n        double fa = 0, fb = 0;\n        for (char c : strings[a].unique_chars) fa += global_char_freq[c];\n        for (char c : strings[b].unique_chars) fb += global_char_freq[c];\n        return fa > fb;\n    });\n    orders.push_back(o8);\n    \n    // Order 9: Unique characters count (ascending) with shuffle\n    vector<int> o9(M);\n    iota(o9.begin(), o9.end(), 0);\n    shuffle(o9.begin(), o9.end(), rng);\n    sort(o9.begin(), o9.end(), [&](int a, int b) {\n        return strings[a].unique_chars.size() < strings[b].unique_chars.size();\n    });\n    orders.push_back(o9);\n    \n    // Order 10: Weight descending with random tie-breaking\n    vector<int> o10(M);\n    iota(o10.begin(), o10.end(), 0);\n    shuffle(o10.begin(), o10.end(), rng);\n    sort(o10.begin(), o10.end(), [&](int a, int b) {\n        if (strings[a].weight != strings[b].weight) {\n            return strings[a].weight > strings[b].weight;\n        }\n        return (rng() % 2) == 0;\n    });\n    orders.push_back(o10);\n    \n    // Order 11: Difficulty-based (fewest possible placements first)\n    vector<int> o11(M);\n    iota(o11.begin(), o11.end(), 0);\n    // We'll compute difficulty later in the loop, so just use weight for now\n    sort(o11.begin(), o11.end(), [&](int a, int b) {\n        return strings[a].len > strings[b].len; // Start with length\n    });\n    orders.push_back(o11);\n    \n    // Order 12: Random weighted by difficulty\n    vector<int> o12(M);\n    iota(o12.begin(), o12.end(), 0);\n    shuffle(o12.begin(), o12.end(), rng);\n    orders.push_back(o12);\n    \n    // Try multiple random seeds\n    vector<int> seeds = {0, 42, 12345, 98765, 11111, 22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999, 111111, 222222};\n    \n    double best_score = -1;\n    int best_c = -1, best_d = -1;\n    vector<string> best_mat;\n    \n    for (int seed : seeds) {\n        rng.seed(seed);\n        \n        for (const auto& order : orders) {\n            vector<string> mat(N, string(N, '.'));\n            vector<bool> covered(M, false);\n            int c = 0;\n            \n            // First pass: try with preferred character\n            for (int idx : order) {\n                if (covered[idx]) continue;\n                const string& str = strings[idx].s;\n                if (try_place_with_pref(mat, str, N, most_frequent) || \n                    try_place_horizontal(mat, str, N) || \n                    try_place_vertical(mat, str, N)) {\n                    covered[idx] = true;\n                    c++;\n                }\n            }\n            \n            // Second pass: try uncovered strings with different strategies\n            vector<int> uncovered;\n            for (int i = 0; i < M; ++i) {\n                if (!covered[i]) uncovered.push_back(i);\n            }\n            \n            // Sort uncovered by length descending\n            sort(uncovered.begin(), uncovered.end(), [&](int a, int b) {\n                return strings[a].len > strings[b].len;\n            });\n            \n            // Try uncovered strings multiple times with different approaches\n            for (int attempt = 0; attempt < 2; ++attempt) {\n                vector<int> still_uncovered;\n                for (int idx : uncovered) {\n                    if (covered[idx]) continue;\n                    const string& str = strings[idx].s;\n                    bool placed = false;\n                    \n                    if (attempt == 0) {\n                        placed = try_place_vertical(mat, str, N) || try_place_horizontal(mat, str, N);\n                    } else {\n                        placed = try_place_horizontal(mat, str, N) || try_place_vertical(mat, str, N);\n                    }\n                    \n                    if (placed) {\n                        covered[idx] = true;\n                        c++;\n                    } else {\n                        still_uncovered.push_back(idx);\n                    }\n                }\n                uncovered = still_uncovered;\n                if (uncovered.empty()) break;\n            }\n            \n            // Third pass: try with character preference for remaining\n            for (int idx : uncovered) {\n                if (covered[idx]) continue;\n                const string& str = strings[idx].s;\n                if (try_place_with_pref(mat, str, N, most_frequent)) {\n                    covered[idx] = true;\n                    c++;\n                }\n            }\n            \n            // Count dots\n            int d = 0;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (mat[i][j] == '.') d++;\n                }\n            }\n            \n            // Post-processing: try to place uncovered strings with zero conflicts\n            if (c < M) {\n                vector<bool> current_covered = covered;\n                bool changed = true;\n                while (changed && !uncovered.empty()) {\n                    changed = false;\n                    vector<int> still_uncovered;\n                    for (int idx : uncovered) {\n                        const string& str = strings[idx].s;\n                        int r, c_pos;\n                        bool horizontal;\n                        if (can_place_no_conflict(mat, str, N, r, c_pos, horizontal)) {\n                            place_at(mat, str, N, r, c_pos, horizontal);\n                            changed = true;\n                            c++;\n                            current_covered[idx] = true;\n                        } else {\n                            still_uncovered.push_back(idx);\n                        }\n                    }\n                    uncovered = still_uncovered;\n                }\n                \n                // Update dot count after post-processing\n                d = 0;\n                for (int i = 0; i < N; ++i) {\n                    for (int j = 0; j < N; ++j) {\n                        if (mat[i][j] == '.') d++;\n                    }\n                }\n            }\n            \n            // Calculate score\n            double score;\n            if (c < M) {\n                score = 1e8 * (double)c / M;\n            } else {\n                int total = 800;\n                score = 1e8 * (double)total / (total - d);\n            }\n            \n            // Update best solution\n            if (score > best_score) {\n                best_score = score;\n                best_c = c;\n                best_d = d;\n                best_mat = mat;\n            }\n        }\n    }\n    \n    // Final optimization: if we have full coverage, try to remove some characters\n    if (best_c == M) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (best_mat[i][j] != '.') {\n                        char temp = best_mat[i][j];\n                        best_mat[i][j] = '.';\n                        bool still_covered = true;\n                        for (int k = 0; k < M; ++k) {\n                            if (!is_covered(best_mat, strings[k].s, N)) {\n                                still_covered = false;\n                                break;\n                            }\n                        }\n                        if (still_covered) {\n                            changed = true;\n                            best_d++;\n                        } else {\n                            best_mat[i][j] = temp;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output the best matrix\n    for (int i = 0; i < N; ++i) {\n        cout << best_mat[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAX_ITER = 100000;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    // Precompute horizontal and vertical segments\n    vector<vector<int>> hid(N, vector<int>(N, -1));\n    vector<vector<int>> vid(N, vector<int>(N, -1));\n    int totalH = 0, totalV = 0;\n\n    // Horizontal segments\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '#') continue;\n            if (j == 0 || grid[i][j-1] == '#') {\n                int k = j;\n                while (k < N && grid[i][k] != '#') {\n                    hid[i][k] = totalH;\n                    k++;\n                }\n                totalH++;\n            }\n        }\n    }\n\n    // Vertical segments\n    for (int j = 0; j < N; j++) {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][j] == '#') continue;\n            if (i == 0 || grid[i-1][j] == '#') {\n                int k = i;\n                while (k < N && grid[k][j] != '#') {\n                    vid[k][j] = totalV;\n                    k++;\n                }\n                totalV++;\n            }\n        }\n    }\n\n    // Precompute distance from start for better candidate selection\n    vector<vector<int>> dist_from_start(N, vector<int>(N, INF));\n    {\n        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;\n        dist_from_start[si][sj] = 0;\n        pq.push({0, si, sj});\n        while (!pq.empty()) {\n            auto [cost, i, j] = pq.top();\n            pq.pop();\n            if (cost != dist_from_start[i][j]) continue;\n            const int dx[4] = {-1, 1, 0, 0};\n            const int dy[4] = {0, 0, -1, 1};\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) continue;\n                if (grid[ni][nj] == '#') continue;\n                int ncost = cost + (grid[ni][nj] - '0');\n                if (ncost < dist_from_start[ni][nj]) {\n                    dist_from_start[ni][nj] = ncost;\n                    pq.push({ncost, ni, nj});\n                }\n            }\n        }\n    }\n\n    // Try multiple strategies and pick the best\n    string best_route = \"\";\n    int best_coverage = -1;\n    int best_travel_time = INF;\n\n    // Try 4 different strategies\n    for (int strategy = 0; strategy < 4; strategy++) {\n        vector<bool> uncoveredH(totalH, true);\n        vector<bool> uncoveredV(totalV, true);\n        \n        int startH = hid[si][sj];\n        int startV = vid[si][sj];\n        if (startH != -1) uncoveredH[startH] = false;\n        if (startV != -1) uncoveredV[startV] = false;\n\n        int cur_i = si, cur_j = sj;\n        string route = \"\";\n        int travel_time = 0;\n        int covered_segments = 0;\n\n        int iter = 0;\n        while (iter < MAX_ITER) {\n            // Check if all segments are covered\n            bool has_uncovered = false;\n            for (bool b : uncoveredH) if (b) { has_uncovered = true; break; }\n            if (!has_uncovered) for (bool b : uncoveredV) if (b) { has_uncovered = true; break; }\n            if (!has_uncovered) break;\n\n            // Run Dijkstra\n            vector<vector<int>> dist(N, vector<int>(N, INF));\n            vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1,-1}));\n            vector<vector<char>> move_dir(N, vector<char>(N, 0));\n            priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq;\n\n            dist[cur_i][cur_j] = 0;\n            pq.push({0, cur_i, cur_j});\n\n            while (!pq.empty()) {\n                auto [cost, i, j] = pq.top();\n                pq.pop();\n                if (cost != dist[i][j]) continue;\n                const int dx[4] = {-1, 1, 0, 0};\n                const int dy[4] = {0, 0, -1, 1};\n                const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n                    if (grid[ni][nj] == '#') continue;\n                    int ncost = cost + (grid[ni][nj] - '0');\n                    if (ncost < dist[ni][nj]) {\n                        dist[ni][nj] = ncost;\n                        parent[ni][nj] = {i, j};\n                        move_dir[ni][nj] = dirs[d];\n                        pq.push({ncost, ni, nj});\n                    }\n                }\n            }\n\n            // Select candidate with improved scoring\n            int best_i = -1, best_j = -1;\n            int best_score = -INF;\n            int best_cost = INF;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] == '#' || dist[i][j] == INF) continue;\n                    int gain = 0;\n                    if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) gain++;\n                    if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) gain++;\n                    if (gain == 0) continue;\n                    \n                    // Different strategies for scoring\n                    int score;\n                    if (strategy == 0) {\n                        // Aggressive coverage: prioritize gain heavily\n                        score = gain * 100000 - dist[i][j];\n                    } else if (strategy == 1) {\n                        // Balanced: consider both gain and return cost\n                        score = gain * 50000 - dist[i][j] - dist_from_start[i][j];\n                    } else if (strategy == 2) {\n                        // Conservative: minimize travel time\n                        score = gain * 20000 - dist[i][j] * 2;\n                    } else {\n                        // Hybrid: balance between coverage and efficiency\n                        score = gain * 70000 - dist[i][j] - dist_from_start[i][j] * 0.5;\n                    }\n                    \n                    if (score > best_score || (score == best_score && dist[i][j] < best_cost)) {\n                        best_score = score;\n                        best_cost = dist[i][j];\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n\n            if (best_i == -1) break;\n\n            // Build path and update coverage\n            string path_moves = \"\";\n            int i = best_i, j = best_j;\n            while (i != cur_i || j != cur_j) {\n                char m = move_dir[i][j];\n                path_moves = m + path_moves;\n                // Update coverage along the path\n                if (hid[i][j] != -1 && uncoveredH[hid[i][j]]) {\n                    uncoveredH[hid[i][j]] = false;\n                    covered_segments++;\n                }\n                if (vid[i][j] != -1 && uncoveredV[vid[i][j]]) {\n                    uncoveredV[vid[i][j]] = false;\n                    covered_segments++;\n                }\n                auto [pi, pj] = parent[i][j];\n                i = pi;\n                j = pj;\n            }\n\n            route += path_moves;\n            travel_time += best_cost;\n            cur_i = best_i;\n            cur_j = best_j;\n            iter++;\n        }\n\n        // Return to start\n        vector<vector<int>> dist_ret(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> parent_ret(N, vector<pair<int,int>>(N, {-1,-1}));\n        vector<vector<char>> move_dir_ret(N, vector<char>(N, 0));\n        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<tuple<int, int, int>>> pq_ret;\n\n        dist_ret[cur_i][cur_j] = 0;\n        pq_ret.push({0, cur_i, cur_j});\n\n        while (!pq_ret.empty()) {\n            auto [cost, i, j] = pq_ret.top();\n            pq_ret.pop();\n            if (cost != dist_ret[i][j]) continue;\n            const int dx[4] = {-1, 1, 0, 0};\n            const int dy[4] = {0, 0, -1, 1};\n            const char dirs[4] = {'U', 'D', 'L', 'R'};\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) continue;\n                if (grid[ni][nj] == '#') continue;\n                int ncost = cost + (grid[ni][nj] - '0');\n                if (ncost < dist_ret[ni][nj]) {\n                    dist_ret[ni][nj] = ncost;\n                    parent_ret[ni][nj] = {i, j};\n                    move_dir_ret[ni][nj] = dirs[d];\n                    pq_ret.push({ncost, ni, nj});\n                }\n            }\n        }\n\n        if (dist_ret[si][sj] != INF) {\n            string return_path = \"\";\n            int i = si, j = sj;\n            while (i != cur_i || j != cur_j) {\n                auto [pi, pj] = parent_ret[i][j];\n                char m = move_dir_ret[i][j];\n                return_path = m + return_path;\n                i = pi;\n                j = pj;\n            }\n            route += return_path;\n            travel_time += dist_ret[si][sj];\n            \n            // Update best solution\n            if (covered_segments > best_coverage || (covered_segments == best_coverage && travel_time < best_travel_time)) {\n                best_coverage = covered_segments;\n                best_travel_time = travel_time;\n                best_route = route;\n            }\n        }\n\n        // Early exit if we found perfect coverage\n        if (best_coverage == totalH + totalV) {\n            break;\n        }\n    }\n\n    // Fallback: ensure we have a valid route\n    if (best_route.empty()) {\n        best_route = \"\";\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != '#' && (i != si || j != sj)) {\n                    if (j+1 < N && grid[i][j+1] != '#') {\n                        best_route += \"RL\";\n                    }\n                    if (i+1 < N && grid[i+1][j] != '#') {\n                        best_route += \"DU\";\n                    }\n                }\n            }\n        }\n    }\n\n    cout << best_route << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <tuple>\n#include <random>\n\nusing namespace std;\n\nstruct Task {\n    int id;\n    vector<int> requirements;\n    vector<int> dependents;\n    int remaining_dependencies;\n    double total_requirement;\n    int depth_forward;\n};\n\nstruct SkillDistribution {\n    double mean;\n    double variance;\n    int count;\n    \n    SkillDistribution() : mean(0.0), variance(100.0), count(0) {}\n    \n    void update(double observed_value) {\n        count++;\n        double alpha = 1.0 / (1.0 + count);\n        mean = (1 - alpha) * mean + alpha * observed_value;\n        variance = (1 - alpha) * variance + alpha * pow(observed_value - mean, 2);\n        mean = max(0.0, mean);\n    }\n};\n\nstruct TeamMember {\n    vector<SkillDistribution> skills;\n    int tasks_completed;\n    \n    TeamMember(int k) : tasks_completed(0) {\n        skills.resize(k);\n    }\n};\n\nstruct AssignmentCandidate {\n    double score;\n    int member_idx;\n    int task_idx;\n    \n    bool operator<(const AssignmentCandidate& other) const {\n        return score > other.score;\n    }\n};\n\nclass TaskScheduler {\nprivate:\n    int N, M, K;\n    vector<Task> tasks;\n    vector<TeamMember> members;\n    vector<bool> task_completed;\n    vector<int> task_assigned_to;\n    vector<int> member_assigned_task;\n    vector<int> start_day;\n    mt19937 rng;\n    \npublic:\n    TaskScheduler(int n, int m, int k) : N(n), M(m), K(k), rng(42) {\n        tasks.resize(N);\n        task_completed.assign(N, false);\n        task_assigned_to.assign(N, -1);\n        member_assigned_task.assign(M, -1);\n        start_day.assign(N, -1);\n        \n        for (int i = 0; i < M; i++) {\n            members.emplace_back(K);\n        }\n    }\n    \n    void setTaskRequirements(int task_idx, const vector<int>& reqs) {\n        tasks[task_idx].id = task_idx;\n        tasks[task_idx].requirements = reqs;\n        tasks[task_idx].remaining_dependencies = 0;\n        \n        double total_req = 0.0;\n        for (int req : reqs) total_req += req;\n        tasks[task_idx].total_requirement = total_req;\n    }\n    \n    void addDependency(int u, int v) {\n        tasks[u].dependents.push_back(v);\n        tasks[v].remaining_dependencies++;\n    }\n    \n    void computeDepthForward() {\n        // Compute critical path depth forward (longest path to completion)\n        for (int i = N-1; i >= 0; i--) {\n            if (tasks[i].dependents.empty()) {\n                tasks[i].depth_forward = 0;\n            } else {\n                int max_depth = 0;\n                for (int dep : tasks[i].dependents) {\n                    max_depth = max(max_depth, tasks[dep].depth_forward);\n                }\n                tasks[i].depth_forward = 1 + max_depth;\n            }\n        }\n    }\n    \n    bool areDependenciesComplete(int task_idx) {\n        return tasks[task_idx].remaining_dependencies == 0;\n    }\n    \n    // Estimate time with uncertainty\n    double estimateTime(int member_idx, int task_idx, double& uncertainty) {\n        double gap = 0.0;\n        const auto& reqs = tasks[task_idx].requirements;\n        const auto& member_skills = members[member_idx].skills;\n        \n        for (int k = 0; k < K; k++) {\n            double skill_estimate = max(0.0, member_skills[k].mean);\n            if (reqs[k] > skill_estimate) {\n                gap += reqs[k] - skill_estimate;\n            }\n        }\n        \n        if (gap == 0.0) {\n            uncertainty = 0.0;\n            return 1.0;\n        }\n        \n        uncertainty = 0.0;\n        for (int k = 0; k < K; k++) {\n            if (reqs[k] > member_skills[k].mean) {\n                uncertainty += member_skills[k].variance;\n            }\n        }\n        uncertainty = sqrt(uncertainty);\n        \n        return 1.0 + gap + uncertainty * 0.1;\n    }\n    \n    void updateSkills(int member_idx, int task_idx, int time_taken) {\n        if (time_taken <= 1) {\n            members[member_idx].tasks_completed++;\n            return;\n        }\n        \n        double total_gap = time_taken - 1.0;\n        const auto& reqs = tasks[task_idx].requirements;\n        auto& member_skills = members[member_idx].skills;\n        \n        vector<double> gaps(K, 0.0);\n        double total_gap_calc = 0.0;\n        for (int k = 0; k < K; k++) {\n            double skill_estimate = member_skills[k].mean;\n            if (reqs[k] > skill_estimate) {\n                gaps[k] = reqs[k] - skill_estimate;\n                total_gap_calc += gaps[k];\n            }\n        }\n        \n        if (total_gap_calc > 0) {\n            for (int k = 0; k < K; k++) {\n                if (gaps[k] > 0) {\n                    double observed_deficit = (gaps[k] / total_gap_calc) * total_gap;\n                    member_skills[k].update(observed_deficit);\n                    member_skills[k].mean = min(member_skills[k].mean, (double)reqs[k]);\n                }\n            }\n        }\n        \n        members[member_idx].tasks_completed++;\n    }\n    \n    void processCompletions(int current_day, const vector<int>& completed_members) {\n        for (int member_idx : completed_members) {\n            int task_idx = member_assigned_task[member_idx];\n            if (task_idx == -1) continue;\n            \n            int time_taken = current_day - start_day[task_idx] + 1;\n            updateSkills(member_idx, task_idx, time_taken);\n            \n            task_completed[task_idx] = true;\n            task_assigned_to[task_idx] = -1;\n            member_assigned_task[member_idx] = -1;\n            \n            for (int dependent : tasks[task_idx].dependents) {\n                tasks[dependent].remaining_dependencies--;\n            }\n        }\n    }\n    \n    vector<pair<int, int>> getAssignments(int current_day) {\n        vector<int> free_members;\n        for (int i = 0; i < M; i++) {\n            if (member_assigned_task[i] == -1) {\n                free_members.push_back(i);\n            }\n        }\n        \n        vector<int> available_tasks;\n        for (int i = 0; i < N; i++) {\n            if (!task_completed[i] && task_assigned_to[i] == -1 && areDependenciesComplete(i)) {\n                available_tasks.push_back(i);\n            }\n        }\n        \n        if (available_tasks.empty() || free_members.empty()) {\n            return {};\n        }\n        \n        vector<AssignmentCandidate> candidates;\n        \n        for (int task_idx : available_tasks) {\n            for (int member_idx : free_members) {\n                double uncertainty;\n                double time_est = estimateTime(member_idx, task_idx, uncertainty);\n                \n                // Multi-factor scoring:\n                // 1. Time efficiency: 1000/(time+1)\n                // 2. Criticality bonus: depth * 50\n                // 3. Exploration: -uncertainty * 0.5 (encourages learning)\n                // 4. Experience bonus: +tasks_completed * 10\n                double score = 1000.0 / (time_est + 1.0) + \n                               tasks[task_idx].depth_forward * 50.0 - \n                               uncertainty * 0.5 + \n                               members[member_idx].tasks_completed * 10.0;\n                \n                // Add tiny random component to break ties\n                score += (rng() % 1000) * 0.001;\n                \n                candidates.push_back({score, member_idx, task_idx});\n            }\n        }\n        \n        sort(candidates.begin(), candidates.end());\n        \n        vector<pair<int, int>> assignments;\n        vector<bool> member_used(M, false);\n        vector<bool> task_used(N, false);\n        \n        for (const auto& cand : candidates) {\n            if (member_used[cand.member_idx] || task_used[cand.task_idx]) continue;\n            \n            assignments.emplace_back(cand.member_idx, cand.task_idx);\n            member_used[cand.member_idx] = true;\n            task_used[cand.task_idx] = true;\n            \n            member_assigned_task[cand.member_idx] = cand.task_idx;\n            task_assigned_to[cand.task_idx] = cand.member_idx;\n            start_day[cand.task_idx] = -1;\n        }\n        \n        return assignments;\n    }\n    \n    void setStartDay(int task_idx, int day) {\n        start_day[task_idx] = day;\n    }\n    \n    bool allTasksCompleted() {\n        for (bool completed : task_completed) {\n            if (!completed) return false;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    TaskScheduler scheduler(N, M, K);\n    \n    for (int i = 0; i < N; i++) {\n        vector<int> reqs(K);\n        for (int k = 0; k < K; k++) {\n            cin >> reqs[k];\n        }\n        scheduler.setTaskRequirements(i, reqs);\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        scheduler.addDependency(u, v);\n    }\n    \n    scheduler.computeDepthForward();\n    \n    for (int day = 1; day <= 2000; day++) {\n        if (day > 1) {\n            int n_completed;\n            cin >> n_completed;\n            \n            if (n_completed == -1) {\n                break;\n            }\n            \n            vector<int> completed_members(n_completed);\n            for (int i = 0; i < n_completed; i++) {\n                cin >> completed_members[i];\n                completed_members[i]--;\n            }\n            \n            scheduler.processCompletions(day - 1, completed_members);\n        }\n        \n        if (scheduler.allTasksCompleted()) {\n            cout << 0 << endl;\n            cout.flush();\n            while (day <= 2000) {\n                int check;\n                cin >> check;\n                if (check == -1) break;\n                day++;\n            }\n            break;\n        }\n        \n        auto assignments = scheduler.getAssignments(day);\n        \n        cout << assignments.size();\n        for (auto& assignment : assignments) {\n            int member_idx = assignment.first;\n            int task_idx = assignment.second;\n            scheduler.setStartDay(task_idx, day);\n            cout << \" \" << member_idx + 1 << \" \" << task_idx + 1;\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Order {\n    int a, b, c, d;\n    int index;\n};\n\ninline int manhattan(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nvector<Order> selectOrdersWithWeight(const vector<Order>& allOrders, int weight) {\n    Point office(400, 400);\n    \n    vector<pair<int, int>> costIndex;\n    costIndex.reserve(1000);\n    for (int i = 0; i < 1000; i++) {\n        Point pickup(allOrders[i].a, allOrders[i].b);\n        Point delivery(allOrders[i].c, allOrders[i].d);\n        int cost = manhattan(office, pickup) + manhattan(pickup, delivery) + manhattan(delivery, office);\n        costIndex.push_back({cost, i});\n    }\n    \n    sort(costIndex.begin(), costIndex.end());\n    \n    vector<Order> candidates;\n    candidates.reserve(100);\n    for (int i = 0; i < 100; i++) {\n        candidates.push_back(allOrders[costIndex[i].second]);\n    }\n    \n    vector<Order> selected;\n    vector<bool> used(100, false);\n    selected.push_back(candidates[0]);\n    used[0] = true;\n    \n    while (selected.size() < 50) {\n        int bestIdx = -1;\n        int bestScore = 1e9;\n        \n        for (int i = 0; i < 100; i++) {\n            if (used[i]) continue;\n            \n            int individualCost = manhattan(office, {candidates[i].a, candidates[i].b}) +\n                                manhattan({candidates[i].a, candidates[i].b}, {candidates[i].c, candidates[i].d}) +\n                                manhattan({candidates[i].c, candidates[i].d}, office);\n            \n            int minDist = 1e9;\n            for (const Order& sel : selected) {\n                Point selPoints[2] = {{sel.a, sel.b}, {sel.c, sel.d}};\n                Point candPickup(candidates[i].a, candidates[i].b);\n                Point candDelivery(candidates[i].c, candidates[i].d);\n                \n                minDist = min(minDist, manhattan(candPickup, selPoints[0]));\n                minDist = min(minDist, manhattan(candPickup, selPoints[1]));\n                minDist = min(minDist, manhattan(candDelivery, selPoints[0]));\n                minDist = min(minDist, manhattan(candDelivery, selPoints[1]));\n            }\n            \n            int score = individualCost + minDist / weight;\n            if (score < bestScore) {\n                bestScore = score;\n                bestIdx = i;\n            }\n        }\n        \n        if (bestIdx != -1) {\n            selected.push_back(candidates[bestIdx]);\n            used[bestIdx] = true;\n        } else {\n            break;\n        }\n    }\n    \n    for (int i = 0; i < 100 && selected.size() < 50; i++) {\n        if (!used[i]) {\n            selected.push_back(candidates[i]);\n            used[i] = true;\n        }\n    }\n    \n    return selected;\n}\n\nvector<Point> buildRoute(const vector<Order>& selected) {\n    vector<Point> route;\n    route.reserve(102);\n    Point office(400, 400);\n    route.push_back(office);\n    \n    vector<int> state(selected.size(), 0);\n    Point current = office;\n    int delivered = 0;\n    int n = selected.size();\n    \n    while (delivered < n) {\n        int bestDist = 1e9;\n        Point bestPoint;\n        int bestIdx = -1;\n        bool isDelivery = false;\n        \n        for (int i = 0; i < n; i++) {\n            if (state[i] == 0) {\n                int dist = manhattan(current, {selected[i].a, selected[i].b});\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPoint = {selected[i].a, selected[i].b};\n                    bestIdx = i;\n                    isDelivery = false;\n                }\n            }\n        }\n        \n        for (int i = 0; i < n; i++) {\n            if (state[i] == 1) {\n                int dist = manhattan(current, {selected[i].c, selected[i].d});\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestPoint = {selected[i].c, selected[i].d};\n                    bestIdx = i;\n                    isDelivery = true;\n                }\n            }\n        }\n        \n        route.push_back(bestPoint);\n        current = bestPoint;\n        \n        if (isDelivery) {\n            state[bestIdx] = 2;\n            delivered++;\n        } else {\n            state[bestIdx] = 1;\n        }\n    }\n    \n    route.push_back(office);\n    return route;\n}\n\nint calculateCost(const vector<Point>& route) {\n    int cost = 0;\n    for (int i = 0; i < (int)route.size() - 1; i++) {\n        cost += manhattan(route[i], route[i+1]);\n    }\n    return cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<Order> allOrders;\n    allOrders.reserve(1000);\n    for (int i = 0; i < 1000; i++) {\n        Order order;\n        cin >> order.a >> order.b >> order.c >> order.d;\n        order.index = i + 1;\n        allOrders.push_back(order);\n    }\n    \n    // Try different weights and pick the best\n    vector<int> weights = {5, 10, 15, 20};\n    int bestCost = 1e9;\n    vector<Order> bestSelected;\n    vector<Point> bestRoute;\n    \n    for (int weight : weights) {\n        vector<Order> selected = selectOrdersWithWeight(allOrders, weight);\n        vector<Point> route = buildRoute(selected);\n        int cost = calculateCost(route);\n        \n        if (cost < bestCost) {\n            bestCost = cost;\n            bestSelected = selected;\n            bestRoute = route;\n        }\n    }\n    \n    cout << bestSelected.size();\n    for (const Order& order : bestSelected) {\n        cout << \" \" << order.index;\n    }\n    cout << \"\\n\";\n    \n    cout << bestRoute.size();\n    for (const Point& p : bestRoute) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct DSU {\n    vector<int> parent, rank;\n    DSU() {\n        parent.resize(N);\n        rank.resize(N, 0);\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) {\n            parent[x] = y;\n        } else if (rank[x] > rank[y]) {\n            parent[y] = x;\n        } else {\n            parent[y] = x;\n            rank[x]++;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read coordinates\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n\n    // Read edges\n    vector<pair<int, int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n    }\n\n    // Precompute baseline distances\n    vector<int> d(M);\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        long long dx = x[u] - x[v];\n        long long dy = y[u] - y[v];\n        double dist = sqrt(dx*dx + dy*dy);\n        d[i] = (int)round(dist);\n    }\n\n    DSU dsu;\n    vector<vector<int>> remaining_edges(N, vector<int>(N, 0));\n    \n    // Initialize remaining_edges matrix\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].first, v = edges[i].second;\n        remaining_edges[u][v]++;\n        remaining_edges[v][u]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].first;\n        int v = edges[i].second;\n        \n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n\n        if (ru == rv) {\n            cout << \"0\" << endl;\n            continue;\n        }\n\n        // Get current edge count between components\n        int count = remaining_edges[ru][rv];\n        // More selective: threshold 1.7 instead of 1.8\n        bool take = (count == 1) || (l_i * 10 <= 17 * d[i]);\n\n        if (take) {\n            cout << \"1\" << endl;\n            \n            if (dsu.unite(ru, rv)) {\n                int new_root = dsu.find(ru);\n                int old_root = (new_root == ru) ? rv : ru;\n                \n                // Clear the edge between ru and rv\n                remaining_edges[ru][rv] = 0;\n                remaining_edges[rv][ru] = 0;\n                \n                // Update matrix only for vertices that are roots\n                for (int j = 0; j < N; j++) {\n                    if (j == new_root || j == old_root) continue;\n                    int rj = dsu.find(j);\n                    if (rj == new_root) continue;\n                    \n                    remaining_edges[new_root][rj] += remaining_edges[old_root][j];\n                    remaining_edges[rj][new_root] = remaining_edges[new_root][rj];\n                    remaining_edges[old_root][j] = 0;\n                    remaining_edges[j][old_root] = 0;\n                }\n            }\n        } else {\n            cout << \"0\" << endl;\n            // Decrement remaining edge count\n            remaining_edges[ru][rv]--;\n            remaining_edges[rv][ru]--;\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\nusing namespace std;\n\nconst int dx4[4] = {-1, 1, 0, 0};\nconst int dy4[4] = {0, 0, -1, 1};\nconst int INF = 1e9;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<int> pet_x(N), pet_y(N), pet_type(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n        pet_x[i]--; \n        pet_y[i]--;\n    }\n\n    int M;\n    cin >> M;\n    vector<int> human_x(M), human_y(M);\n    for (int i = 0; i < M; i++) {\n        cin >> human_x[i] >> human_y[i];\n        human_x[i]--;\n        human_y[i]--;\n    }\n\n    bool blocked[30][30] = {false};\n\n    for (int turn = 0; turn < 300; turn++) {\n        vector<char> actions(M, '.');\n        vector<bool> will_block(M, false);\n        vector<int> block_direction(M, -1);\n        \n        // Precompute pet positions and average\n        vector<pair<int, int>> pet_positions(N);\n        double avg_pet_x = 0, avg_pet_y = 0;\n        int min_global_dist = INF;\n        for (int j = 0; j < N; j++) {\n            pet_positions[j] = {pet_x[j], pet_y[j]};\n            avg_pet_x += pet_x[j];\n            avg_pet_y += pet_y[j];\n        }\n        avg_pet_x /= N;\n        avg_pet_y /= N;\n        \n        // Find global minimum distance between any human and any pet\n        for (int i = 0; i < M; i++) {\n            for (int j = 0; j < N; j++) {\n                int dist = abs(human_x[i] - pet_x[j]) + abs(human_y[i] - pet_y[j]);\n                if (dist < min_global_dist) min_global_dist = dist;\n            }\n        }\n        \n        // Phase 1: Determine all blocking actions with adaptive strategy\n        for (int i = 0; i < M; i++) {\n            int hx = human_x[i], hy = human_y[i];\n            \n            // Find closest pet\n            int min_dist = INF;\n            int closest_pet = -1;\n            for (int j = 0; j < N; j++) {\n                int dist = abs(hx - pet_x[j]) + abs(hy - pet_y[j]);\n                if (dist < min_dist) {\n                    min_dist = dist;\n                    closest_pet = j;\n                }\n            }\n            \n            // Calculate distance from average pet position\n            int avg_dist = abs(hx - avg_pet_x) + abs(hy - avg_pet_y);\n            \n            // Adaptive blocking based on global pet proximity\n            int center_dist = abs(hx - 14) + abs(hy - 14);\n            bool should_block = false;\n            \n            if (min_global_dist <= 3) {\n                // Pets are very close - be extremely aggressive with blocking\n                should_block = (min_dist <= 8) || (center_dist <= 3);\n            } else if (min_global_dist <= 6) {\n                // Pets are moderately close - be aggressive\n                should_block = (min_dist <= 7) || (center_dist <= 2);\n            } else {\n                // Pets are far - focus on creating large barriers\n                should_block = (min_dist <= 6) || (center_dist <= 2) || (avg_dist > 15);\n            }\n            \n            if (should_block) {\n                // Create priority directions\n                vector<int> priority_dirs;\n                \n                // Priority 1: Block toward center to create enclosure\n                if (center_dist > 0) {\n                    if (hx < 14) priority_dirs.push_back(1); // down\n                    else if (hx > 14) priority_dirs.push_back(0); // up\n                    if (hy < 14) priority_dirs.push_back(3); // right\n                    else if (hy > 14) priority_dirs.push_back(2); // left\n                }\n                \n                // Priority 2: Block away from closest pet\n                if (closest_pet != -1) {\n                    int dx = pet_x[closest_pet] - hx;\n                    int dy = pet_y[closest_pet] - hy;\n                    if (abs(dx) > abs(dy)) {\n                        priority_dirs.push_back(dx > 0 ? 0 : 1);\n                        priority_dirs.push_back(dy > 0 ? 3 : 2);\n                    } else {\n                        priority_dirs.push_back(dy > 0 ? 3 : 2);\n                        priority_dirs.push_back(dx > 0 ? 0 : 1);\n                    }\n                }\n                \n                // Priority 3: Block away from average pet position\n                int avg_dx = avg_pet_x - hx;\n                int avg_dy = avg_pet_y - hy;\n                if (abs(avg_dx) > abs(avg_dy)) {\n                    priority_dirs.push_back(avg_dx > 0 ? 0 : 1);\n                    priority_dirs.push_back(avg_dy > 0 ? 3 : 2);\n                } else {\n                    priority_dirs.push_back(avg_dy > 0 ? 3 : 2);\n                    priority_dirs.push_back(avg_dx > 0 ? 0 : 1);\n                }\n                \n                // Remove duplicates\n                sort(priority_dirs.begin(), priority_dirs.end());\n                priority_dirs.erase(unique(priority_dirs.begin(), priority_dirs.end()), priority_dirs.end());\n                \n                // Try each direction\n                for (int d : priority_dirs) {\n                    int bx = hx + dx4[d];\n                    int by = hy + dy4[d];\n                    if (bx < 0 || bx >= 30 || by < 0 || by >= 30) continue;\n                    if (blocked[bx][by]) continue;\n                    \n                    // Check if square is occupied\n                    bool occupied = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == bx && pet_y[j] == by) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    for (int j = 0; j < M; j++) {\n                        if (human_x[j] == bx && human_y[j] == by) {\n                            occupied = true;\n                            break;\n                        }\n                    }\n                    if (occupied) continue;\n                    \n                    // Check if any adjacent square has a pet\n                    bool has_adjacent_pet = false;\n                    for (int k = 0; k < 4; k++) {\n                        int nx = bx + dx4[k];\n                        int ny = by + dy4[k];\n                        if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                        for (int j = 0; j < N; j++) {\n                            if (pet_x[j] == nx && pet_y[j] == ny) {\n                                has_adjacent_pet = true;\n                                break;\n                            }\n                        }\n                        if (has_adjacent_pet) break;\n                    }\n                    if (has_adjacent_pet) continue;\n                    \n                    // This is a valid blocking action\n                    will_block[i] = true;\n                    block_direction[i] = d;\n                    actions[i] = (d == 0) ? 'u' : (d == 1) ? 'd' : (d == 2) ? 'l' : 'r';\n                    break;\n                }\n            }\n        }\n        \n        // Create temporary blocked grid\n        bool temp_blocked[30][30];\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                temp_blocked[i][j] = blocked[i][j];\n            }\n        }\n        \n        for (int i = 0; i < M; i++) {\n            if (will_block[i] && block_direction[i] != -1) {\n                int bx = human_x[i] + dx4[block_direction[i]];\n                int by = human_y[i] + dy4[block_direction[i]];\n                if (bx >= 0 && bx < 30 && by >= 0 && by < 30) {\n                    temp_blocked[bx][by] = true;\n                }\n            }\n        }\n        \n        // Phase 2: Determine movement for non-blocking humans\n        for (int i = 0; i < M; i++) {\n            if (will_block[i]) continue;\n            \n            int hx = human_x[i], hy = human_y[i];\n            \n            // Find closest pet\n            int min_dist = INF;\n            int closest_pet = -1;\n            for (int j = 0; j < N; j++) {\n                int dist = abs(hx - pet_x[j]) + abs(hy - pet_y[j]);\n                if (dist < min_dist) {\n                    min_dist = dist;\n                    closest_pet = j;\n                }\n            }\n            \n            // Adaptive pet avoidance based on global proximity\n            int avoidance_threshold = (min_global_dist <= 3) ? 8 : (min_global_dist <= 6) ? 7 : 6;\n            \n            if (min_dist <= avoidance_threshold) {\n                // Move away from closest pet\n                int best_dir = -1;\n                int best_dist = -1;\n                for (int d = 0; d < 4; d++) {\n                    int nx = hx + dx4[d];\n                    int ny = hy + dy4[d];\n                    if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                    if (temp_blocked[nx][ny]) continue;\n                    \n                    // Check if square has a pet\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (has_pet) continue;\n                    \n                    int new_dist = abs(nx - pet_x[closest_pet]) + abs(ny - pet_y[closest_pet]);\n                    if (new_dist > best_dist) {\n                        best_dist = new_dist;\n                        best_dir = d;\n                    }\n                }\n                \n                if (best_dir != -1) {\n                    actions[i] = (best_dir == 0) ? 'U' : (best_dir == 1) ? 'D' : (best_dir == 2) ? 'L' : 'R';\n                    continue;\n                }\n            }\n            \n            // Otherwise, prioritize moving toward center but avoid pets\n            int target_x = 14, target_y = 14;\n            int best_dir = -1;\n            int best_score = -1000000;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = hx + dx4[d];\n                int ny = hy + dy4[d];\n                if (nx < 0 || nx >= 30 || ny < 0 || ny >= 30) continue;\n                if (temp_blocked[nx][ny]) continue;\n                \n                // Check if square has a pet\n                bool has_pet = false;\n                for (int j = 0; j < N; j++) {\n                    if (pet_x[j] == nx && pet_y[j] == ny) {\n                        has_pet = true;\n                        break;\n                    }\n                }\n                if (has_pet) continue;\n                \n                // Score based on multiple factors\n                int center_dist = abs(nx - target_x) + abs(ny - target_y);\n                int pet_dist = INF;\n                for (int j = 0; j < N; j++) {\n                    int dist = abs(nx - pet_x[j]) + abs(ny - pet_y[j]);\n                    if (dist < pet_dist) pet_dist = dist;\n                }\n                \n                // Strongly favor being far from pets (adaptive weight)\n                int pet_weight = (min_global_dist <= 3) ? 200 : (min_global_dist <= 6) ? 150 : 120;\n                int score = pet_dist * pet_weight;\n                \n                // Then favor moving toward center\n                score -= center_dist * 5;\n                \n                // Bonus for being in corners/edges (more defensible)\n                if (nx <= 2 || nx >= 27 || ny <= 2 || ny >= 27) score += 30;\n                \n                // Bonus for being near other humans (coordination)\n                int near_human_count = 0;\n                for (int j = 0; j < M; j++) {\n                    if (i == j) continue;\n                    int dist = abs(nx - human_x[j]) + abs(ny - human_y[j]);\n                    if (dist <= 2) near_human_count++;\n                }\n                score += near_human_count * 10;\n                \n                // Penalty for moving toward average pet position\n                double avg_dx = nx - avg_pet_x;\n                double avg_dy = ny - avg_pet_y;\n                double avg_dist_score = avg_dx * avg_dx + avg_dy * avg_dy;\n                score -= (int)avg_dist_score / 50;\n                \n                // Bonus for moving away from global pet cluster\n                if (min_global_dist > 5) {\n                    // If pets are far, encourage expansion\n                    if (center_dist <= 5) score += 50;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = d;\n                }\n            }\n            \n            if (best_dir != -1) {\n                actions[i] = (best_dir == 0) ? 'U' : (best_dir == 1) ? 'D' : (best_dir == 2) ? 'L' : 'R';\n            }\n        }\n\n        // Output actions\n        for (int i = 0; i < M; i++) {\n            cout << actions[i];\n        }\n        cout << endl;\n        cout.flush();\n\n        // Update grid with new blocks\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'u' || actions[i] == 'd' || actions[i] == 'l' || actions[i] == 'r') {\n                int bx = human_x[i], by = human_y[i];\n                if (actions[i] == 'u') bx--;\n                else if (actions[i] == 'd') bx++;\n                else if (actions[i] == 'l') by--;\n                else if (actions[i] == 'r') by++;\n                if (bx >= 0 && bx < 30 && by >= 0 && by < 30) {\n                    blocked[bx][by] = true;\n                }\n            }\n        }\n\n        // Update human positions\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U' || actions[i] == 'D' || actions[i] == 'L' || actions[i] == 'R') {\n                int nx = human_x[i], ny = human_y[i];\n                if (actions[i] == 'U') nx--;\n                else if (actions[i] == 'D') nx++;\n                else if (actions[i] == 'L') ny--;\n                else if (actions[i] == 'R') ny++;\n                if (nx >= 0 && nx < 30 && ny >= 0 && ny < 30 && !blocked[nx][ny]) {\n                    bool has_pet = false;\n                    for (int j = 0; j < N; j++) {\n                        if (pet_x[j] == nx && pet_y[j] == ny) {\n                            has_pet = true;\n                            break;\n                        }\n                    }\n                    if (!has_pet) {\n                        human_x[i] = nx;\n                        human_y[i] = ny;\n                    }\n                }\n            }\n        }\n\n        // Update pet positions\n        for (int i = 0; i < N; i++) {\n            string move_str;\n            cin >> move_str;\n            if (move_str == \".\") continue;\n            for (char c : move_str) {\n                if (c == 'U') pet_x[i]--;\n                else if (c == 'D') pet_x[i]++;\n                else if (c == 'L') pet_y[i]--;\n                else if (c == 'R') pet_y[i]++;\n            }\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <tuple>\n#include <climits>\nusing namespace std;\n\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nbool canMove(int i, int j, int d, const vector<string>& h, const vector<string>& v) {\n    if (d == 0) { // U\n        if (i == 0) return false;\n        if (v[i-1][j] == '1') return false;\n    } else if (d == 1) { // D\n        if (i == 19) return false;\n        if (v[i][j] == '1') return false;\n    } else if (d == 2) { // L\n        if (j == 0) return false;\n        if (h[i][j-1] == '1') return false;\n    } else if (d == 3) { // R\n        if (j == 19) return false;\n        if (h[i][j] == '1') return false;\n    }\n    return true;\n}\n\nint main() {\n    int s_i, s_j, t_i, t_j;\n    double p;\n    cin >> s_i >> s_j >> t_i >> t_j >> p;\n\n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n\n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n\n    // Check if already at office\n    if (s_i == t_i && s_j == t_j) {\n        cout << \"\" << endl;\n        return 0;\n    }\n\n    // BFS to find shortest path\n    vector<vector<int>> dist(20, vector<int>(20, INT_MAX));\n    vector<vector<pair<int, int>>> parent(20, vector<pair<int, int>>(20, {-1, -1}));\n    vector<vector<char>> move_char(20, vector<char>(20, ' '));\n\n    queue<pair<int, int>> q;\n    dist[s_i][s_j] = 0;\n    q.push({s_i, s_j});\n\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (i == t_i && j == t_j) break;\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 >= 20 || nj < 0 || nj >= 20) continue;\n            if (!canMove(i, j, d, h, v)) continue;\n\n            if (dist[ni][nj] == INT_MAX) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent[ni][nj] = {i, j};\n                move_char[ni][nj] = dir_char[d];\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // Reconstruct path\n    string path = \"\";\n    int i = t_i, j = t_j;\n    while (i != s_i || j != s_j) {\n        path += move_char[i][j];\n        auto [pi, pj] = parent[i][j];\n        i = pi;\n        j = pj;\n    }\n    reverse(path.begin(), path.end());\n\n    if (path.empty()) {\n        cout << string(200, 'U') << endl;\n        return 0;\n    }\n\n    int L = path.size();\n    \n    // Strategy: ensure each move is repeated at least twice, then distribute remaining\n    string result = \"\";\n    int remaining = 200;\n    \n    // First pass: give each move at least 2 repetitions\n    for (int i = 0; i < L; i++) {\n        if (remaining >= 2) {\n            result += path[i];\n            result += path[i];\n            remaining -= 2;\n        } else {\n            break;\n        }\n    }\n    \n    // Second pass: distribute remaining moves equally\n    int extra = remaining;\n    if (extra > 0) {\n        for (int i = 0; i < extra; i++) {\n            result += path[i % L];\n        }\n    }\n\n    cout << result << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Process 100 test cases\n    for (int tc = 0; tc < 100; tc++) {\n        // Read 30 lines of 30 characters\n        for (int i = 0; i < 30; i++) {\n            string line;\n            cin >> line;\n            // We don't actually use the input for this simple solution\n        }\n\n        // Output 900 zeros (one per tile)\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                cout << '0';\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <unordered_set>\nusing namespace std;\nusing namespace std::chrono;\n\nint N, T;\nvector<vector<int>> board;\nint empty_i, empty_j;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\nconst int opp[4] = {1, 0, 3, 2};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Stats {\n    int largest_tree;\n    int total_in_trees;\n    int num_components;\n    int total_tiles;\n};\n\nStats compute_stats() {\n    Stats s = {0, 0, 0, 0};\n    vector<vector<int>> comp_id(N, vector<int>(N, -1));\n    vector<int> comp_size;\n    vector<int> comp_edges;\n    int comp_counter = 0;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    s.total_tiles = N * N - 1;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            comp_id[i][j] = comp_counter;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                size++;\n                \n                for (int d = 0; d < 4; d++) {\n                    int nx = x + di[d];\n                    int ny = y + dj[d];\n                    if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                    if (board[nx][ny] == 0 || visited[nx][ny]) continue;\n                    \n                    bool connected = false;\n                    if (d == 0 && (board[x][y] & 2) && (board[nx][ny] & 8)) connected = true;\n                    else if (d == 1 && (board[x][y] & 8) && (board[nx][ny] & 2)) connected = true;\n                    else if (d == 2 && (board[x][y] & 1) && (board[nx][ny] & 4)) connected = true;\n                    else if (d == 3 && (board[x][y] & 4) && (board[nx][ny] & 1)) connected = true;\n                    \n                    if (connected) {\n                        visited[nx][ny] = true;\n                        comp_id[nx][ny] = comp_counter;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            comp_size.push_back(size);\n            comp_counter++;\n        }\n    }\n    \n    comp_edges.assign(comp_counter, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            int cid = comp_id[i][j];\n            if (j + 1 < N && comp_id[i][j + 1] == cid) {\n                if ((board[i][j] & 4) && (board[i][j + 1] & 1)) comp_edges[cid]++;\n            }\n            if (i + 1 < N && comp_id[i + 1][j] == cid) {\n                if ((board[i][j] & 8) && (board[i + 1][j] & 2)) comp_edges[cid]++;\n            }\n        }\n    }\n    \n    s.num_components = 0;\n    for (int cid = 0; cid < comp_counter; cid++) {\n        if (comp_size[cid] == 0) continue;\n        s.num_components++;\n        if (comp_edges[cid] == comp_size[cid] - 1) {\n            s.total_in_trees += comp_size[cid];\n            if (comp_size[cid] > s.largest_tree) {\n                s.largest_tree = comp_size[cid];\n            }\n        }\n    }\n    return s;\n}\n\nint get_score(const Stats& s) {\n    int target = N * N - 1;\n    if (s.largest_tree == target) return 2000000000;\n    int fragmentation = s.num_components - (s.total_in_trees > 0 ? 1 : 0);\n    int score = s.largest_tree * 300000 + s.total_in_trees * 3000 - fragmentation * 2000;\n    if (s.largest_tree >= target * 0.9) score += 50000;\n    if (s.largest_tree >= target * 0.8) score += 20000;\n    return score;\n}\n\nint evaluate_move(int move, int ei, int ej) {\n    int ni = ei + di[move];\n    int nj = ej + dj[move];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return -1;\n    swap(board[ei][ej], board[ni][nj]);\n    auto s = compute_stats();\n    swap(board[ei][ej], board[ni][nj]);\n    return get_score(s);\n}\n\nunsigned long long hash_board() {\n    unsigned long long h = empty_i * 1000003 + empty_j;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            h = h * 131 + board[i][j];\n        }\n    }\n    return h;\n}\n\nint main() {\n    cin >> N >> T;\n    board.assign(N, vector<int>(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            char c = s[j];\n            if (c >= '0' && c <= '9') board[i][j] = c - '0';\n            else board[i][j] = 10 + c - 'a';\n            if (board[i][j] == 0) {\n                empty_i = i;\n                empty_j = j;\n            }\n        }\n    }\n    \n    auto initial = compute_stats();\n    if (initial.largest_tree == N * N - 1) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    string result = \"\";\n    int target = N * N - 1;\n    auto start_time = high_resolution_clock::now();\n    unordered_set<unsigned long long> visited_states;\n    \n    for (int move_count = 0; move_count < T; move_count++) {\n        auto now = high_resolution_clock::now();\n        if (duration_cast<milliseconds>(now - start_time).count() > 2800) break;\n        \n        auto current = compute_stats();\n        if (current.largest_tree == target) break;\n        \n        unsigned long long state_hash = hash_board();\n        if (visited_states.find(state_hash) != visited_states.end()) {\n            vector<int> valid;\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (!result.empty() && result.back() == dir_char[opp[d]]) continue;\n                    valid.push_back(d);\n                }\n            }\n            if (!valid.empty()) {\n                int d = valid[rng() % valid.size()];\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                swap(board[empty_i][empty_j], board[ni][nj]);\n                empty_i = ni;\n                empty_j = nj;\n                result += dir_char[d];\n                continue;\n            }\n        }\n        \n        visited_states.insert(state_hash);\n        if (visited_states.size() > 10000) visited_states.clear();\n        \n        int best_move = -1;\n        int best_score = -1;\n        bool found_full = false;\n        \n        // 2-step lookahead\n        for (int d1 = 0; d1 < 4; d1++) {\n            int ni1 = empty_i + di[d1];\n            int nj1 = empty_j + dj[d1];\n            if (ni1 < 0 || ni1 >= N || nj1 < 0 || nj1 >= N) continue;\n            if (!result.empty() && result.back() == dir_char[opp[d1]]) continue;\n            \n            swap(board[empty_i][empty_j], board[ni1][nj1]);\n            \n            for (int d2 = 0; d2 < 4; d2++) {\n                if (d2 == d1) continue;\n                int ni2 = ni1 + di[d2];\n                int nj2 = nj1 + dj[d2];\n                if (ni2 < 0 || ni2 >= N || nj2 < 0 || nj2 >= N) continue;\n                \n                swap(board[ni1][nj1], board[ni2][nj2]);\n                auto s2 = compute_stats();\n                swap(board[ni1][nj1], board[ni2][nj2]);\n                \n                int score = get_score(s2);\n                if (s2.largest_tree == target) {\n                    best_move = d1;\n                    found_full = true;\n                    break;\n                }\n                if (score > best_score) {\n                    best_score = score;\n                    best_move = d1;\n                }\n            }\n            \n            swap(board[empty_i][empty_j], board[ni1][nj1]);\n            if (found_full) break;\n        }\n        \n        // 3-step lookahead for early moves\n        if (!found_full && move_count < 10 && duration_cast<milliseconds>(now - start_time).count() < 2000) {\n            for (int d1 = 0; d1 < 4; d1++) {\n                int ni1 = empty_i + di[d1];\n                int nj1 = empty_j + dj[d1];\n                if (ni1 < 0 || ni1 >= N || nj1 < 0 || nj1 >= N) continue;\n                if (!result.empty() && result.back() == dir_char[opp[d1]]) continue;\n                \n                swap(board[empty_i][empty_j], board[ni1][nj1]);\n                \n                for (int d2 = 0; d2 < 4; d2++) {\n                    if (d2 == d1) continue;\n                    int ni2 = ni1 + di[d2];\n                    int nj2 = nj1 + dj[d2];\n                    if (ni2 < 0 || ni2 >= N || nj2 < 0 || nj2 >= N) continue;\n                    \n                    swap(board[ni1][nj1], board[ni2][nj2]);\n                    \n                    for (int d3 = 0; d3 < 4; d3++) {\n                        if (d3 == d2) continue;\n                        int ni3 = ni2 + di[d3];\n                        int nj3 = nj2 + dj[d3];\n                        if (ni3 < 0 || ni3 >= N || nj3 < 0 || nj3 >= N) continue;\n                        \n                        swap(board[ni2][nj2], board[ni3][nj3]);\n                        auto s3 = compute_stats();\n                        swap(board[ni2][nj2], board[ni3][nj3]);\n                        \n                        int score = get_score(s3);\n                        if (s3.largest_tree == target) {\n                            best_move = d1;\n                            found_full = true;\n                            break;\n                        }\n                        if (score > best_score) {\n                            best_score = score;\n                            best_move = d1;\n                        }\n                    }\n                    \n                    swap(board[ni1][nj1], board[ni2][nj2]);\n                    if (found_full) break;\n                }\n                \n                swap(board[empty_i][empty_j], board[ni1][nj1]);\n                if (found_full) break;\n            }\n        }\n        \n        // Fallback to 1-step\n        if (best_move == -1) {\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (!result.empty() && result.back() == dir_char[opp[d]]) continue;\n                \n                int score = evaluate_move(d, empty_i, empty_j);\n                if (score > best_score) {\n                    best_score = score;\n                    best_move = d;\n                }\n            }\n        }\n        \n        // Random escape\n        if (best_score <= get_score(current) && move_count > T / 4) {\n            vector<int> valid;\n            for (int d = 0; d < 4; d++) {\n                int ni = empty_i + di[d];\n                int nj = empty_j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (!result.empty() && result.back() == dir_char[opp[d]]) continue;\n                    valid.push_back(d);\n                }\n            }\n            if (!valid.empty()) {\n                best_move = valid[rng() % valid.size()];\n            }\n        }\n        \n        if (best_move == -1) break;\n        \n        int ni = empty_i + di[best_move];\n        int nj = empty_j + dj[best_move];\n        swap(board[empty_i][empty_j], board[ni][nj]);\n        empty_i = ni;\n        empty_j = nj;\n        result += dir_char[best_move];\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Point {\n    ll x, y;\n};\n\nstruct Line {\n    Point p1, p2;\n};\n\nint main() {\n    srand(time(0));\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    vector<Point> strawberries(N);\n    set<int> forbidden_x, forbidden_y;\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        forbidden_x.insert(strawberries[i].x);\n        forbidden_y.insert(strawberries[i].y);\n    }\n\n    set<int> used_vertical, used_horizontal;\n    vector<Line> lines;\n\n    for (int i = 0; i < K; i++) {\n        int type = rand() % 2;\n        if (type == 0) { // vertical\n            if (used_vertical.size() >= 20001 - forbidden_x.size()) {\n                type = 1;\n            }\n        } else {\n            if (used_horizontal.size() >= 20001 - forbidden_y.size()) {\n                type = 0;\n            }\n        }\n\n        if (type == 0) {\n            int C;\n            int attempts = 0;\n            while (attempts < 1000) {\n                C = rand() % 20001 - 10000;\n                if (forbidden_x.find(C) == forbidden_x.end() && used_vertical.find(C) == used_vertical.end()) {\n                    break;\n                }\n                attempts++;\n            }\n            if (attempts == 1000) {\n                type = 1;\n            } else {\n                used_vertical.insert(C);\n                lines.push_back({{C, 0}, {C, 1}});\n                continue;\n            }\n        }\n\n        if (type == 1) {\n            int C;\n            int attempts = 0;\n            while (attempts < 1000) {\n                C = rand() % 20001 - 10000;\n                if (forbidden_y.find(C) == forbidden_y.end() && used_horizontal.find(C) == used_horizontal.end()) {\n                    break;\n                }\n                attempts++;\n            }\n            if (attempts == 1000) {\n                break;\n            }\n            used_horizontal.insert(C);\n            lines.push_back({{0, C}, {1, C}});\n        }\n    }\n\n    cout << lines.size() << endl;\n    for (const Line& line : lines) {\n        cout << line.p1.x << \" \" << line.p1.y << \" \" << line.p2.x << \" \" << line.p2.y << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <unordered_set>\n#include <queue>\n#include <random>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nusing Point = pair<int, int>;\nusing Segment = pair<Point, Point>;\n\nstruct Candidate {\n    Point new_dot;\n    vector<Point> existing;\n    int type;\n    int weight;\n    int gap_size;\n    \n    bool operator<(const Candidate& other) const {\n        if (weight != other.weight) return weight < other.weight;\n        return gap_size < other.gap_size;\n    }\n};\n\nSegment make_segment(Point a, Point b) {\n    if (a < b) return {a, b};\n    return {b, a};\n}\n\nint main() {\n    auto start = high_resolution_clock::now();\n    int N, M;\n    cin >> N >> M;\n    vector<Point> initial_dots;\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> row_set(N);\n    vector<set<int>> col_set(N);\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        initial_dots.push_back({x, y});\n        grid[x][y] = true;\n        row_set[y].insert(x);\n        col_set[x].insert(y);\n    }\n\n    int c = (N-1)/2;\n    auto weight_func = [c](int x, int y) {\n        int dx = x - c;\n        int dy = y - c;\n        return dx*dx + dy*dy + 1;\n    };\n\n    set<Segment> drawn_segments;\n    vector<vector<int>> operations;\n\n    const double TIME_LIMIT = 4.98;\n    int K_top = 2000;\n    int consecutive_failures = 0;\n\n    for (int iter = 0; iter < 1000000; iter++) {\n        auto now = high_resolution_clock::now();\n        auto elapsed = duration_cast<milliseconds>(now - start).count() / 1000.0;\n        if (elapsed > TIME_LIMIT) break;\n        if (consecutive_failures > 300) break;\n\n        priority_queue<Candidate> candidates;\n        unordered_set<long long> added_new_dot;\n\n        // Axis-aligned rectangles - consider gaps up to 120\n        for (int y = 0; y < N; y++) {\n            if (row_set[y].size() < 2) continue;\n            vector<int> xs(row_set[y].begin(), row_set[y].end());\n            sort(xs.begin(), xs.end());\n            for (int i = 0; i < xs.size(); i++) {\n                for (int j = i+1; j < xs.size(); j++) {\n                    int x1 = xs[i], x2 = xs[j];\n                    int gap = x2 - x1;\n                    if (gap > 120) break;\n                    for (int y1 : col_set[x1]) {\n                        if (y1 == y) continue;\n                        if (x2 < N && !grid[x2][y1]) {\n                            long long key = (long long)x2 * 1000 + y1;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x2, y1);\n                                candidates.push({{x2,y1}, {{x1,y}, {x2,y}, {x1,y1}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                                if (candidates.size() > K_top) candidates.pop();\n                            }\n                        }\n                    }\n                    for (int y1 : col_set[x2]) {\n                        if (y1 == y) continue;\n                        if (x1 >= 0 && !grid[x1][y1]) {\n                            long long key = (long long)x1 * 1000 + y1;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x1, y1);\n                                candidates.push({{x1,y1}, {{x1,y}, {x2,y}, {x2,y1}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                                if (candidates.size() > K_top) candidates.pop();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        for (int x = 0; x < N; x++) {\n            if (col_set[x].size() < 2) continue;\n            vector<int> ys(col_set[x].begin(), col_set[x].end());\n            sort(ys.begin(), ys.end());\n            for (int i = 0; i < ys.size(); i++) {\n                for (int j = i+1; j < ys.size(); j++) {\n                    int y1 = ys[i], y2 = ys[j];\n                    int gap = y2 - y1;\n                    if (gap > 120) break;\n                    for (int x1 : row_set[y1]) {\n                        if (x1 == x) continue;\n                        if (y2 < N && !grid[x1][y2]) {\n                            long long key = (long long)x1 * 1000 + y2;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x1, y2);\n                                candidates.push({{x1,y2}, {{x,y1}, {x,y2}, {x1,y1}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                                if (candidates.size() > K_top) candidates.pop();\n                            }\n                        }\n                    }\n                    for (int x1 : row_set[y2]) {\n                        if (x1 == x) continue;\n                        if (y1 >= 0 && !grid[x1][y1]) {\n                            long long key = (long long)x1 * 1000 + y1;\n                            if (added_new_dot.find(key) == added_new_dot.end()) {\n                                int w = weight_func(x1, y1);\n                                candidates.push({{x1,y1}, {{x,y1}, {x,y2}, {x1,y2}}, 0, w, gap});\n                                added_new_dot.insert(key);\n                                if (candidates.size() > K_top) candidates.pop();\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // 45-degree squares - consider a=1 to 25\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y]) continue;\n                long long key = (long long)x * 1000 + y;\n                if (added_new_dot.find(key) != added_new_dot.end()) continue;\n                int w = weight_func(x, y);\n                for (int a = 1; a <= 25; a++) {\n                    bool found = false;\n                    // Orientation 0\n                    if (x+a < N && x-a >= 0 && y-2*a >= 0 && y-a >= 0) {\n                        if (grid[x+a][y-a] && grid[x][y-2*a] && grid[x-a][y-a]) {\n                            candidates.push({{x,y}, {{x+a,y-a}, {x,y-2*a}, {x-a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                    // Orientation 1\n                    if (!found && x+2*a < N && x+a >= 0 && y+a < N && y-a >= 0) {\n                        if (grid[x+a][y+a] && grid[x+2*a][y] && grid[x+a][y-a]) {\n                            candidates.push({{x,y}, {{x+a,y+a}, {x+2*a,y}, {x+a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                    // Orientation 2\n                    if (!found && x-a >= 0 && x+a < N && y-2*a >= 0 && y-a >= 0) {\n                        if (grid[x-a][y-a] && grid[x][y-2*a] && grid[x+a][y-a]) {\n                            candidates.push({{x,y}, {{x-a,y-a}, {x,y-2*a}, {x+a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                    // Orientation 3\n                    if (!found && x-2*a >= 0 && x-a >= 0 && y+a < N && y-a >= 0) {\n                        if (grid[x-a][y+a] && grid[x-2*a][y] && grid[x-a][y-a]) {\n                            candidates.push({{x,y}, {{x-a,y+a}, {x-2*a,y}, {x-a,y-a}}, 1, w, a});\n                            added_new_dot.insert(key);\n                            found = true;\n                        }\n                    }\n                    if (found) break;\n                }\n            }\n        }\n\n        if (candidates.empty()) {\n            consecutive_failures++;\n            continue;\n        }\n\n        // Extract top candidates from priority queue\n        vector<Candidate> top_candidates;\n        while (!candidates.empty()) {\n            top_candidates.push_back(candidates.top());\n            candidates.pop();\n        }\n        reverse(top_candidates.begin(), top_candidates.end());\n        \n        // Shuffle to avoid deterministic behavior\n        random_device rd;\n        mt19937 g(rd());\n        shuffle(top_candidates.begin(), top_candidates.end(), g);\n\n        bool found_valid = false;\n        for (const Candidate& cand : top_candidates) {\n            Point new_dot = cand.new_dot;\n            vector<Point> existing = cand.existing;\n            int type = cand.type;\n\n            set<Point> corners = {new_dot, existing[0], existing[1], existing[2]};\n\n            // Quick validation: check if existing dots are valid\n            bool all_exist = true;\n            for (const Point& p : existing) {\n                if (!grid[p.first][p.second]) {\n                    all_exist = false;\n                    break;\n                }\n            }\n            if (!all_exist) continue;\n\n            // Condition 2: Check perimeter for other dots\n            bool condition2_ok = true;\n            \n            if (type == 0) {\n                int x_min = min({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int x_max = max({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int y_min = min({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                int y_max = max({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                \n                // Check top and bottom edges using row_set\n                if (!row_set[y_min].empty()) {\n                    auto it = row_set[y_min].lower_bound(x_min+1);\n                    if (it != row_set[y_min].end() && *it < x_max) {\n                        condition2_ok = false;\n                    }\n                }\n                if (condition2_ok && !row_set[y_max].empty()) {\n                    auto it = row_set[y_max].lower_bound(x_min+1);\n                    if (it != row_set[y_max].end() && *it < x_max) {\n                        condition2_ok = false;\n                    }\n                }\n                // Check left and right edges using col_set\n                if (condition2_ok && !col_set[x_min].empty()) {\n                    auto it = col_set[x_min].lower_bound(y_min+1);\n                    if (it != col_set[x_min].end() && *it < y_max) {\n                        condition2_ok = false;\n                    }\n                }\n                if (condition2_ok && !col_set[x_max].empty()) {\n                    auto it = col_set[x_max].lower_bound(y_min+1);\n                    if (it != col_set[x_max].end() && *it < y_max) {\n                        condition2_ok = false;\n                    }\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                \n                for (int i = 0; i < 4 && condition2_ok; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = max(abs(dx), abs(dy));\n                    if (steps == 0) continue;\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k <= steps; k++) {\n                        if (corners.find(current) == corners.end() && grid[current.first][current.second]) {\n                            condition2_ok = false;\n                            break;\n                        }\n                        current.first += sx;\n                        current.second += sy;\n                    }\n                }\n            }\n\n            if (!condition2_ok) continue;\n\n            // Condition 3: Check segment overlap\n            bool condition3_ok = true;\n            vector<Segment> new_segments;\n\n            if (type == 0) {\n                int x_min = min({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int x_max = max({new_dot.first, existing[0].first, existing[1].first, existing[2].first});\n                int y_min = min({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                int y_max = max({new_dot.second, existing[0].second, existing[1].second, existing[2].second});\n                \n                for (int x = x_min; x < x_max && condition3_ok; x++) {\n                    Segment seg1 = make_segment({x, y_min}, {x+1, y_min});\n                    if (drawn_segments.find(seg1) != drawn_segments.end()) {\n                        condition3_ok = false;\n                        break;\n                    }\n                    new_segments.push_back(seg1);\n                    \n                    Segment seg2 = make_segment({x, y_max}, {x+1, y_max});\n                    if (drawn_segments.find(seg2) != drawn_segments.end()) {\n                        condition3_ok = false;\n                        break;\n                    }\n                    new_segments.push_back(seg2);\n                }\n                if (!condition3_ok) continue;\n                \n                for (int y = y_min; y < y_max && condition3_ok; y++) {\n                    Segment seg1 = make_segment({x_min, y}, {x_min, y+1});\n                    if (drawn_segments.find(seg1) != drawn_segments.end()) {\n                        condition3_ok = false;\n                        break;\n                    }\n                    new_segments.push_back(seg1);\n                    \n                    Segment seg2 = make_segment({x_max, y}, {x_max, y+1});\n                    if (drawn_segments.find(seg2) != drawn_segments.end()) {\n                        condition3_ok = false;\n                        break;\n                    }\n                    new_segments.push_back(seg2);\n                }\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                for (int i = 0; i < 4 && condition3_ok; i++) {\n                    Point a = corners_vec[i];\n                    Point b = corners_vec[(i+1)%4];\n                    int dx = b.first - a.first;\n                    int dy = b.second - a.second;\n                    int steps = max(abs(dx), abs(dy));\n                    if (steps == 0) continue;\n                    int sx = dx / steps;\n                    int sy = dy / steps;\n                    Point current = a;\n                    for (int k = 0; k < steps; k++) {\n                        Point next = {current.first + sx, current.second + sy};\n                        Segment seg = make_segment(current, next);\n                        if (drawn_segments.find(seg) != drawn_segments.end()) {\n                            condition3_ok = false;\n                            break;\n                        }\n                        new_segments.push_back(seg);\n                        current = next;\n                    }\n                    if (!condition3_ok) break;\n                }\n            }\n\n            if (!condition3_ok) continue;\n\n            // Valid move found\n            for (const Segment& seg : new_segments) {\n                drawn_segments.insert(seg);\n            }\n            grid[new_dot.first][new_dot.second] = true;\n            row_set[new_dot.second].insert(new_dot.first);\n            col_set[new_dot.first].insert(new_dot.second);\n\n            vector<int> op;\n            if (type == 0) {\n                Point same_x, same_y, opposite;\n                for (const Point& p : existing) {\n                    if (p.first == new_dot.first) same_x = p;\n                    else if (p.second == new_dot.second) same_y = p;\n                    else opposite = p;\n                }\n                op = {new_dot.first, new_dot.second, same_y.first, same_y.second, \n                      opposite.first, opposite.second, same_x.first, same_x.second};\n            } else {\n                vector<Point> corners_vec = {new_dot, existing[0], existing[1], existing[2]};\n                double cx = 0, cy = 0;\n                for (const Point& p : corners_vec) {\n                    cx += p.first;\n                    cy += p.second;\n                }\n                cx /= 4.0;\n                cy /= 4.0;\n                sort(corners_vec.begin(), corners_vec.end(), [cx, cy](const Point& a, const Point& b) {\n                    double angleA = atan2(a.second - cy, a.first - cx);\n                    double angleB = atan2(b.second - cy, b.first - cx);\n                    return angleA < angleB;\n                });\n                int idx = 0;\n                while (corners_vec[idx] != new_dot) idx++;\n                for (int i = 0; i < 4; i++) {\n                    Point p = corners_vec[(idx+i)%4];\n                    op.push_back(p.first);\n                    op.push_back(p.second);\n                }\n            }\n            operations.push_back(op);\n\n            found_valid = true;\n            consecutive_failures = 0;\n            break;\n        }\n\n        if (!found_valid) {\n            consecutive_failures++;\n        }\n    }\n\n    cout << operations.size() << endl;\n    for (const vector<int>& op : operations) {\n        for (int i = 0; i < op.size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nvector<vector<int>> tilt_grid(const vector<vector<int>>& grid, char dir) {\n    vector<vector<int>> new_grid(10, vector<int>(10, 0));\n    if (dir == 'F') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 9; i >= 0; i--) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 9;\n            for (int candy : candies) {\n                new_grid[idx--][j] = candy;\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; j++) {\n            vector<int> candies;\n            for (int i = 0; i < 10; i++) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 0;\n            for (int candy : candies) {\n                new_grid[idx++][j] = candy;\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 0;\n            for (int candy : candies) {\n                new_grid[i][idx++] = candy;\n            }\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; i++) {\n            vector<int> candies;\n            for (int j = 9; j >= 0; j--) {\n                if (grid[i][j] != 0) candies.push_back(grid[i][j]);\n            }\n            int idx = 9;\n            for (int candy : candies) {\n                new_grid[i][idx--] = candy;\n            }\n        }\n    }\n    return new_grid;\n}\n\nint compute_components(const vector<vector<int>>& grid) {\n    vector<vector<bool>> visited(10, vector<bool>(10, false));\n    int total_score = 0;\n    int dx[4] = {1, -1, 0, 0};\n    int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < 10; i++) {\n        for (int j = 0; j < 10; j++) {\n            if (grid[i][j] != 0 && !visited[i][j]) {\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int flavor = grid[i][j];\n                int size = 0;\n\n                while (!q.empty()) {\n                    auto [x, y] = q.front();\n                    q.pop();\n                    size++;\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x + dx[d];\n                        int ny = y + dy[d];\n                        if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && \n                            !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                total_score += size * size;\n            }\n        }\n    }\n    return total_score;\n}\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n\n    vector<vector<int>> grid(10, vector<int>(10, 0));\n\n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell\n        int count = 0;\n        int i0 = -1, j0 = -1;\n        for (int i = 0; i < 10; i++) {\n            for (int j = 0; j < 10; j++) {\n                if (grid[i][j] == 0) {\n                    count++;\n                    if (count == p) {\n                        i0 = i;\n                        j0 = j;\n                        break;\n                    }\n                }\n            }\n            if (i0 != -1) break;\n        }\n\n        // Place the candy\n        grid[i0][j0] = flavors[t];\n\n        // If it's the last candy, we don't need to tilt\n        if (t == 99) {\n            break;\n        }\n\n        // Try all directions and choose the best\n        char best_dir = 'F';\n        int best_score = -1;\n        string dirs = \"FBLR\";\n        \n        for (char d : dirs) {\n            vector<vector<int>> temp_grid = grid;\n            vector<vector<int>> tilted = tilt_grid(temp_grid, d);\n            \n            int base_score = compute_components(tilted);\n            int zone_bonus = 0;\n            int connection_bonus = 0;\n            int current_bonus = 0;\n            int penalty = 0;\n            \n            // Zone bonus and connection bonus\n            for (int i = 0; i < 10; i++) {\n                for (int j = 0; j < 10; j++) {\n                    if (tilted[i][j] != 0) {\n                        int flavor = tilted[i][j];\n                        // Zone bonus\n                        bool in_zone = false;\n                        if (flavor == 1 && i < 5 && j < 5) in_zone = true;\n                        if (flavor == 2 && i < 5 && j >= 5) in_zone = true;\n                        if (flavor == 3 && i >= 5) in_zone = true;\n                        if (in_zone) zone_bonus += 10;\n                        \n                        // Connection bonus (right and down)\n                        if (i < 9 && tilted[i+1][j] == flavor) connection_bonus += 5;\n                        if (j < 9 && tilted[i][j+1] == flavor) connection_bonus += 5;\n                    }\n                }\n            }\n            \n            // Current flavor bonus\n            int current_flavor = flavors[t];\n            int count_current = 0;\n            for (int i = 0; i < 10; i++) {\n                for (int j = 0; j < 10; j++) {\n                    if (tilted[i][j] == current_flavor) count_current++;\n                }\n            }\n            if (count_current >= 2) {\n                current_bonus = count_current * 5;\n            }\n            \n            // Isolation penalty (slightly reduced for stability)\n            vector<vector<bool>> visited(10, vector<bool>(10, false));\n            for (int i = 0; i < 10; i++) {\n                for (int j = 0; j < 10; j++) {\n                    if (tilted[i][j] != 0 && !visited[i][j]) {\n                        queue<pair<int, int>> q;\n                        q.push({i, j});\n                        visited[i][j] = true;\n                        int flavor = tilted[i][j];\n                        int size = 0;\n                        \n                        while (!q.empty()) {\n                            auto [x, y] = q.front();\n                            q.pop();\n                            size++;\n                            int dx[4] = {1, -1, 0, 0};\n                            int dy[4] = {0, 0, 1, -1};\n                            for (int dir = 0; dir < 4; dir++) {\n                                int nx = x + dx[dir];\n                                int ny = y + dy[dir];\n                                if (nx >= 0 && nx < 10 && ny >= 0 && ny < 10 && \n                                    !visited[nx][ny] && tilted[nx][ny] == flavor) {\n                                    visited[nx][ny] = true;\n                                    q.push({nx, ny});\n                                }\n                            }\n                        }\n                        if (size == 1) {\n                            penalty += 8; // Reduced from 10 for better stability\n                        }\n                    }\n                }\n            }\n            \n            int score = base_score * 100 + zone_bonus + connection_bonus + current_bonus - penalty;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n\n        cout << best_dir << endl;\n\n        // Apply the best tilt to our grid state\n        grid = tilt_grid(grid, best_dir);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\nusing namespace std;\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n\n    // More refined N selection based on M and epsilon\n    int N;\n    if (M <= 15 && epsilon <= 0.05) {\n        N = 20;\n    } else if (M <= 25 && epsilon <= 0.1) {\n        N = 30;\n    } else if (M <= 40 && epsilon <= 0.15) {\n        N = 50;\n    } else if (M <= 60 && epsilon <= 0.25) {\n        N = 70;\n    } else {\n        N = 100;\n    }\n\n    const int T = N * (N - 1) / 2;\n    int g = T / (M - 1);\n    if (g < 1) g = 1;\n\n    // Precompute prototype degree sequences with optimized edge assignment\n    vector<vector<int>> proto_degrees(M, vector<int>(N, 0));\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        \n        // More balanced edge assignment to maximize degree sequence distinctiveness\n        vector<int> deg(N, 0);\n        if (edge_count > 0) {\n            // Distribute edges to create distinct degree profiles\n            int remaining = edge_count;\n            int current_vertex = 0;\n            while (remaining > 0) {\n                for (int j = current_vertex + 1; j < N && remaining > 0; j++) {\n                    if (deg[current_vertex] < N - 1) {\n                        deg[current_vertex]++;\n                        deg[j]++;\n                        remaining--;\n                    }\n                }\n                current_vertex = (current_vertex + 1) % N;\n            }\n        }\n        sort(deg.begin(), deg.end());\n        proto_degrees[k] = deg;\n    }\n\n    // Precompute expected degree sequences after noise\n    vector<vector<double>> proto_expected(M, vector<double>(N, 0));\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < N; i++) {\n            proto_expected[k][i] = proto_degrees[k][i] * (1 - 2 * epsilon) + (N - 1) * epsilon;\n        }\n    }\n\n    // Output graphs\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        int edge_count = k * g;\n        if (edge_count > T) edge_count = T;\n        string s = \"\";\n        int count = 0;\n        // Use the same edge assignment as in degree sequence calculation\n        vector<int> deg(N, 0);\n        if (edge_count > 0) {\n            int remaining = edge_count;\n            int current_vertex = 0;\n            while (remaining > 0) {\n                for (int j = current_vertex + 1; j < N && remaining > 0; j++) {\n                    if (deg[current_vertex] < N - 1) {\n                        deg[current_vertex]++;\n                        deg[j]++;\n                        remaining--;\n                    }\n                }\n                current_vertex = (current_vertex + 1) % N;\n            }\n        }\n        // Convert degree assignment to edge string\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                // Check if this edge was assigned in our degree calculation\n                bool edge_exists = false;\n                if (deg[i] > 0 && deg[j] > 0) {\n                    // We need to reconstruct the edge existence from degrees\n                    // This is a simplification - in practice, we should store the edge matrix\n                    // For now, we'll use a heuristic: if both degrees are positive, assume edge exists\n                    // But this might not be accurate\n                    // Instead, let's generate edges in the same order as degree calculation\n                    // We'll recreate the edge assignment\n                    edge_exists = (i < j && deg[i] > 0 && deg[j] > 0);\n                }\n                s += edge_exists ? '1' : '0';\n                count++;\n            }\n        }\n        // Actually, let's generate edges properly based on our degree assignment\n        // We need to reconstruct the edge string from the degree assignment\n        // Since we know the degree sequence, we can try to reconstruct a graph with that degree sequence\n        // But that's complex. Instead, let's use a simpler method: assign edges in canonical order up to edge_count\n        s = \"\";\n        int assigned = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (assigned < edge_count) {\n                    s += '1';\n                    assigned++;\n                } else {\n                    s += '0';\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    // Process queries\n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        vector<int> obs_deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (s[idx] == '1') {\n                    obs_deg[i]++;\n                    obs_deg[j]++;\n                }\n                idx++;\n            }\n        }\n        sort(obs_deg.begin(), obs_deg.end());\n\n        // Use degree sequence method with noise-adjusted expected values\n        double best_dist = 1e18;\n        int best_k = 0;\n        for (int k = 0; k < M; k++) {\n            double dist = 0.0;\n            for (int i = 0; i < N; i++) {\n                double diff = obs_deg[i] - proto_expected[k][i];\n                dist += diff * diff;\n            }\n            // Add small regularization to break ties\n            dist += 1e-6 * k;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_k = k;\n            }\n        }\n        cout << best_k << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long LL;\ntypedef long double LD;\n\nstruct Edge {\n    int to;\n    LL w;\n    int id;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<vector<Edge>> adj(N);\n    vector<LL> edge_weight(M);\n    vector<pair<int, int>> edge_endpoints(M);\n    \n    for (int i = 0; i < M; i++) {\n        int u, v;\n        LL w;\n        cin >> u >> v >> w;\n        u--; v--;\n        edge_weight[i] = w;\n        edge_endpoints[i] = {u, v};\n        adj[u].push_back({v, w, i});\n        adj[v].push_back({u, w, i});\n    }\n\n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Compute edge betweenness with optimal sampling\n    vector<LD> betweenness(M, 0.0);\n    \n    // Adaptive sampling based on graph size\n    int sample_size = min(N, 80);\n    vector<int> sample_vertices;\n    if (N <= 80) {\n        sample_vertices.resize(N);\n        iota(sample_vertices.begin(), sample_vertices.end(), 0);\n    } else {\n        // Deterministic, spaced sampling with better distribution\n        for (int i = 0; i < sample_size; i++) {\n            sample_vertices.push_back((i * N) / sample_size);\n        }\n    }\n\n    // Process each sampled vertex\n    for (int s : sample_vertices) {\n        vector<LL> dist(N, LLONG_MAX);\n        vector<LL> sigma(N, 0);\n        vector<vector<pair<int, int>>> pred(N);\n        \n        // Dijkstra with optimization\n        priority_queue<pair<LL, int>, vector<pair<LL, int>>, greater<>> pq;\n        dist[s] = 0;\n        sigma[s] = 1;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            for (const auto& e : adj[u]) {\n                LL nd = dist[u] + e.w;\n                if (nd < dist[e.to]) {\n                    dist[e.to] = nd;\n                    sigma[e.to] = sigma[u];\n                    pred[e.to].clear();\n                    pred[e.to].push_back({u, e.id});\n                    pq.push({nd, e.to});\n                } else if (nd == dist[e.to]) {\n                    sigma[e.to] += sigma[u];\n                    pred[e.to].push_back({u, e.id});\n                }\n            }\n        }\n        \n        // Back-propagation for edge betweenness\n        vector<LD> delta(N, 0.0);\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return dist[a] > dist[b];\n        });\n        \n        for (int v : order) {\n            if (dist[v] == LLONG_MAX || v == s) continue;\n            for (auto [u, eid] : pred[v]) {\n                if (sigma[v] == 0) continue;\n                LD contrib = (LD)sigma[u] / sigma[v] * (1.0 + delta[v]);\n                delta[u] += contrib;\n                betweenness[eid] += contrib;\n            }\n        }\n    }\n\n    // Enhanced edge importance calculation\n    vector<pair<LD, int>> edges;\n    for (int i = 0; i < M; i++) {\n        LD importance = betweenness[i] * (LD)edge_weight[i];\n        \n        // Additional factor: edge length relative to average in local neighborhood\n        auto [u, v] = edge_endpoints[i];\n        LD local_avg = 0;\n        int count = 0;\n        for (const auto& e : adj[u]) {\n            local_avg += e.w;\n            count++;\n        }\n        for (const auto& e : adj[v]) {\n            local_avg += e.w;\n            count++;\n        }\n        if (count > 0) {\n            local_avg /= count;\n            LD length_ratio = (LD)edge_weight[i] / max(local_avg, (LD)1);\n            // Slightly boost importance for edges longer than local average\n            importance *= (1.0 + 0.2 * (length_ratio - 1.0));\n        }\n        \n        edges.push_back({importance, i});\n    }\n    \n    // Sort by importance descending\n    sort(edges.rbegin(), edges.rend());\n\n    // Assignment strategy: minimize maximum daily cost with lookahead\n    vector<LD> day_cost(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<int> ans(M, -1);\n    \n    // Phase 1: Greedy assignment with impact prediction\n    for (auto& [cost, eid] : edges) {\n        int best_day = -1;\n        LD min_impact = 1e30;\n        \n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            \n            // Calculate the new maximum cost if we add this edge to day d\n            LD new_max = max(day_cost[d] + cost, \n                            *max_element(day_cost.begin(), day_cost.end()));\n            \n            if (new_max < min_impact) {\n                min_impact = new_max;\n                best_day = d;\n            }\n        }\n        \n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if (day_count[d] < K) {\n                    best_day = d;\n                    break;\n                }\n            }\n            if (best_day == -1) best_day = 0;\n        }\n        \n        ans[eid] = best_day;\n        day_cost[best_day] += cost;\n        day_count[best_day]++;\n    }\n\n    // Phase 2: Aggressive local search focusing on bottleneck days\n    for (int iter = 0; iter < 150; iter++) {\n        // Find current bottleneck day\n        LD max_cost = 0;\n        int max_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_cost[d] > max_cost) {\n                max_cost = day_cost[d];\n                max_day = d;\n            }\n        }\n        if (max_day == -1) break;\n\n        // Compute current second maximum\n        LD second_max = 0;\n        for (int d = 0; d < D; d++) {\n            if (d == max_day) continue;\n            second_max = max(second_max, day_cost[d]);\n        }\n\n        // Find best edge to move\n        int best_edge = -1;\n        int best_target = -1;\n        LD best_improvement = 0;\n\n        // Precompute edges in max_day\n        vector<int> edges_in_day;\n        for (int e = 0; e < M; e++) {\n            if (ans[e] == max_day) {\n                edges_in_day.push_back(e);\n            }\n        }\n\n        for (int e : edges_in_day) {\n            LD e_cost = betweenness[e] * (LD)edge_weight[e];\n            \n            for (int d = 0; d < D; d++) {\n                if (d == max_day || day_count[d] >= K) continue;\n                \n                // Calculate improvement\n                LD new_max_day = max_cost - e_cost;\n                LD new_target = day_cost[d] + e_cost;\n                LD new_max = max({new_max_day, new_target, second_max});\n                LD improvement = max_cost - new_max;\n                \n                if (improvement > best_improvement) {\n                    best_improvement = improvement;\n                    best_edge = e;\n                    best_target = d;\n                }\n            }\n        }\n\n        if (best_improvement <= 1e-9) break;\n\n        // Apply best move\n        LD e_cost = betweenness[best_edge] * (LD)edge_weight[best_edge];\n        day_cost[max_day] -= e_cost;\n        day_cost[best_target] += e_cost;\n        day_count[max_day]--;\n        day_count[best_target]++;\n        ans[best_edge] = best_target;\n    }\n\n    // Phase 3: Final refinement - specifically target the highest frustration days\n    // Find top 2 bottleneck days\n    vector<pair<LD, int>> day_costs;\n    for (int d = 0; d < D; d++) {\n        day_costs.push_back({day_cost[d], d});\n    }\n    sort(day_costs.rbegin(), day_costs.rend());\n    \n    // Try to balance top 2 days\n    if (day_costs.size() >= 2 && day_costs[0].first > day_costs[1].first * 1.1) {\n        int max_day = day_costs[0].second;\n        int target_day = day_costs[1].second;\n        \n        if (day_count[target_day] < K) {\n            // Find edges in max_day that can improve balance\n            for (int e = 0; e < M; e++) {\n                if (ans[e] != max_day) continue;\n                if (day_count[target_day] >= K) break;\n                \n                LD e_cost = betweenness[e] * (LD)edge_weight[e];\n                LD improvement = day_cost[max_day] - day_cost[target_day] - e_cost;\n                \n                if (improvement > 0) {\n                    day_cost[max_day] -= e_cost;\n                    day_cost[target_day] += e_cost;\n                    day_count[max_day]--;\n                    day_count[target_day]++;\n                    ans[e] = target_day;\n                }\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i) cout << \" \";\n        cout << ans[i] + 1;\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    int D;\n    cin >> D;\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> is_common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> is_only2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\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                bool in1 = (f1[z][x] == '1' && r1[z][y] == '1');\n                bool in2 = (f2[z][x] == '1' && r2[z][y] == '1');\n                if (in1 && in2) {\n                    is_common[x][y][z] = true;\n                } else if (in1) {\n                    is_only1[x][y][z] = true;\n                } else if (in2) {\n                    is_only2[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<int>>> block1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> block2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    int next_block_id = 1;\n    vector<int> dx = {1, -1, 0, 0, 0, 0};\n    vector<int> dy = {0, 0, 1, -1, 0, 0};\n    vector<int> dz = {0, 0, 0, 0, 1, -1};\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 (is_common[x][y][z] && !visited[x][y][z]) {\n                    queue<tuple<int, int, int>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = true;\n                    block1[x][y][z] = next_block_id;\n                    block2[x][y][z] = next_block_id;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D) {\n                                if (is_common[nx][ny][nz] && !visited[nx][ny][nz]) {\n                                    visited[nx][ny][nz] = true;\n                                    block1[nx][ny][nz] = next_block_id;\n                                    block2[nx][ny][nz] = next_block_id;\n                                    q.push({nx, ny, nz});\n                                }\n                            }\n                        }\n                    }\n                    next_block_id++;\n                }\n            }\n        }\n    }\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 (is_only1[x][y][z]) {\n                    block1[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n                if (is_only2[x][y][z]) {\n                    block2[x][y][z] = next_block_id;\n                    next_block_id++;\n                }\n            }\n        }\n    }\n\n    cout << next_block_id - 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 << block1[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 << block2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstring>\n#include <random>\n\nusing namespace std;\n\ntypedef pair<int, int> pii;\n\nconst double INF = 1e18;\nconst int MAXN = 100;\nconst int MAXM = 300;\nconst int MAXK = 5000;\n\nint N, M, K;\ndouble x[MAXN], y[MAXN];\nvector<pii> edges;\nint w[MAXM];\ndouble resident_x[MAXK], resident_y[MAXK];\n\nvector<pair<int, int>> adj[MAXN];\ndouble dist_2d[MAXN][MAXN];\nint parent_2d[MAXN][MAXN];\n\nmap<pii, int> edge_index_map;\n\ndouble euclid(double x1, double y1, double x2, double y2) {\n    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));\n}\n\nvoid dijkstra(int src) {\n    for (int i = 0; i < N; i++) {\n        dist_2d[src][i] = INF;\n        parent_2d[src][i] = -1;\n    }\n    dist_2d[src][src] = 0;\n    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;\n    pq.push({0, src});\n\n    while (!pq.empty()) {\n        double d = pq.top().first;\n        int u = pq.top().second;\n        pq.pop();\n        if (d != dist_2d[src][u]) continue;\n        for (auto &edge : adj[u]) {\n            int v = edge.first;\n            int weight = edge.second;\n            double new_d = d + weight;\n            if (new_d < dist_2d[src][v]) {\n                dist_2d[src][v] = new_d;\n                parent_2d[src][v] = u;\n                pq.push({new_d, v});\n            }\n        }\n    }\n}\n\nvector<int> get_path(int src, int dest) {\n    vector<int> path;\n    if (dist_2d[src][dest] >= INF) return path;\n    int cur = dest;\n    while (cur != src) {\n        path.push_back(cur);\n        cur = parent_2d[src][cur];\n    }\n    path.push_back(src);\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstruct Edge {\n    int u, v;\n    double weight;\n    bool operator<(const Edge& other) const {\n        return weight < other.weight;\n    }\n};\n\nvector<int> parent_kruskal;\n\nint find_set(int v) {\n    if (v == parent_kruskal[v]) return v;\n    return parent_kruskal[v] = find_set(parent_kruskal[v]);\n}\n\nbool union_sets(int a, int b) {\n    a = find_set(a);\n    b = find_set(b);\n    if (a == b) return false;\n    parent_kruskal[b] = a;\n    return true;\n}\n\nvoid build_MST_on_T(const vector<int>& T_list, vector<pii>& MST_edges) {\n    int t_size = T_list.size();\n    map<int, int> comp;\n    for (int i = 0; i < t_size; i++) {\n        comp[T_list[i]] = i;\n    }\n\n    vector<Edge> edges_complete;\n    for (int i = 0; i < t_size; i++) {\n        for (int j = i+1; j < t_size; j++) {\n            int u = T_list[i];\n            int v = T_list[j];\n            double d = dist_2d[u][v];\n            edges_complete.push_back({u, v, d});\n        }\n    }\n\n    sort(edges_complete.begin(), edges_complete.end());\n\n    parent_kruskal.resize(t_size);\n    for (int i = 0; i < t_size; i++) parent_kruskal[i] = i;\n\n    MST_edges.clear();\n    for (const Edge& e : edges_complete) {\n        int u_comp = comp[e.u];\n        int v_comp = comp[e.v];\n        if (union_sets(u_comp, v_comp)) {\n            MST_edges.push_back({e.u, e.v});\n        }\n    }\n}\n\n// Function to check if a set of V_prime with given powers covers all residents\nbool check_coverage(const vector<int>& V_prime, const vector<int>& P) {\n    for (int k = 0; k < K; k++) {\n        bool covered = false;\n        for (int i : V_prime) {\n            if (P[i] == 0) continue;\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d <= P[i] + 1e-9) {\n                covered = true;\n                break;\n            }\n        }\n        if (!covered) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    cin >> N >> M >> K;\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    for (int j = 0; j < M; j++) {\n        int u, v, weight;\n        cin >> u >> v >> weight;\n        u--; v--;\n        edges.push_back({u, v});\n        w[j] = weight;\n        adj[u].push_back({v, weight});\n        adj[v].push_back({u, weight});\n        int a = min(u, v);\n        int b = max(u, v);\n        edge_index_map[{a, b}] = j;\n    }\n    for (int k = 0; k < K; k++) {\n        cin >> resident_x[k] >> resident_y[k];\n    }\n\n    // Precompute all-pairs shortest paths\n    for (int i = 0; i < N; i++) {\n        dijkstra(i);\n    }\n\n    // Find closest node for each resident\n    vector<int> best_node(K);\n    vector<double> min_dist(K);\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best = -1;\n        for (int i = 0; i < N; i++) {\n            double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n            if (d < min_d) {\n                min_d = d;\n                best = i;\n            }\n        }\n        best_node[k] = best;\n        min_dist[k] = min_d;\n    }\n\n    // Node selection with cost-benefit analysis\n    vector<int> T_list;\n    vector<bool> inT(N, false);\n    vector<double> d_T(K);\n    \n    T_list.push_back(0);\n    inT[0] = true;\n\n    for (int k = 0; k < K; k++) {\n        d_T[k] = euclid(resident_x[k], resident_y[k], x[0], y[0]);\n    }\n\n    vector<bool> covered(K, false);\n    for (int k = 0; k < K; k++) {\n        if (d_T[k] <= 5000) covered[k] = true;\n    }\n\n    while (true) {\n        bool all_covered = true;\n        int uncovered_index = -1;\n        double max_dist = -1;\n        for (int k = 0; k < K; k++) {\n            if (!covered[k]) {\n                all_covered = false;\n                if (d_T[k] > max_dist) {\n                    max_dist = d_T[k];\n                    uncovered_index = k;\n                }\n            }\n        }\n        if (all_covered) break;\n\n        int best_i = -1;\n        double best_benefit = -1e18;\n        \n        // Try multiple candidates and pick the best\n        vector<pair<double, int>> candidates;\n        for (int i = 0; i < N; i++) {\n            if (inT[i]) continue;\n            \n            int count_covered = 0;\n            double total_reduction = 0;\n            for (int k = 0; k < K; k++) {\n                if (covered[k]) continue;\n                double d = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n                if (d <= 5000) {\n                    count_covered++;\n                    total_reduction += (d_T[k] * d_T[k] - d * d);\n                }\n            }\n            \n            if (count_covered == 0) continue;\n            \n            double min_edge_cost = INF;\n            for (int existing : T_list) {\n                min_edge_cost = min(min_edge_cost, dist_2d[i][existing]);\n            }\n            \n            // Use a weighted benefit that considers both coverage and cost\n            double benefit = total_reduction - min_edge_cost * 0.5;\n            candidates.push_back({benefit, i});\n        }\n        \n        if (!candidates.empty()) {\n            sort(candidates.begin(), candidates.end(), greater<pair<double, int>>());\n            // Pick the best candidate\n            best_i = candidates[0].second;\n        } else {\n            best_i = best_node[uncovered_index];\n        }\n        \n        if (!inT[best_i]) {\n            T_list.push_back(best_i);\n            inT[best_i] = true;\n            for (int k = 0; k < K; k++) {\n                double d = euclid(resident_x[k], resident_y[k], x[best_i], y[best_i]);\n                if (d < d_T[k]) {\n                    d_T[k] = d;\n                }\n                if (d_T[k] <= 5000) {\n                    covered[k] = true;\n                }\n            }\n        }\n    }\n\n    vector<pii> MST_edges;\n    if (T_list.size() > 1) {\n        build_MST_on_T(T_list, MST_edges);\n    }\n\n    set<int> activated_edges;\n    for (auto &e : MST_edges) {\n        int u = e.first;\n        int v = e.second;\n        vector<int> path = get_path(u, v);\n        for (int idx = 0; idx < (int)path.size()-1; idx++) {\n            int a = path[idx];\n            int b = path[idx+1];\n            int aa = min(a, b);\n            int bb = max(a, b);\n            auto key = make_pair(aa, bb);\n            if (edge_index_map.find(key) != edge_index_map.end()) {\n                int j = edge_index_map[key];\n                activated_edges.insert(j);\n            }\n        }\n    }\n\n    vector<bool> inV_prime(N, false);\n    vector<vector<int>> adj_steiner(N);\n    for (int j : activated_edges) {\n        int u = edges[j].first;\n        int v = edges[j].second;\n        adj_steiner[u].push_back(v);\n        adj_steiner[v].push_back(u);\n    }\n    queue<int> q;\n    q.push(0);\n    inV_prime[0] = true;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj_steiner[u]) {\n            if (!inV_prime[v]) {\n                inV_prime[v] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    vector<int> V_prime;\n    for (int i = 0; i < N; i++) {\n        if (inV_prime[i]) {\n            V_prime.push_back(i);\n        }\n    }\n\n    // Precompute distances from residents to nodes in V_prime\n    vector<vector<double>> dist_res_node(K, vector<double>(N, 0.0));\n    for (int k = 0; k < K; k++) {\n        for (int i : V_prime) {\n            dist_res_node[k][i] = euclid(resident_x[k], resident_y[k], x[i], y[i]);\n        }\n    }\n\n    // Initial assignment\n    vector<int> assign(K, -1);\n    vector<vector<int>> residents(N);\n    for (int k = 0; k < K; k++) {\n        double min_d = INF;\n        int best_i = -1;\n        for (int i : V_prime) {\n            double d = dist_res_node[k][i];\n            if (d < min_d) {\n                min_d = d;\n                best_i = i;\n            }\n        }\n        assign[k] = best_i;\n        residents[best_i].push_back(k);\n    }\n\n    // Statistics for efficient reassignment\n    vector<double> max1(N, 0.0);\n    vector<int> count_max1(N, 0);\n    vector<double> max2(N, 0.0);\n\n    for (int i : V_prime) {\n        if (residents[i].empty()) {\n            max1[i] = 0;\n            count_max1[i] = 0;\n            max2[i] = 0;\n            continue;\n        }\n        double m1 = 0, m2 = 0;\n        int cnt = 0;\n        for (int k : residents[i]) {\n            double d = dist_res_node[k][i];\n            if (d > m1) {\n                m2 = m1;\n                m1 = d;\n                cnt = 1;\n            } else if (d == m1) {\n                cnt++;\n            } else if (d > m2) {\n                m2 = d;\n            }\n        }\n        max1[i] = m1;\n        count_max1[i] = cnt;\n        max2[i] = m2;\n    }\n\n    // Enhanced reassignment with more iterations\n    int iter = 0;\n    bool improved = true;\n    while (improved && iter < 80) {\n        improved = false;\n        double best_reduction = 0;\n        int best_k = -1, best_j = -1, best_i = -1;\n\n        for (int k = 0; k < K; k++) {\n            int i = assign[k];\n            for (int j : V_prime) {\n                if (j == i) continue;\n                double d_i = dist_res_node[k][i];\n                double d_j = dist_res_node[k][j];\n                \n                double new_max_i;\n                if (d_i == max1[i]) {\n                    if (count_max1[i] > 1) {\n                        new_max_i = max1[i];\n                    } else {\n                        new_max_i = max2[i];\n                    }\n                } else {\n                    new_max_i = max1[i];\n                }\n                \n                double new_max_j = max(max1[j], d_j);\n                \n                double reduction = max1[i]*max1[i] + max1[j]*max1[j] - (new_max_i*new_max_i + new_max_j*new_max_j);\n                \n                if (reduction > best_reduction) {\n                    best_reduction = reduction;\n                    best_k = k;\n                    best_j = j;\n                    best_i = i;\n                }\n            }\n        }\n\n        if (best_reduction > 1e-9) {\n            residents[best_i].erase(remove(residents[best_i].begin(), residents[best_i].end(), best_k), residents[best_i].end());\n            residents[best_j].push_back(best_k);\n            assign[best_k] = best_j;\n\n            for (int node : {best_i, best_j}) {\n                if (residents[node].empty()) {\n                    max1[node] = 0;\n                    count_max1[node] = 0;\n                    max2[node] = 0;\n                } else {\n                    double m1 = 0, m2 = 0;\n                    int cnt = 0;\n                    for (int k : residents[node]) {\n                        double d = dist_res_node[k][node];\n                        if (d > m1) {\n                            m2 = m1;\n                            m1 = d;\n                            cnt = 1;\n                        } else if (d == m1) {\n                            cnt++;\n                        } else if (d > m2) {\n                            m2 = d;\n                        }\n                    }\n                    max1[node] = m1;\n                    count_max1[node] = cnt;\n                    max2[node] = m2;\n                }\n            }\n\n            improved = true;\n            iter++;\n        }\n    }\n\n    // Set output strengths\n    vector<int> P(N, 0);\n    for (int i : V_prime) {\n        if (max1[i] > 0) {\n            P[i] = ceil(max1[i]);\n            if (P[i] > 5000) P[i] = 5000;\n        }\n    }\n\n    // Final optimization: try to reduce powers slightly if possible\n    // For each node, check if we can reduce the power by 1 and still cover all residents\n    for (int i : V_prime) {\n        if (P[i] <= 1) continue;\n        int original_power = P[i];\n        P[i]--;\n        if (!check_coverage(V_prime, P)) {\n            P[i] = original_power; // Revert if coverage is lost\n        }\n    }\n\n    // Set edge activation\n    vector<int> B(M, 0);\n    for (int j : activated_edges) {\n        B[j] = 1;\n    }\n\n    // Output\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << endl;\n\n    for (int j = 0; j < M; j++) {\n        if (j > 0) cout << \" \";\n        cout << B[j];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N = 30;\n    vector<vector<int>> grid(N);\n    for (int i = 0; i < N; i++) {\n        grid[i].resize(i+1);\n        for (int j = 0; j <= i; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<tuple<int, int, int, int>> swaps;\n    priority_queue<tuple<int, int, int>> pq;\n\n    auto check_and_push = [&](int x, int y) {\n        if (x < 0 || x >= N-1 || y < 0 || y > x) return;\n        if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n            pq.push({grid[x][y], x, y});\n        }\n    };\n\n    // Initial push of all violating nodes\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            check_and_push(x, y);\n        }\n    }\n\n    while (!pq.empty() && swaps.size() < 10000) {\n        auto [val, x, y] = pq.top();\n        pq.pop();\n        \n        // Check if this node still violates the condition\n        if (grid[x][y] <= grid[x+1][y] && grid[x][y] <= grid[x+1][y+1]) {\n            continue;\n        }\n\n        // Find the smaller child\n        int min_x = x+1;\n        int min_y = (grid[x+1][y] < grid[x+1][y+1]) ? y : y+1;\n        \n        // Swap\n        swap(grid[x][y], grid[min_x][min_y]);\n        swaps.push_back({x, y, min_x, min_y});\n\n        // Push affected nodes\n        check_and_push(x, y);          // The node that moved up\n        check_and_push(min_x, min_y);   // The node that moved down\n        check_and_push(x-1, y-1);       // Left parent of the moved up node\n        check_and_push(x-1, y);         // Right parent of the moved up node\n    }\n\n    cout << swaps.size() << endl;\n    for (auto [x1, y1, x2, y2] : swaps) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nconst int MAX_D = 9;\nconst int entrance_i = 0;\nconst int entrance_j = 4;\nint dx[4] = {1, -1, 0, 0};\nint dy[4] = {0, 0, 1, -1};\n\nint main() {\n    int D, N;\n    cin >> D >> N;\n    bool obstacle[MAX_D][MAX_D] = {false};\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    int M = D * D - 1 - N;\n    \n    // Precompute base_dist from entrance\n    int base_dist[MAX_D][MAX_D];\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            base_dist[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    base_dist[entrance_i][entrance_j] = 0;\n    q.push({entrance_i, entrance_j});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + dx[k];\n            int nj = j + dy[k];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                if (!obstacle[ni][nj] && base_dist[ni][nj] == -1) {\n                    base_dist[ni][nj] = base_dist[i][j] + 1;\n                    q.push({ni, nj});\n                }\n            }\n        }\n    }\n\n    // Create fixed order of free squares (excluding entrance), sorted by distance descending\n    vector<pair<int, int>> fixed_order;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if ((i != entrance_i || j != entrance_j) && !obstacle[i][j]) {\n                fixed_order.push_back({i, j});\n            }\n        }\n    }\n    sort(fixed_order.begin(), fixed_order.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n        if (base_dist[a.first][a.second] != base_dist[b.first][b.second]) {\n            return base_dist[a.first][a.second] > base_dist[b.first][b.second]; // Descending\n        }\n        if (a.first != b.first) {\n            return a.first > b.first; // Descending by row\n        }\n        return a.second > b.second; // Descending by column\n    });\n\n    bool occupied[MAX_D][MAX_D] = {false};\n    int container_number[MAX_D][MAX_D];\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            container_number[i][j] = -1;\n        }\n    }\n\n    // Storage phase\n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n\n        // Compute reachable free squares\n        bool visited[MAX_D][MAX_D] = {false};\n        vector<pair<int, int>> reachable;\n        queue<pair<int, int>> q_storage;\n        \n        if (!occupied[entrance_i][entrance_j] && !obstacle[entrance_i][entrance_j]) {\n            visited[entrance_i][entrance_j] = true;\n            q_storage.push({entrance_i, entrance_j});\n        }\n        \n        while (!q_storage.empty()) {\n            auto [i, j] = q_storage.front(); q_storage.pop();\n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                    if (!visited[ni][nj] && !obstacle[ni][nj] && !occupied[ni][nj]) {\n                        visited[ni][nj] = true;\n                        q_storage.push({ni, nj});\n                        if (!(ni == entrance_i && nj == entrance_j)) {\n                            reachable.push_back({ni, nj});\n                        }\n                    }\n                }\n            }\n        }\n\n        if (reachable.empty()) {\n            // If no reachable squares, find any free square\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (!obstacle[i][j] && !occupied[i][j] && !(i == entrance_i && j == entrance_j)) {\n                        reachable.push_back({i, j});\n                    }\n                }\n            }\n        }\n\n        // Find the first square in fixed_order that is reachable\n        auto chosen = reachable[0]; // Default\n        bool found = false;\n        for (auto pos : fixed_order) {\n            for (auto r : reachable) {\n                if (pos.first == r.first && pos.second == r.second) {\n                    chosen = pos;\n                    found = true;\n                    break;\n                }\n            }\n            if (found) break;\n        }\n\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n\n        occupied[chosen.first][chosen.second] = true;\n        container_number[chosen.first][chosen.second] = t;\n    }\n\n    // Transportation phase\n    bool free[MAX_D][MAX_D];\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (obstacle[i][j]) {\n                free[i][j] = false;\n            } else if (occupied[i][j]) {\n                free[i][j] = false;\n            } else {\n                free[i][j] = true;\n            }\n        }\n    }\n\n    for (int k = 0; k < M; k++) {\n        // Compute connected component of free squares connected to entrance\n        bool visited_cc[MAX_D][MAX_D] = {false};\n        queue<pair<int, int>> q_cc;\n        if (free[entrance_i][entrance_j]) {\n            visited_cc[entrance_i][entrance_j] = true;\n            q_cc.push({entrance_i, entrance_j});\n        }\n        while (!q_cc.empty()) {\n            auto [i, j] = q_cc.front(); q_cc.pop();\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 < D && nj >= 0 && nj < D) {\n                    if (free[ni][nj] && !visited_cc[ni][nj]) {\n                        visited_cc[ni][nj] = true;\n                        q_cc.push({ni, nj});\n                    }\n                }\n            }\n        }\n\n        // Find removable containers\n        vector<tuple<int, int, int>> removable;\n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (occupied[i][j]) {\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 < D && nj >= 0 && nj < D && visited_cc[ni][nj]) {\n                            removable.push_back({container_number[i][j], i, j});\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (removable.empty()) {\n            break;\n        }\n\n        sort(removable.begin(), removable.end());\n        auto [num, i, j] = removable[0];\n        cout << i << \" \" << j << endl;\n        free[i][j] = true;\n        occupied[i][j] = false;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c;\n            cin >> c;\n            cout << c;\n            if (j < n-1) cout << \" \";\n        }\n        cout << endl;\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <string>\n#include <cmath>\n#include <iomanip>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Phase 1: Robust weight estimation using insertion sort with refinement\n    vector<int> order;\n    int queries_used = 0;\n    \n    // Build initial order with binary search insertion\n    for (int i = 0; i < N; i++) {\n        int low = 0, high = order.size();\n        while (low < high && queries_used < Q) {\n            int mid = (low + high) / 2;\n            cout << \"1 1 \" << i << \" \" << order[mid] << endl;\n            cout.flush();\n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \">\") {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        order.insert(order.begin() + low, i);\n    }\n    \n    // Refine the order using remaining queries\n    // Use a more sophisticated approach: compare items that are likely to be out of order\n    while (queries_used < Q) {\n        bool found = false;\n        // Try to find two adjacent items that might be in wrong order\n        for (int i = 0; i < (int)order.size() - 1 && queries_used < Q; i++) {\n            // Compare order[i] and order[i+1]\n            cout << \"1 1 \" << order[i] << \" \" << order[i+1] << endl;\n            cout.flush();\n            string res;\n            cin >> res;\n            queries_used++;\n            \n            if (res == \"<\") {\n                // order[i] is lighter than order[i+1], so swap\n                swap(order[i], order[i+1]);\n                found = true;\n            }\n        }\n        \n        // If no swaps, try random pairs\n        if (!found && queries_used < Q) {\n            // Compare random items that are not adjacent\n            int i = rand() % N;\n            int j = rand() % N;\n            if (i != j && queries_used < Q) {\n                cout << \"1 1 \" << order[i] << \" \" << order[j] << endl;\n                cout.flush();\n                string res;\n                cin >> res;\n                queries_used++;\n                \n                // Update order based on result\n                if (res == \">\" && i < j) {\n                    // order[i] is heavier, should come before order[j]\n                    // But we need to find their positions\n                    auto it_i = find(order.begin(), order.end(), order[i]);\n                    auto it_j = find(order.begin(), order.end(), order[j]);\n                    if (it_i > it_j) {\n                        swap(*it_i, *it_j);\n                    }\n                } else if (res == \"<\" && i > j) {\n                    auto it_i = find(order.begin(), order.end(), order[i]);\n                    auto it_j = find(order.begin(), order.end(), order[j]);\n                    if (it_i < it_j) {\n                        swap(*it_i, *it_j);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Try multiple assignment strategies and pick the best\n    vector<int> best_assignment;\n    double best_variance = 1e18;\n    \n    // Strategy 1: Simple greedy by order\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            int min_set = 0;\n            for (int d = 1; d < D; d++) {\n                if (set_totals[d] < set_totals[min_set]) {\n                    min_set = d;\n                }\n            }\n            assignment[item] = min_set;\n            set_totals[min_set] += (N - i); // Weight estimate\n        }\n        \n        // Calculate variance\n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 2: Round-robin assignment\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            assignment[item] = i % D;\n            set_totals[i % D] += (N - i);\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 3: Alternate assignment (heaviest to smallest set, then lightest to largest set)\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            if (i % 2 == 0) {\n                // Heaviest items: assign to smallest set\n                int min_set = 0;\n                for (int d = 1; d < D; d++) {\n                    if (set_totals[d] < set_totals[min_set]) {\n                        min_set = d;\n                    }\n                }\n                assignment[item] = min_set;\n                set_totals[min_set] += (N - i);\n            } else {\n                // Lightest items: assign to largest set\n                int max_set = 0;\n                for (int d = 1; d < D; d++) {\n                    if (set_totals[d] > set_totals[max_set]) {\n                        max_set = d;\n                    }\n                }\n                assignment[item] = max_set;\n                set_totals[max_set] += (N - i);\n            }\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Strategy 4: Use the sorted order but with weighted assignment\n    {\n        vector<double> set_totals(D, 0.0);\n        vector<int> assignment(N);\n        // Use exponential weights: heaviest items get much higher weight\n        for (int i = 0; i < N; i++) {\n            int item = order[i];\n            double weight = pow(2.0, (N - i) / (N / 4.0)); // Exponential weighting\n            int min_set = 0;\n            for (int d = 1; d < D; d++) {\n                if (set_totals[d] < set_totals[min_set]) {\n                    min_set = d;\n                }\n            }\n            assignment[item] = min_set;\n            set_totals[min_set] += weight;\n        }\n        \n        double mean = 0;\n        for (double total : set_totals) mean += total;\n        mean /= D;\n        double variance = 0;\n        for (double total : set_totals) {\n            variance += (total - mean) * (total - mean);\n        }\n        variance /= D;\n        \n        if (variance < best_variance) {\n            best_variance = variance;\n            best_assignment = assignment;\n        }\n    }\n    \n    // Output the best assignment found\n    for (int i = 0; i < N; i++) {\n        cout << best_assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cout.tie(0);\n\n    int n, m;\n    cin >> n >> m;\n    int per_stack = n / m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        for (int j = 0; j < per_stack; ++j) {\n            int x;\n            cin >> x;\n            stacks[i].push_back(x);\n        }\n    }\n\n    vector<int> stack_of(n + 1, -1);\n    vector<int> idx_in_stack(n + 1, -1);\n\n    auto recompute = [&]() {\n        fill(stack_of.begin(), stack_of.end(), -1);\n        fill(idx_in_stack.begin(), idx_in_stack.end(), -1);\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                int box = stacks[i][j];\n                stack_of[box] = i;\n                idx_in_stack[box] = j;\n            }\n        }\n    };\n\n    vector<pair<int, int>> ops;\n\n    for (int v = 1; v <= n; ++v) {\n        recompute();\n        int s = stack_of[v];\n        int i = idx_in_stack[v];\n\n        if (i == (int)stacks[s].size() - 1) {\n            ops.emplace_back(v, 0);\n            stacks[s].pop_back();\n            continue;\n        }\n\n        int B = stacks[s][i + 1];\n        int candidate = -1;\n        int best_size = 1000;\n\n        // First, look for empty stacks\n        for (int t = 0; t < m; ++t) {\n            if (t == s) continue;\n            if (stacks[t].empty()) {\n                candidate = t;\n                break;\n            }\n        }\n\n        // If no empty stack, look for stacks with top > B and smallest size\n        if (candidate == -1) {\n            for (int t = 0; t < m; ++t) {\n                if (t == s) continue;\n                int top = stacks[t].empty() ? -1 : stacks[t].back();\n                if (top > B) {\n                    if (stacks[t].size() < best_size) {\n                        best_size = stacks[t].size();\n                        candidate = t;\n                    }\n                }\n            }\n        }\n\n        // If still no candidate, choose stack with smallest size\n        if (candidate == -1) {\n            for (int t = 0; t < m; ++t) {\n                if (t == s) continue;\n                if (stacks[t].size() < best_size) {\n                    best_size = stacks[t].size();\n                    candidate = t;\n                }\n            }\n        }\n\n        // Move the group above v to candidate stack\n        for (int j = i + 1; j < (int)stacks[s].size(); ++j) {\n            stacks[candidate].push_back(stacks[s][j]);\n        }\n        stacks[s].resize(i + 1);\n        ops.emplace_back(B, candidate + 1);\n\n        // Carry out v\n        ops.emplace_back(v, 0);\n        stacks[s].pop_back();\n    }\n\n    for (auto &p : ops) {\n        cout << p.first << \" \" << p.second << \"\\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;\nvector<vector<bool>> visited;\nstring moves = \"\";\n\n// Direction vectors: right, down, left, up\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'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    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check walls based on direction\n    if (dir == 0) { // right\n        return v[i][j] == '0';\n    } else if (dir == 1) { // down\n        return h[i][j] == '0';\n    } else if (dir == 2) { // left\n        return j > 0 && v[i][j-1] == '0';\n    } else { // up\n        return i > 0 && h[i-1][j] == '0';\n    }\n}\n\nvoid dfs(int i, int j) {\n    visited[i][j] = true;\n    \n    // Collect all possible moves to unvisited squares\n    vector<tuple<int, int, int>> candidates; // (d_value, new_i, new_j)\n    \n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n            !visited[ni][nj] && can_move(i, j, dir)) {\n            candidates.emplace_back(d[ni][nj], ni, nj);\n        }\n    }\n    \n    // Sort by susceptibility in descending order - visit high-susceptibility squares first\n    sort(candidates.begin(), candidates.end(), [](const tuple<int,int,int>& a, const tuple<int,int,int>& b) {\n        return get<0>(a) > get<0>(b);\n    });\n    \n    for (auto& candidate : candidates) {\n        int new_d = get<0>(candidate);\n        int ni = get<1>(candidate);\n        int nj = get<2>(candidate);\n        \n        // Determine direction\n        int dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (i + di[d] == ni && j + dj[d] == nj) {\n                dir = d;\n                break;\n            }\n        }\n        \n        // Move to the new square\n        moves += dir_char[dir];\n        dfs(ni, nj);\n        \n        // Move back\n        moves += dir_char[(dir + 2) % 4];\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    visited.assign(N, vector<bool>(N, false));\n    \n    dfs(0, 0);\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 15;\nconst int NN = GRID_SIZE * GRID_SIZE;\nconst int INF = 1e9;\n\nvector<int> pos[26];  // positions (linear index) for each letter\n\ninline int row(int idx) { return idx / GRID_SIZE; }\ninline int col(int idx) { return idx % GRID_SIZE; }\n\n// Manhattan distance transform: out[v] = min_u (cur[u] + dist(u, v))\nvoid dist_transform(const vector<int>& cur, vector<int>& out) {\n    int val[GRID_SIZE][GRID_SIZE];\n    for (int i = 0; i < GRID_SIZE; ++i)\n        for (int j = 0; j < GRID_SIZE; ++j)\n            val[i][j] = cur[i * GRID_SIZE + j];\n\n    int tmp[GRID_SIZE][GRID_SIZE];\n    // horizontal pass\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        // left to right\n        tmp[i][0] = val[i][0];\n        for (int j = 1; j < GRID_SIZE; ++j) {\n            int a = val[i][j];\n            int b = tmp[i][j-1] + 1;\n            tmp[i][j] = a < b ? a : b;\n        }\n        // right to left\n        for (int j = GRID_SIZE - 2; j >= 0; --j) {\n            int b = tmp[i][j+1] + 1;\n            if (b < tmp[i][j]) tmp[i][j] = b;\n        }\n    }\n\n    // vertical pass\n    for (int j = 0; j < GRID_SIZE; ++j) {\n        // top to bottom\n        out[0 * GRID_SIZE + j] = tmp[0][j];\n        for (int i = 1; i < GRID_SIZE; ++i) {\n            int a = tmp[i][j];\n            int b = out[(i-1) * GRID_SIZE + j] + 1;\n            out[i * GRID_SIZE + j] = a < b ? a : b;\n        }\n        // bottom to top\n        for (int i = GRID_SIZE - 2; i >= 0; --i) {\n            int b = out[(i+1) * GRID_SIZE + j] + 1;\n            if (b < out[i * GRID_SIZE + j]) out[i * GRID_SIZE + j] = b;\n        }\n    }\n}\n\n// Compute minimal additional cost to type X from current distribution dp\nint compute_cost(const vector<int>& dp, const string& X,\n                 vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    int ans = INF;\n    for (int v : pos[X.back() - 'A'])\n        if (cur[v] < ans) ans = cur[v];\n    return ans;\n}\n\n// Extend dp by typing X, returning the new distribution\nvector<int> extend_dp(const vector<int>& dp, const string& X,\n                      vector<int>& cur, vector<int>& minDist, vector<int>& next) {\n    cur = dp;\n    for (char ch : X) {\n        dist_transform(cur, minDist);\n        fill(next.begin(), next.end(), INF);\n        for (int v : pos[ch - 'A'])\n            next[v] = minDist[v] + 1;\n        cur.swap(next);\n    }\n    return cur;\n}\n\n// Reconstruct the optimal sequence of squares for typing X\nvector<int> reconstruct_path(const vector<int>& dp, const string& X) {\n    int L = X.size();\n    vector<vector<int>> cost(L + 1, vector<int>(NN, INF));\n    vector<vector<int>> prev(L + 1, vector<int>(NN, -1));\n\n    // pos 0\n    for (int u = 0; u < NN; ++u) cost[0][u] = dp[u];\n\n    for (int p = 0; p < L; ++p) {\n        char c = X[p];\n        for (int v : pos[c - 'A']) {\n            for (int u = 0; u < NN; ++u) {\n                if (cost[p][u] == INF) continue;\n                int d = abs(row(u) - row(v)) + abs(col(u) - col(v));\n                int new_cost = cost[p][u] + d + 1;\n                if (new_cost < cost[p+1][v]) {\n                    cost[p+1][v] = new_cost;\n                    prev[p+1][v] = u;\n                }\n            }\n        }\n    }\n\n    // find best end\n    int best_v = -1, best_cost = INF;\n    for (int v : pos[X.back() - 'A']) {\n        if (cost[L][v] < best_cost) {\n            best_cost = cost[L][v];\n            best_v = v;\n        }\n    }\n\n    // backtrack\n    vector<int> path(L);\n    int cur_v = best_v;\n    for (int p = L; p >= 1; --p) {\n        path[p-1] = cur_v;\n        cur_v = prev[p][cur_v];\n    }\n    return path;\n}\n\n// Compute maximum overlap (0..4) between suffix of S and prefix of tk\nint compute_overlap(const string& S, const string& tk) {\n    int slen = S.size();\n    int max_possible = min(4, slen);\n    for (int l = max_possible; l >= 1; --l) {\n        if (S.compare(slen - l, l, tk, 0, l) == 0)\n            return l;\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N_input, M;\n    cin >> N_input >> M;\n    int si, sj;\n    cin >> si >> sj;\n\n    // read grid\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            char c = row[j];\n            pos[c - 'A'].push_back(i * GRID_SIZE + j);\n        }\n    }\n\n    // read target strings\n    vector<string> t(M);\n    for (int i = 0; i < M; ++i) cin >> t[i];\n\n    // initial state\n    vector<int> dp(NN, INF);\n    int start_idx = si * GRID_SIZE + sj;\n    dp[start_idx] = 0;\n\n    string S = \"\";\n    vector<pair<int, int>> ops;\n    vector<bool> covered(M, false);\n\n    // buffers for DP\n    vector<int> cur_buf(NN), minDist_buf(NN), next_buf(NN);\n\n    while (true) {\n        // check if all covered\n        bool all_covered = true;\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k]) {\n                all_covered = false;\n                break;\n            }\n        }\n        if (all_covered) break;\n\n        int best_k = -1;\n        int best_cost_val = INF;\n        string best_X;\n\n        // evaluate all uncovered t_k\n        for (int k = 0; k < M; ++k) {\n            if (covered[k]) continue;\n            const string& tk = t[k];\n            int overlap = compute_overlap(S, tk);\n            string X = tk.substr(overlap);\n            if (X.empty()) {   // already covered\n                covered[k] = true;\n                continue;\n            }\n            int cost = compute_cost(dp, X, cur_buf, minDist_buf, next_buf);\n            if (cost < best_cost_val) {\n                best_cost_val = cost;\n                best_k = k;\n                best_X = X;\n            }\n        }\n\n        if (best_k == -1) break;  // nothing left to type\n\n        // reconstruct the optimal path for best_X\n        vector<int> path = reconstruct_path(dp, best_X);\n        for (int idx : path) {\n            ops.push_back({row(idx), col(idx)});\n        }\n\n        // update dp and S\n        dp = extend_dp(dp, best_X, cur_buf, minDist_buf, next_buf);\n        S += best_X;\n\n        // update covered set\n        for (int k = 0; k < M; ++k) {\n            if (!covered[k] && S.find(t[k]) != string::npos)\n                covered[k] = true;\n        }\n    }\n\n    // output operations\n    for (auto& p : ops) {\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    vector<vector<pair<int, int>>> polyominoes(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        vector<pair<int, int>> poly(d);\n        for (int i = 0; i < d; i++) {\n            cin >> poly[i].first >> poly[i].second;\n        }\n        polyominoes[k] = poly;\n    }\n\n    vector<pair<int, int>> has_oil;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << \"q 1 \" << i << \" \" << j << endl;\n            cout.flush();\n            int val;\n            cin >> val;\n            if (val > 0) {\n                has_oil.push_back({i, j});\n            }\n        }\n    }\n\n    cout << \"a \" << has_oil.size();\n    for (auto &p : has_oil) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl;\n    cout.flush();\n\n    int result;\n    cin >> result;\n\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n\nusing namespace std;\n\nstruct Config {\n    int R, C;\n    vector<int> cell_areas;\n};\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    vector<vector<int>> A(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int i = 0; i < N; i++) {\n            cin >> A[d][i];\n        }\n    }\n\n    // Generate all grid configurations\n    vector<Config> configs;\n    for (int R = 1; R <= N; R++) {\n        for (int C = 1; C <= N; C++) {\n            if (R * C >= N) {\n                Config cfg;\n                cfg.R = R;\n                cfg.C = C;\n                // Compute cell areas\n                for (int i = 0; i < R; i++) {\n                    int h1 = (i * W) / R;\n                    int h2 = ((i + 1) * W) / R;\n                    for (int j = 0; j < C; j++) {\n                        int w1 = (j * W) / C;\n                        int w2 = ((j + 1) * W) / C;\n                        cfg.cell_areas.push_back((h2 - h1) * (w2 - w1));\n                    }\n                }\n                sort(cfg.cell_areas.rbegin(), cfg.cell_areas.rend());\n                if (cfg.cell_areas.size() > N) {\n                    cfg.cell_areas.resize(N);\n                }\n                configs.push_back(cfg);\n            }\n        }\n    }\n\n    int num_configs = configs.size();\n    vector<vector<long long>> area_cost(D, vector<long long>(num_configs, 0));\n    \n    // Precompute area costs for each day and configuration\n    for (int d = 0; d < D; d++) {\n        vector<int> sorted_areas = A[d];\n        sort(sorted_areas.rbegin(), sorted_areas.rend());\n        for (int idx = 0; idx < num_configs; idx++) {\n            long long cost = 0;\n            for (int k = 0; k < N; k++) {\n                if (sorted_areas[k] > configs[idx].cell_areas[k]) {\n                    cost += 100LL * (sorted_areas[k] - configs[idx].cell_areas[k]);\n                }\n            }\n            area_cost[d][idx] = cost;\n        }\n    }\n\n    // Precompute partition costs\n    vector<vector<long long>> part_cost(num_configs, vector<long long>(num_configs, 0));\n    for (int i = 0; i < num_configs; i++) {\n        for (int j = 0; j < num_configs; j++) {\n            part_cost[i][j] = abs(configs[i].R - configs[j].R) + abs(configs[i].C - configs[j].C);\n        }\n    }\n\n    // DP table and parent tracking\n    vector<vector<long long>> dp(D, vector<long long>(num_configs, LLONG_MAX));\n    vector<vector<int>> parent(D, vector<int>(num_configs, -1));\n\n    // Initialize first day\n    for (int i = 0; i < num_configs; i++) {\n        dp[0][i] = area_cost[0][i];\n    }\n\n    // DP for remaining days\n    for (int d = 1; d < D; d++) {\n        for (int j = 0; j < num_configs; j++) {\n            long long min_cost = LLONG_MAX;\n            int best_prev = -1;\n            for (int i = 0; i < num_configs; i++) {\n                if (dp[d-1][i] == LLONG_MAX) continue;\n                long long cost = dp[d-1][i] + part_cost[i][j] + area_cost[d][j];\n                if (cost < min_cost) {\n                    min_cost = cost;\n                    best_prev = i;\n                }\n            }\n            if (best_prev != -1) {\n                dp[d][j] = min_cost;\n                parent[d][j] = best_prev;\n            }\n        }\n    }\n\n    // Find best configuration for last day\n    int best_idx = 0;\n    long long best_total = LLONG_MAX;\n    for (int i = 0; i < num_configs; i++) {\n        if (dp[D-1][i] < best_total) {\n            best_total = dp[D-1][i];\n            best_idx = i;\n        }\n    }\n\n    // Backtrack to get configuration sequence\n    vector<int> config_seq(D);\n    config_seq[D-1] = best_idx;\n    for (int d = D-2; d >= 0; d--) {\n        config_seq[d] = parent[d+1][config_seq[d+1]];\n    }\n\n    // Output rectangles for each day\n    for (int d = 0; d < D; d++) {\n        int cfg_idx = config_seq[d];\n        Config& cfg = configs[cfg_idx];\n        int R = cfg.R;\n        int C = cfg.C;\n\n        // Compute grid lines\n        vector<int> rows(R + 1);\n        vector<int> cols(C + 1);\n        for (int i = 0; i <= R; i++) {\n            rows[i] = (i * W) / R;\n        }\n        for (int j = 0; j <= C; j++) {\n            cols[j] = (j * W) / C;\n        }\n\n        // Create list of cells with coordinates and areas\n        vector<pair<int, int>> cell_coords; // (area, cell_index)\n        vector<pair<int, int>> cell_rects;  // (row, col) for cell index\n        for (int i = 0; i < R; i++) {\n            for (int j = 0; j < C; j++) {\n                int area = (rows[i+1] - rows[i]) * (cols[j+1] - cols[j]);\n                int cell_idx = i * C + j;\n                cell_coords.push_back({area, cell_idx});\n                cell_rects.push_back({i, j});\n            }\n        }\n        sort(cell_coords.rbegin(), cell_coords.rend());\n        if (cell_coords.size() > N) {\n            cell_coords.resize(N);\n        }\n\n        // Sort areas for this day\n        vector<pair<int, int>> areas_with_idx(N);\n        for (int k = 0; k < N; k++) {\n            areas_with_idx[k] = {A[d][k], k};\n        }\n        sort(areas_with_idx.rbegin(), areas_with_idx.rend());\n\n        // Assign largest areas to largest cells\n        vector<int> assignment(N);\n        for (int k = 0; k < N; k++) {\n            int cell_idx = cell_coords[k].second;\n            int orig_idx = areas_with_idx[k].second;\n            assignment[orig_idx] = cell_idx;\n        }\n\n        // Output in original order\n        for (int k = 0; k < N; k++) {\n            int cell_idx = assignment[k];\n            int i = cell_idx / C;\n            int j = cell_idx % C;\n            cout << rows[i] << \" \" << cols[j] << \" \" << rows[i+1] << \" \" << cols[j+1] << endl;\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <climits>\n\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    int rem[9][9];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> rem[i][j];\n            rem[i][j] %= MOD;\n        }\n    }\n\n    int s[20][3][3];\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> ops;\n\n    for (int step = 0; step < K; step++) {\n        long long best_change = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= 6; p++) {\n                for (int q = 0; q <= 6; q++) {\n                    long long change = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int r = rem[p+i][q+j];\n                            int s_val = s[m][i][j];\n                            if (r + s_val < MOD) {\n                                change += s_val;\n                            } else {\n                                change += s_val - MOD;\n                            }\n                        }\n                    }\n                    if (change > best_change) {\n                        best_change = change;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_change <= 0) {\n            break;\n        }\n\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int &r = rem[best_p+i][best_q+j];\n                int s_val = s[best_m][i][j];\n                if (r + s_val < MOD) {\n                    r += s_val;\n                } else {\n                    r = r + s_val - MOD;\n                }\n            }\n        }\n\n        ops.push_back(make_tuple(best_m, best_p, best_q));\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto op : ops) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <queue>\n\nusing namespace std;\n\nconst int MAX_N = 5;\nconst int MAX_TURNS = 10000;\n\nint N;\nint A[MAX_N][MAX_N];\n\nstruct Crane {\n    int x, y;\n    int carrying;\n};\n\nint grid[MAX_N][MAX_N];\nCrane cranes[MAX_N];\nint next_arrival[MAX_N];\nint dispatched_count[MAX_N];\nint next_required[MAX_N];\n\nvoid init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n        next_arrival[i] = 0;\n        dispatched_count[i] = 0;\n        next_required[i] = i * N;\n    }\n    for (int i = 0; i < N; i++) {\n        cranes[i] = {i, 0, -1};\n    }\n}\n\nchar get_move(int x1, int y1, int x2, int y2) {\n    if (x1 < x2) return 'D';\n    if (x1 > x2) return 'U';\n    if (y1 < y2) return 'R';\n    if (y1 > y2) return 'L';\n    return '.';\n}\n\npair<int, int> find_temp_storage(int preferred_row) {\n    // Try to find a storage spot in the preferred row\n    for (int col = 1; col < N-1; col++) {\n        if (grid[preferred_row][col] == -1) {\n            return {preferred_row, col};\n        }\n    }\n    // Try other rows\n    for (int row = 0; row < N; row++) {\n        for (int col = 1; col < N-1; col++) {\n            if (grid[row][col] == -1) {\n                return {row, col};\n            }\n        }\n    }\n    // Fallback: return a spot that's not a gate\n    for (int row = 0; row < N; row++) {\n        for (int col = 0; col < N; col++) {\n            if (grid[row][col] == -1 && col != 0 && col != N-1) {\n                return {row, col};\n            }\n        }\n    }\n    return {-1, -1};\n}\n\nint main() {\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    init();\n\n    vector<string> actions_per_crane(N, \"\");\n    int total_containers = N * N;\n    int turn = 0;\n\n    while (turn < MAX_TURNS) {\n        // Step 1: Container arrival\n        for (int i = 0; i < N; i++) {\n            if (next_arrival[i] < N) {\n                bool gate_free = (grid[i][0] == -1);\n                for (int k = 0; k < N; k++) {\n                    if (cranes[k].x == i && cranes[k].y == 0) {\n                        gate_free = false;\n                        break;\n                    }\n                }\n                if (gate_free) {\n                    grid[i][0] = A[i][next_arrival[i]];\n                    next_arrival[i]++;\n                }\n            }\n        }\n\n        // Prepare for actions\n        vector<char> actions(N, '.');\n        vector<pair<int, int>> intended_pos(N);\n\n        // Plan actions for each crane\n        for (int idx = 0; idx < N; idx++) {\n            int x = cranes[idx].x;\n            int y = cranes[idx].y;\n            int carrying = cranes[idx].carrying;\n\n            if (idx == 0) { // Large crane\n                if (carrying != -1) {\n                    // Carrying a container\n                    int gate = carrying / N;\n                    if (carrying == next_required[gate]) {\n                        // This is the next required container\n                        if (x == gate && y == N-1) {\n                            actions[idx] = 'Q';\n                        } else {\n                            actions[idx] = get_move(x, y, gate, N-1);\n                        }\n                    } else {\n                        // Not the next required, move to temporary storage\n                        pair<int, int> storage = find_temp_storage(gate);\n                        if (storage.first != -1) {\n                            if (x == storage.first && y == storage.second) {\n                                actions[idx] = 'Q';\n                            } else {\n                                actions[idx] = get_move(x, y, storage.first, storage.second);\n                            }\n                        } else {\n                            actions[idx] = '.';\n                        }\n                    }\n                } else {\n                    // Not carrying, check for wrong containers at dispatch gates\n                    bool found_wrong = false;\n                    for (int i = 0; i < N; i++) {\n                        if (grid[i][N-1] != -1 && grid[i][N-1] != next_required[i]) {\n                            // Found a wrong container at dispatch gate\n                            if (x == i && y == N-1) {\n                                actions[idx] = 'P';\n                            } else {\n                                actions[idx] = get_move(x, y, i, N-1);\n                            }\n                            found_wrong = true;\n                            break;\n                        }\n                    }\n                    \n                    if (!found_wrong) {\n                        // Check if next required container is available\n                        int target = next_required[0]; // We'll check all gates\n                        bool found = false;\n                        for (int i = 0; i < N; i++) {\n                            int req = next_required[i];\n                            for (int r = 0; r < N; r++) {\n                                for (int c = 0; c < N; c++) {\n                                    if (grid[r][c] == req) {\n                                        if (x == r && y == c) {\n                                            actions[idx] = 'P';\n                                        } else {\n                                            actions[idx] = get_move(x, y, r, c);\n                                        }\n                                        found = true;\n                                        break;\n                                    }\n                                }\n                                if (found) break;\n                            }\n                            if (found) break;\n                        }\n                        \n                        if (!found) {\n                            // Check for containers at receiving gates that aren't next required\n                            for (int i = 0; i < N; i++) {\n                                if (grid[i][0] != -1 && grid[i][0] != next_required[i]) {\n                                    if (x == i && y == 0) {\n                                        actions[idx] = 'P';\n                                    } else {\n                                        actions[idx] = get_move(x, y, i, 0);\n                                    }\n                                    found = true;\n                                    break;\n                                }\n                            }\n                            \n                            if (!found) {\n                                // Wait at a central position\n                                if (x != 0 || y != N-1) {\n                                    actions[idx] = get_move(x, y, 0, N-1);\n                                }\n                            }\n                        }\n                    }\n                }\n            } else { // Small cranes\n                // Move to the rightmost column and stay there\n                if (y < N-1) {\n                    actions[idx] = 'R';\n                }\n            }\n\n            // Compute intended position\n            int nx = x, ny = y;\n            if (actions[idx] == 'U') nx--;\n            else if (actions[idx] == 'D') nx++;\n            else if (actions[idx] == 'L') ny--;\n            else if (actions[idx] == 'R') ny++;\n            \n            intended_pos[idx] = {nx, ny};\n        }\n\n        // Robust collision detection and resolution\n        bool has_conflict;\n        do {\n            has_conflict = false;\n            set<int> cranes_to_revert;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    // Check for same intended position\n                    if (intended_pos[i] == intended_pos[j]) {\n                        cranes_to_revert.insert(j);\n                        has_conflict = true;\n                    }\n                    // Check for swapping\n                    if (intended_pos[i] == make_pair(cranes[j].x, cranes[j].y) &&\n                        intended_pos[j] == make_pair(cranes[i].x, cranes[i].y)) {\n                        cranes_to_revert.insert(j);\n                        has_conflict = true;\n                    }\n                    // Check if one crane is moving into another crane's current position\n                    if (actions[j] == '.' && intended_pos[i] == make_pair(cranes[j].x, cranes[j].y)) {\n                        cranes_to_revert.insert(i);\n                        has_conflict = true;\n                    }\n                }\n            }\n            \n            // Revert conflicting cranes\n            for (int idx : cranes_to_revert) {\n                actions[idx] = '.';\n                intended_pos[idx] = {cranes[idx].x, cranes[idx].y};\n            }\n        } while (has_conflict);\n\n        // Apply actions\n        for (int idx = 0; idx < N; idx++) {\n            int x = cranes[idx].x;\n            int y = cranes[idx].y;\n            char action = actions[idx];\n            int nx = intended_pos[idx].first;\n            int ny = intended_pos[idx].second;\n            \n            // Validate move boundaries\n            if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) {\n                    action = '.';\n                    nx = x;\n                    ny = y;\n                }\n            }\n            \n            // Apply action\n            if (action == 'P') {\n                if (cranes[idx].carrying == -1 && grid[x][y] != -1) {\n                    cranes[idx].carrying = grid[x][y];\n                    grid[x][y] = -1;\n                }\n            } else if (action == 'Q') {\n                if (cranes[idx].carrying != -1 && grid[x][y] == -1) {\n                    grid[x][y] = cranes[idx].carrying;\n                    cranes[idx].carrying = -1;\n                }\n            } else if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                // Check small crane restriction\n                if (idx >= 1 && cranes[idx].carrying != -1 && grid[nx][ny] != -1) {\n                    // Skip movement for small crane carrying container to occupied square\n                } else {\n                    cranes[idx].x = nx;\n                    cranes[idx].y = ny;\n                }\n            }\n            \n            actions_per_crane[idx] += action;\n        }\n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                if (grid[i][N-1] == next_required[i]) {\n                    grid[i][N-1] = -1;\n                    dispatched_count[i]++;\n                    next_required[i] = i * N + dispatched_count[i];\n                }\n            }\n        }\n\n        // Check if done\n        bool all_dispatched = true;\n        for (int i = 0; i < N; i++) {\n            if (dispatched_count[i] < N) {\n                all_dispatched = false;\n                break;\n            }\n        }\n        if (all_dispatched) break;\n\n        turn++;\n    }\n\n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << actions_per_crane[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(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    vector<tuple<int, int, int>> surp;\n    vector<tuple<int, int, int>> def;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                surp.push_back(make_tuple(i, j, grid[i][j]));\n            } else if (grid[i][j] < 0) {\n                def.push_back(make_tuple(i, j, -grid[i][j]));\n            }\n        }\n    }\n\n    int cur_i = 0, cur_j = 0;\n    vector<string> ops;\n\n    auto move_to = [&](int target_i, int target_j) {\n        while (cur_i < target_i) {\n            ops.push_back(\"D\");\n            cur_i++;\n        }\n        while (cur_i > target_i) {\n            ops.push_back(\"U\");\n            cur_i--;\n        }\n        while (cur_j < target_j) {\n            ops.push_back(\"R\");\n            cur_j++;\n        }\n        while (cur_j > target_j) {\n            ops.push_back(\"L\");\n            cur_j--;\n        }\n    };\n\n    while (!surp.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < surp.size(); idx++) {\n            auto [i, j, amt] = surp[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = surp[best_idx];\n        move_to(i, j);\n        ops.push_back(\"+\" + to_string(amt));\n        surp.erase(surp.begin() + best_idx);\n    }\n\n    while (!def.empty()) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        for (int idx = 0; idx < def.size(); idx++) {\n            auto [i, j, amt] = def[idx];\n            int dist = abs(i - cur_i) + abs(j - cur_j);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = idx;\n            }\n        }\n        auto [i, j, amt] = def[best_idx];\n        move_to(i, j);\n        ops.push_back(\"-\" + to_string(amt));\n        def.erase(def.begin() + best_idx);\n    }\n\n    for (const string& op : ops) {\n        cout << op << '\\n';\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n    int grid_size = N * N;\n\n    vector<vector<int>> seeds(seed_count, vector<int>(M));\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n        }\n    }\n\n    // Initialize random number generator\n    mt19937 rng(12345);\n    \n    // Precompute maximum values for each criterion\n    vector<int> max_vals(M, 0);\n    for (int l = 0; l < M; l++) {\n        for (int i = 0; i < seed_count; i++) {\n            max_vals[l] = max(max_vals[l], seeds[i][l]);\n        }\n    }\n    \n    // Target sum to aim for\n    long long target_sum = 0;\n    for (int l = 0; l < M; l++) {\n        target_sum += max_vals[l];\n    }\n\n    // Grid directions\n    vector<int> di = {-1, 1, 0, 0};\n    vector<int> dj = {0, 0, -1, 1};\n\n    for (int t = 0; t < T; t++) {\n        // 1. ADVANCED SEED SELECTION\n        // Calculate total values and criterion-wise strengths\n        vector<int> total(seed_count, 0);\n        vector<vector<int>> criterion_strength(M, vector<int>(seed_count));\n        for (int i = 0; i < seed_count; i++) {\n            for (int l = 0; l < M; l++) {\n                total[i] += seeds[i][l];\n                criterion_strength[l][i] = seeds[i][l];\n            }\n        }\n\n        // Sort seeds by total value\n        vector<int> indices(seed_count);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(), [&](int i, int j) { \n            if (total[i] != total[j]) return total[i] > total[j];\n            return i < j;\n        });\n\n        // Select seeds using a hybrid approach\n        vector<int> selected_indices;\n        set<int> selected_set;\n        \n        // Strategy: Select seeds that are good in different criteria\n        // Phase 1: Top seeds by total value (50% of grid)\n        for (int i = 0; i < grid_size / 2 && i < seed_count; i++) {\n            if (selected_set.count(indices[i]) == 0) {\n                selected_indices.push_back(indices[i]);\n                selected_set.insert(indices[i]);\n            }\n        }\n        \n        // Phase 2: Seeds that are strong in specific criteria (25% of grid)\n        for (int l = 0; l < M && selected_indices.size() < grid_size * 3 / 4; l++) {\n            // Find top seeds for this criterion\n            vector<int> candidates;\n            for (int i = 0; i < seed_count; i++) {\n                if (selected_set.count(i) == 0) {\n                    candidates.push_back(i);\n                }\n            }\n            sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                return criterion_strength[l][a] > criterion_strength[l][b];\n            });\n            for (int i = 0; i < min(2, (int)candidates.size()) && selected_indices.size() < grid_size * 3 / 4; i++) {\n                selected_indices.push_back(candidates[i]);\n                selected_set.insert(candidates[i]);\n            }\n        }\n        \n        // Phase 3: Fill remaining with seeds that have high variance (diverse profiles)\n        vector<pair<double, int>> variance_seeds;\n        for (int i = 0; i < seed_count; i++) {\n            if (selected_set.count(i)) continue;\n            // Calculate variance of the seed's values\n            double mean = total[i] / (double)M;\n            double variance = 0;\n            for (int l = 0; l < M; l++) {\n                variance += (seeds[i][l] - mean) * (seeds[i][l] - mean);\n            }\n            variance /= M;\n            variance_seeds.push_back({variance, i});\n        }\n        sort(variance_seeds.begin(), variance_seeds.end(), greater<pair<double, int>>());\n        for (auto [var, idx] : variance_seeds) {\n            if (selected_indices.size() >= grid_size) break;\n            if (selected_set.count(idx) == 0) {\n                selected_indices.push_back(idx);\n                selected_set.insert(idx);\n            }\n        }\n\n        // 2. SMART GRID ASSIGNMENT\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Precompute potential value of pairs\n        auto pair_potential = [&](int a, int b) {\n            long long potential = 0;\n            for (int l = 0; l < M; l++) {\n                // Expected value if we could always take the max\n                potential += max(seeds[a][l], seeds[b][l]);\n                // Add a bonus for complementarity (how well they cover different criteria)\n                if (seeds[a][l] > 0 && seeds[b][l] > 0) {\n                    potential += min(seeds[a][l], seeds[b][l]) * 0.1;\n                }\n            }\n            return potential;\n        };\n\n        // Precompute \"goodness\" of each seed\n        vector<double> seed_goodness(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            if (selected_set.count(i) == 0) continue;\n            // Goodness is based on total value and diversity\n            double goodness = total[i];\n            double mean = total[i] / (double)M;\n            double variance = 0;\n            for (int l = 0; l < M; l++) {\n                variance += (seeds[i][l] - mean) * (seeds[i][l] - mean);\n            }\n            goodness += sqrt(variance) * 0.5; // Reward diversity\n            seed_goodness[i] = goodness;\n        }\n\n        // Assignment strategy: Place good seeds in the center, and pair complementary seeds\n        vector<pair<int, int>> cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cells.push_back({i, j});\n            }\n        }\n        \n        // Sort cells by number of neighbors (center first)\n        sort(cells.begin(), cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n            int na = 0, nb = 0;\n            for (int d = 0; d < 4; d++) {\n                int ai = a.first + di[d], aj = a.second + dj[d];\n                if (ai >= 0 && ai < N && aj >= 0 && aj < N) na++;\n                int bi = b.first + di[d], bj = b.second + dj[d];\n                if (bi >= 0 && bi < N && bj >= 0 && bj < N) nb++;\n            }\n            if (na != nb) return na > nb;\n            return a < b;\n        });\n\n        // Greedy assignment with lookahead\n        for (auto [i, j] : cells) {\n            int best_seed = -1;\n            double best_score = -1e18;\n            \n            // Try each unused seed\n            for (int seed_idx : selected_indices) {\n                if (used[seed_idx]) continue;\n                \n                // Calculate score for placing this seed here\n                double score = seed_goodness[seed_idx];\n                int neighbor_count = 0;\n                \n                // Consider existing neighbors\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor = grid[ni][nj];\n                        double pair_score = pair_potential(seed_idx, neighbor);\n                        score += pair_score;\n                        neighbor_count++;\n                    }\n                }\n                \n                // If no neighbors, use the seed's own potential\n                if (neighbor_count == 0) {\n                    score += seed_goodness[seed_idx];\n                }\n                \n                // Add small exploration factor that decreases over time\n                double exploration = max(0.0, 1.0 - (double)t / T) * 5.0;\n                score += exploration * (rng() % 100);\n                \n                // Penalty for seeds that are too similar to existing neighbors\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d], nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                        int neighbor = grid[ni][nj];\n                        // Calculate similarity (lower is better)\n                        double similarity = 0;\n                        for (int l = 0; l < M; l++) {\n                            similarity += abs(seeds[seed_idx][l] - seeds[neighbor][l]);\n                        }\n                        score -= similarity * 0.01; // Small penalty for similarity\n                    }\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_seed = seed_idx;\n                }\n            }\n            \n            if (best_seed != -1) {\n                grid[i][j] = best_seed;\n                used[best_seed] = true;\n            }\n        }\n\n        // 3. OUTPUT\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[i][j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // 4. READ NEW SEEDS\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n            }\n        }\n        \n        // 5. ADAPTIVE STRATEGY\n        // Check if we're making progress\n        int current_max = 0;\n        for (int i = 0; i < seed_count; i++) {\n            int sum = 0;\n            for (int l = 0; l < M; l++) sum += seeds[i][l];\n            current_max = max(current_max, sum);\n        }\n        \n        // If we're close to target, we can adjust parameters for more aggressive optimization\n        if (current_max > target_sum * 0.9) {\n            // Increase exploration in future iterations\n            // This is handled implicitly by the decreasing exploration factor\n        }\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <queue>\n#include <map>\n#include <set>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n};\n\nint manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nPoint get_grab_pos(Point s, char dir, int d) {\n    if (dir == 'R') return Point(s.x - d, s.y);\n    if (dir == 'L') return Point(s.x + d, s.y);\n    if (dir == 'D') return Point(s.x, s.y - d);\n    if (dir == 'U') return Point(s.x, s.y + d);\n    return Point();\n}\n\nPoint get_release_pos(Point t, char dir, int d) {\n    if (dir == 'R') return Point(t.x - d, t.y);\n    if (dir == 'L') return Point(t.x + d, t.y);\n    if (dir == 'D') return Point(t.x, t.y - d);\n    if (dir == 'U') return Point(t.x, t.y + d);\n    return Point();\n}\n\nbool is_valid(Point p, int N) {\n    return p.x >= 0 && p.x < N && p.y >= 0 && p.y < N;\n}\n\nvector<char> get_path(Point from, Point to) {\n    vector<char> path;\n    int x = from.x;\n    int y = from.y;\n    while (x != to.x) {\n        if (x < to.x) {\n            path.push_back('R');\n            x++;\n        } else {\n            path.push_back('L');\n            x--;\n        }\n    }\n    while (y != to.y) {\n        if (y < to.y) {\n            path.push_back('D');\n            y++;\n        } else {\n            path.push_back('U');\n            y--;\n        }\n    }\n    return path;\n}\n\nstring create_turn(char movement, int leaf_index, char direction, bool grab, int V) {\n    string s(2 * V, '.');\n    s[0] = movement;\n    if (leaf_index != -1) {\n        s[leaf_index] = direction;\n        if (grab) {\n            s[V + leaf_index] = 'P';\n        }\n    }\n    return s;\n}\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n\n    vector<string> S(N), T(N);\n    for (int i = 0; i < N; i++) cin >> S[i];\n    for (int i = 0; i < N; i++) cin >> T[i];\n\n    vector<Point> initial_positions;\n    vector<Point> target_positions;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (S[i][j] == '1') initial_positions.push_back(Point(i, j));\n            if (T[i][j] == '1') target_positions.push_back(Point(i, j));\n        }\n    }\n\n    vector<pair<Point, Point>> pairs;\n    vector<bool> assigned(M, false);\n\n    for (int i = 0; i < M; i++) {\n        Point s = initial_positions[i];\n        int best_j = -1;\n        int best_dist = 1e9;\n        for (int j = 0; j < M; j++) {\n            if (assigned[j]) continue;\n            int dist = manhattan(s, target_positions[j]);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_j = j;\n            }\n        }\n        assigned[best_j] = true;\n        pairs.push_back({s, target_positions[best_j]});\n    }\n\n    Point current_root(N / 2, N / 2);\n    vector<string> turns;\n\n    vector<pair<Point, Point>> remaining = pairs;\n\n    while (!remaining.empty()) {\n        int best_cost = 1e9;\n        int best_index = -1;\n        int best_leaf = -1;\n        char best_grab_dir = ' ';\n        char best_release_dir = ' ';\n        Point best_grab_pos, best_release_pos;\n\n        for (int i = 0; i < remaining.size(); i++) {\n            Point s = remaining[i].first;\n            Point t = remaining[i].second;\n            for (int leaf = 1; leaf < V; leaf++) {\n                int d = leaf;\n                for (char grab_dir : {'L', 'R', 'U', 'D'}) {\n                    Point grab_pos = get_grab_pos(s, grab_dir, d);\n                    if (!is_valid(grab_pos, N)) continue;\n                    for (char release_dir : {'L', 'R', 'U', 'D'}) {\n                        Point release_pos = get_release_pos(t, release_dir, d);\n                        if (!is_valid(release_pos, N)) continue;\n                        int cost = manhattan(current_root, grab_pos) + manhattan(grab_pos, release_pos);\n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_index = i;\n                            best_leaf = leaf;\n                            best_grab_dir = grab_dir;\n                            best_release_dir = release_dir;\n                            best_grab_pos = grab_pos;\n                            best_release_pos = release_pos;\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_index == -1) {\n            break;\n        }\n\n        vector<char> path1 = get_path(current_root, best_grab_pos);\n        if (path1.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_grab_dir, true, V));\n        } else {\n            for (int j = 0; j < path1.size(); j++) {\n                bool grab = (j == path1.size() - 1);\n                turns.push_back(create_turn(path1[j], best_leaf, best_grab_dir, grab, V));\n            }\n        }\n        current_root = best_grab_pos;\n\n        vector<char> path2 = get_path(best_grab_pos, best_release_pos);\n        if (path2.empty()) {\n            turns.push_back(create_turn('.', best_leaf, best_release_dir, true, V));\n        } else {\n            for (int j = 0; j < path2.size(); j++) {\n                bool release = (j == path2.size() - 1);\n                turns.push_back(create_turn(path2[j], best_leaf, best_release_dir, release, V));\n            }\n        }\n        current_root = best_release_pos;\n\n        remaining.erase(remaining.begin() + best_index);\n    }\n\n    cout << V << endl;\n    for (int i = 1; i < V; i++) {\n        cout << 0 << \" \" << i << endl;\n    }\n    cout << N/2 << \" \" << N/2 << endl;\n\n    for (const string& turn : turns) {\n        cout << turn << endl;\n    }\n\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <map>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct Point {\n    int x, y, weight;\n};\n\nclass SegmentTree {\npublic:\n    int n;\n    vector<int> sum;\n    vector<int> max_prefix;\n    vector<int> max_suffix;\n    vector<int> max_sum;\n\n    SegmentTree(int size) {\n        n = size;\n        sum.resize(4 * n, 0);\n        max_prefix.resize(4 * n, 0);\n        max_suffix.resize(4 * n, 0);\n        max_sum.resize(4 * n, 0);\n    }\n\n    void update(int idx, int val, int node = 1, int left = 0, int right = -1) {\n        if (right == -1) right = n - 1;\n        if (left == right) {\n            sum[node] += val;\n            max_prefix[node] = sum[node];\n            max_suffix[node] = sum[node];\n            max_sum[node] = sum[node];\n            return;\n        }\n        int mid = (left + right) / 2;\n        if (idx <= mid) {\n            update(idx, val, 2 * node, left, mid);\n        } else {\n            update(idx, val, 2 * node + 1, mid + 1, right);\n        }\n        sum[node] = sum[2 * node] + sum[2 * node + 1];\n        max_prefix[node] = max(max_prefix[2 * node], sum[2 * node] + max_prefix[2 * node + 1]);\n        max_suffix[node] = max(max_suffix[2 * node + 1], sum[2 * node + 1] + max_suffix[2 * node]);\n        max_sum[node] = max({max_sum[2 * node], max_sum[2 * node + 1], max_suffix[2 * node] + max_prefix[2 * node + 1]});\n    }\n\n    int query() {\n        return max_sum[1];\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    srand(time(0));\n\n    int N;\n    cin >> N;\n    vector<Point> points;\n    vector<Point> mackerels;\n    vector<Point> sardines;\n    set<pair<int, int>> point_set;\n    \n    for (int i = 0; i < 2 * N; i++) {\n        int x, y;\n        cin >> x >> y;\n        points.push_back({x, y, 0});\n        point_set.insert({x, y});\n    }\n\n    for (int i = 0; i < N; i++) {\n        points[i].weight = 1;\n        mackerels.push_back(points[i]);\n    }\n    for (int i = N; i < 2 * N; i++) {\n        points[i].weight = -1;\n        sardines.push_back(points[i]);\n    }\n\n    // Sort mackerels and sardines by x-coordinate\n    sort(mackerels.begin(), mackerels.end(), [](const Point& a, const Point& b) {\n        return a.x < b.x;\n    });\n    sort(sardines.begin(), sardines.end(), [](const Point& a, const Point& b) {\n        return a.x < b.x;\n    });\n\n    // Get unique x-coordinates and sort\n    set<int> x_set;\n    for (auto& p : points) {\n        x_set.insert(p.x);\n    }\n    vector<int> unique_x(x_set.begin(), x_set.end());\n    sort(unique_x.begin(), unique_x.end());\n    int total_x = unique_x.size();\n\n    // Group points by x\n    map<int, vector<Point>> points_by_x;\n    for (auto& p : points) {\n        points_by_x[p.x].push_back(p);\n    }\n\n    // Get unique y-coordinates and mapping\n    set<int> y_set;\n    for (auto& p : points) {\n        y_set.insert(p.y);\n    }\n    vector<int> unique_y(y_set.begin(), y_set.end());\n    sort(unique_y.begin(), unique_y.end());\n    map<int, int> y_to_idx;\n    for (int i = 0; i < unique_y.size(); i++) {\n        y_to_idx[unique_y[i]] = i;\n    }\n    int m = unique_y.size();\n\n    // Select candidate x1: top 100 mackerels, top 100 sardines, and 50 evenly spaced\n    vector<int> candidate_x1;\n    \n    // Add top 100 mackerels by x\n    int num_mack = min(100, (int)mackerels.size());\n    for (int i = 0; i < num_mack; i++) {\n        candidate_x1.push_back(mackerels[i].x);\n    }\n    \n    // Add top 100 sardines by x\n    int num_sar = min(100, (int)sardines.size());\n    for (int i = 0; i < num_sar; i++) {\n        candidate_x1.push_back(sardines[i].x);\n    }\n    \n    // Add 50 evenly spaced points from unique_x\n    for (int i = 1; i <= 50; i++) {\n        int idx = total_x * i / 51;\n        if (idx < total_x) {\n            candidate_x1.push_back(unique_x[idx]);\n        }\n    }\n    \n    // Also add first 100 and last 100 unique x-coordinates\n    int num_take = min(100, total_x);\n    for (int i = 0; i < num_take; i++) {\n        candidate_x1.push_back(unique_x[i]);\n    }\n    for (int i = max(0, total_x - num_take); i < total_x; i++) {\n        candidate_x1.push_back(unique_x[i]);\n    }\n    \n    sort(candidate_x1.begin(), candidate_x1.end());\n    candidate_x1.erase(unique(candidate_x1.begin(), candidate_x1.end()), candidate_x1.end());\n\n    int best_score = -1e9;\n    int best_x1 = 0, best_x2 = 0;\n\n    for (int x1 : candidate_x1) {\n        SegmentTree seg(m);\n        for (int x2 : unique_x) {\n            if (x2 < x1) continue;\n            for (auto& p : points_by_x[x2]) {\n                int idx = y_to_idx[p.y];\n                seg.update(idx, p.weight);\n            }\n            int current_score = seg.query();\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_x1 = x1;\n                best_x2 = x2;\n            }\n        }\n    }\n\n    if (best_score < 0) {\n        while (true) {\n            int x = rand() % 100000;\n            int y = rand() % 100000;\n            if (point_set.find({x, y}) == point_set.end() &&\n                point_set.find({x, y+1}) == point_set.end() &&\n                point_set.find({x+1, y}) == point_set.end() &&\n                point_set.find({x+1, y+1}) == point_set.end()) {\n                cout << 4 << endl;\n                cout << x << \" \" << y << endl;\n                cout << x << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y+1 << endl;\n                cout << x+1 << \" \" << y << endl;\n                break;\n            }\n        }\n    } else {\n        vector<int> y_weights(m, 0);\n        for (int x = best_x1; x <= best_x2; x++) {\n            if (points_by_x.find(x) != points_by_x.end()) {\n                for (auto& p : points_by_x[x]) {\n                    int idx = y_to_idx[p.y];\n                    y_weights[idx] += p.weight;\n                }\n            }\n        }\n\n        int best_sum = 0;\n        int current_sum = 0;\n        int best_start = 0, best_end = 0;\n        int current_start = 0;\n\n        for (int i = 0; i < m; i++) {\n            current_sum += y_weights[i];\n            if (current_sum > best_sum) {\n                best_sum = current_sum;\n                best_start = current_start;\n                best_end = i;\n            }\n            if (current_sum < 0) {\n                current_sum = 0;\n                current_start = i + 1;\n            }\n        }\n\n        if (best_sum <= 0) {\n            while (true) {\n                int x = rand() % 100000;\n                int y = rand() % 100000;\n                if (point_set.find({x, y}) == point_set.end() &&\n                    point_set.find({x, y+1}) == point_set.end() &&\n                    point_set.find({x+1, y}) == point_set.end() &&\n                    point_set.find({x+1, y+1}) == point_set.end()) {\n                    cout << 4 << endl;\n                    cout << x << \" \" << y << endl;\n                    cout << x << \" \" << y+1 << endl;\n                    cout << x+1 << \" \" << y+1 << endl;\n                    cout << x+1 << \" \" << y << endl;\n                    break;\n                }\n            }\n        } else {\n            int y1 = unique_y[best_start];\n            int y2 = unique_y[best_end];\n            cout << 4 << endl;\n            cout << best_x1 << \" \" << y1 << endl;\n            cout << best_x1 << \" \" << y2 << endl;\n            cout << best_x2 << \" \" << y2 << endl;\n            cout << best_x2 << \" \" << y1 << endl;\n        }\n    }\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Rectangle {\n    int id;\n    double w_est, h_est;\n    double w_var, h_var;\n    double w_obs, h_obs;\n};\n\nstruct Placement {\n    int id;\n    int rotated;\n    char direction;\n    int reference;\n};\n\nstruct PlacedRect {\n    int id;\n    double x, y, w, h;\n};\n\nclass EnhancedPacker {\nprivate:\n    vector<Rectangle> rects;\n    double sigma;\n    int N, T;\n    mt19937 rng;\n    \n    // Improved Bayesian estimation\n    void updateEstimates(int turn, double W_meas, double H_meas, const vector<Placement>& placement) {\n        if (placement.empty()) return;\n        \n        // Calculate expected vs measured\n        double exp_W = 0, exp_H = 0;\n        vector<PlacedRect> simulated;\n        fastSimulate(placement, simulated, exp_W, exp_H);\n        \n        if (exp_W < 1e-6 || exp_H < 1e-6) return;\n        \n        double err_W = W_meas - exp_W;\n        double err_H = H_meas - exp_H;\n        \n        // Only update if error is significant (more than 1 sigma)\n        if (abs(err_W) < sigma && abs(err_H) < sigma) return;\n        \n        // Update each rectangle proportionally to its contribution\n        for (const auto& p : placement) {\n            Rectangle& rect = rects[p.id];\n            \n            // Expected contribution of this rectangle to dimensions\n            double rect_w = p.rotated ? rect.h_est : rect.w_est;\n            double rect_h = p.rotated ? rect.w_est : rect.h_est;\n            \n            // Simple scaling factor based on error direction\n            double w_factor = 1.0, h_factor = 1.0;\n            if (err_W > 0) w_factor += 0.02 * (rect_w / exp_W);\n            if (err_H > 0) h_factor += 0.02 * (rect_h / exp_H);\n            \n            // Damped update with variance-aware damping\n            double damping = 0.05 / (1.0 + (rect.w_var + rect.h_var) / (sigma * sigma));\n            rect.w_est = rect.w_est * (1 - damping) + rect.w_est * w_factor * damping;\n            rect.h_est = rect.h_est * (1 - damping) + rect.h_est * h_factor * damping;\n            \n            // Update variance (simplified Kalman update)\n            double meas_var = sigma * sigma;\n            rect.w_var = 1.0 / (1.0 / rect.w_var + 1.0 / meas_var);\n            rect.h_var = 1.0 / (1.0 / rect.h_var + 1.0 / meas_var);\n            \n            // Clamp\n            rect.w_est = max(1.0, min(1e9, rect.w_est));\n            rect.h_est = max(1.0, min(1e9, rect.h_est));\n        }\n    }\n    \n    // Fast simulation with simplified overlap check\n    void fastSimulate(const vector<Placement>& placement, vector<PlacedRect>& placed, double& W, double& H) {\n        placed.clear();\n        W = 0; H = 0;\n        \n        for (const auto& p : placement) {\n            const Rectangle& rect = rects[p.id];\n            double w = p.rotated ? rect.h_est : rect.w_est;\n            double h = p.rotated ? rect.w_est : rect.h_est;\n            \n            double x = 0, y = 0;\n            \n            if (p.direction == 'U') {\n                if (p.reference != -1) {\n                    for (const auto& r : placed) {\n                        if (r.id == p.reference) { x = r.x + r.w; break; }\n                    }\n                }\n                // Find highest y that doesn't cause overlap\n                y = 0;\n                for (const auto& r : placed) {\n                    if (x < r.x + r.w && x + w > r.x) {\n                        y = max(y, r.y + r.h);\n                    }\n                }\n            } else {\n                if (p.reference != -1) {\n                    for (const auto& r : placed) {\n                        if (r.id == p.reference) { y = r.y + r.h; break; }\n                    }\n                }\n                // Find leftmost x that doesn't cause overlap\n                x = 0;\n                for (const auto& r : placed) {\n                    if (y < r.y + r.h && y + h > r.y) {\n                        x = max(x, r.x + r.w);\n                    }\n                }\n            }\n            \n            placed.push_back({p.id, x, y, w, h});\n            W = max(W, x + w);\n            H = max(H, y + h);\n        }\n    }\n    \n    // Enhanced greedy construction\n    vector<Placement> constructSolution(int turn) {\n        vector<Placement> solution;\n        solution.reserve(N);\n        \n        // Precompute suffix sum for penalty\n        vector<double> suffix_sum(N + 1, 0);\n        for (int i = N - 1; i >= 0; i--) {\n            suffix_sum[i] = suffix_sum[i + 1] + rects[i].w_est + rects[i].h_est;\n        }\n        \n        // Strategy selection based on turn\n        bool aggressive = (turn < T / 3);\n        bool thorough = (turn > T * 2 / 3);\n        \n        for (int i = 0; i < N; i++) {\n            const Rectangle& rect = rects[i];\n            double best_score = 1e18;\n            Placement best_placement;\n            bool found = false;\n            \n            // Try multiple configurations\n            for (int rot = 0; rot < 2; rot++) {\n                for (char dir : {'U', 'L'}) {\n                    // Try reference to -1 and to last placed\n                    vector<int> refs = {-1};\n                    if (!solution.empty()) {\n                        refs.push_back(solution.back().id);\n                        // Try a random previous rectangle for variety\n                        if (turn > 5) {\n                            refs.push_back(solution[rng() % solution.size()].id);\n                        }\n                    }\n                    \n                    for (int ref : refs) {\n                        Placement candidate = {i, rot, dir, ref};\n                        \n                        // Quick evaluation\n                        vector<Placement> temp = solution;\n                        temp.push_back(candidate);\n                        \n                        double new_W, new_H;\n                        vector<PlacedRect> new_placed;\n                        fastSimulate(temp, new_placed, new_W, new_H);\n                        \n                        double current_W = 0, current_H = 0;\n                        if (!solution.empty()) {\n                            vector<PlacedRect> cur_placed;\n                            fastSimulate(solution, cur_placed, current_W, current_H);\n                        }\n                        \n                        double current_score = current_W + current_H + suffix_sum[i];\n                        double new_score = new_W + new_H + suffix_sum[i + 1];\n                        \n                        // Score with bonus for early turns or small improvement\n                        double score = new_score;\n                        if (aggressive) score *= 0.95; // Favor inclusion in early turns\n                        if (thorough) score *= 1.02; // Be more selective in late turns\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            best_placement = candidate;\n                            found = true;\n                        }\n                    }\n                }\n            }\n            \n            // Decision to include\n            double current_W = 0, current_H = 0;\n            if (!solution.empty()) {\n                vector<PlacedRect> cur_placed;\n                fastSimulate(solution, cur_placed, current_W, current_H);\n            }\n            double current_total = current_W + current_H + suffix_sum[i];\n            double new_total = best_score;\n            \n            // Include if beneficial, or if we need more rectangles\n            bool should_include = found && (\n                new_total <= current_total * (aggressive ? 1.1 : 1.01) ||\n                (solution.size() < max(3, N / 4) && aggressive) ||\n                (i < 5)\n            );\n            \n            if (should_include) {\n                solution.push_back(best_placement);\n            }\n        }\n        \n        return solution;\n    }\n    \n    vector<Placement> validateOutput(vector<Placement> solution) {\n        if (solution.empty()) return solution;\n        \n        // Ensure ascending order\n        sort(solution.begin(), solution.end(), [](const Placement& a, const Placement& b) {\n            return a.id < b.id;\n        });\n        \n        // Remove duplicates\n        vector<Placement> unique;\n        vector<bool> seen(N, false);\n        for (const auto& p : solution) {\n            if (!seen[p.id]) {\n                unique.push_back(p);\n                seen[p.id] = true;\n            }\n        }\n        \n        // Fix references\n        for (size_t i = 0; i < unique.size(); i++) {\n            if (unique[i].reference != -1) {\n                bool found = false;\n                for (size_t j = 0; j < i; j++) {\n                    if (unique[j].id == unique[i].reference) {\n                        found = true; break;\n                    }\n                }\n                if (!found) unique[i].reference = -1;\n            }\n        }\n        \n        return unique;\n    }\n\npublic:\n    EnhancedPacker(int n, int t, double s, const vector<pair<double, double>>& observed) \n        : N(n), T(t), sigma(s), rng(12345 + n * 13) {\n        rects.resize(N);\n        for (int i = 0; i < N; i++) {\n            rects[i].id = i;\n            rects[i].w_obs = observed[i].first;\n            rects[i].h_obs = observed[i].second;\n            // Initialize with observed values plus small noise\n            normal_distribution<double> dist(0, sigma * 0.02);\n            rects[i].w_est = observed[i].first + dist(rng);\n            rects[i].h_est = observed[i].second + dist(rng);\n            rects[i].w_var = sigma * sigma;\n            rects[i].h_var = sigma * sigma;\n            \n            rects[i].w_est = max(1.0, min(1e9, rects[i].w_est));\n            rects[i].h_est = max(1.0, min(1e9, rects[i].h_est));\n        }\n    }\n    \n    vector<Placement> solve(int turn, double W_meas, double H_meas, const vector<Placement>& last_placement) {\n        if (turn > 0) {\n            updateEstimates(turn, W_meas, H_meas, last_placement);\n        }\n        \n        vector<Placement> solution = constructSolution(turn);\n        solution = validateOutput(solution);\n        \n        // Fallback to simple packing if empty\n        if (solution.empty()) {\n            for (int i = 0; i < N; i++) {\n                solution.push_back({i, 0, 'U', (i == 0) ? -1 : i - 1});\n            }\n        }\n        \n        return solution;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, T;\n    double sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<double, double>> observed(N);\n    for (int i = 0; i < N; i++) {\n        cin >> observed[i].first >> observed[i].second;\n    }\n    \n    EnhancedPacker packer(N, T, sigma, observed);\n    \n    vector<Placement> last_placement;\n    \n    for (int turn = 0; turn < T; turn++) {\n        double W_meas = 0, H_meas = 0;\n        if (turn > 0) cin >> W_meas >> H_meas;\n        \n        vector<Placement> placement = packer.solve(turn, W_meas, H_meas, last_placement);\n        \n        cout << placement.size() << \"\\n\";\n        for (const auto& p : placement) {\n            cout << p.id << \" \" << p.rotated << \" \" << p.direction << \" \" << p.reference << \"\\n\";\n        }\n        cout.flush();\n        \n        last_placement = placement;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int N, M, H;\n    vector<int> A;\n    vector<vector<int>> adj;\n    vector<pair<int, int>> coords;\n    vector<int> order_desc, order_asc;\n\n    void read_input() {\n        cin >> N >> M >> H;\n        A.resize(N);\n        for (int i = 0; i < N; ++i) cin >> A[i];\n        adj.assign(N, {});\n        for (int i = 0; i < M; ++i) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        coords.resize(N);\n        for (int i = 0; i < N; ++i) {\n            cin >> coords[i].first >> coords[i].second;\n        }\n\n        // Initialize orders\n        order_desc.resize(N);\n        iota(order_desc.begin(), order_desc.end(), 0);\n        sort(order_desc.begin(), order_desc.end(), [&](int a, int b) { return A[a] > A[b]; });\n        \n        order_asc = order_desc;\n        reverse(order_asc.begin(), order_asc.end());\n    }\n\n    vector<int> solve() {\n        vector<int> best_parent;\n        long long best_score = -1;\n        \n        // Strategy 1: K-root BFS with expanded K values\n        for (int K : {1, 2, 3, 5, 7, 10, 15}) {\n            auto parent = build_k_root_bfs(K);\n            improve_safe(parent);\n            long long score = compute_score(parent);\n            if (score > best_score) {\n                best_score = score;\n                best_parent = parent;\n            }\n        }\n        \n        // Strategy 2: K-root spatial BFS with expanded K values\n        for (int K : {1, 2, 3, 5, 7, 10}) {\n            auto parent = build_spatial_bfs(K);\n            improve_safe(parent);\n            long long score = compute_score(parent);\n            if (score > best_score) {\n                best_score = score;\n                best_parent = parent;\n            }\n        }\n        \n        // Strategy 3: Pure spatial construction\n        {\n            auto parent = build_pure_spatial();\n            improve_safe(parent);\n            long long score = compute_score(parent);\n            if (score > best_score) {\n                best_score = score;\n                best_parent = parent;\n            }\n        }\n        \n        // Strategy 4: Greedy strategies\n        for (const auto& order : {order_desc, order_asc}) {\n            auto parent = build_greedy(order);\n            improve_safe(parent);\n            long long score = compute_score(parent);\n            if (score > best_score) {\n                best_score = score;\n                best_parent = parent;\n            }\n        }\n        \n        // Strategy 5: Degree-weighted with variations\n        for (double weight : {0.5, 0.7, 1.0, 1.3, 1.5}) {\n            auto parent = build_degree_weighted(weight);\n            improve_safe(parent);\n            long long score = compute_score(parent);\n            if (score > best_score) {\n                best_score = score;\n                best_parent = parent;\n            }\n        }\n        \n        return best_parent;\n    }\n\n    vector<int> build_k_root_bfs(int K) {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        vector<int> depth(N, 0);\n        \n        K = min(K, N);\n        for (int i = 0; i < K; ++i) {\n            int root = order_desc[i];\n            if (assigned[root]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({root, 0});\n            assigned[root] = true;\n            depth[root] = 0;\n            parent[root] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<int> neighbors = adj[u];\n                sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                    return A[a] > A[b];\n                });\n                \n                for (int w : neighbors) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        depth[w] = d + 1;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Cover any remaining vertices\n        for (int v : order_desc) {\n            if (assigned[v]) continue;\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            depth[v] = 0;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        depth[w] = d + 1;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_spatial_bfs(int K) {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        vector<int> depth(N, 0);\n        \n        K = min(K, N);\n        for (int i = 0; i < K; ++i) {\n            int root = order_desc[i];\n            if (assigned[root]) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({root, 0});\n            assigned[root] = true;\n            depth[root] = 0;\n            parent[root] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                vector<pair<double, int>> neighbors_with_score;\n                for (int w : adj[u]) {\n                    if (assigned[w]) continue;\n                    int dx = coords[u].first - coords[w].first;\n                    int dy = coords[u].second - coords[w].second;\n                    double dist = sqrt(dx*dx + dy*dy);\n                    double score = A[w] / (dist + 1.0);\n                    neighbors_with_score.push_back({score, w});\n                }\n                sort(neighbors_with_score.begin(), neighbors_with_score.end(), \n                     [](const pair<double, int>& a, const pair<double, int>& b) {\n                         return a.first > b.first;\n                     });\n                \n                for (auto [score, w] : neighbors_with_score) {\n                    assigned[w] = true;\n                    parent[w] = u;\n                    depth[w] = d + 1;\n                    if (d + 1 < H) {\n                        q.push({w, d + 1});\n                    }\n                }\n            }\n        }\n        \n        // Cover any remaining vertices\n        for (int v : order_desc) {\n            if (assigned[v]) continue;\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            depth[v] = 0;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        depth[w] = d + 1;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_pure_spatial() {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        vector<int> depth(N, 0);\n        \n        // Start from geometric center\n        int cx = 0, cy = 0;\n        for (int i = 0; i < N; ++i) {\n            cx += coords[i].first;\n            cy += coords[i].second;\n        }\n        cx /= N;\n        cy /= N;\n        \n        // Find closest vertex to center\n        int center = -1;\n        int min_dist = 1e9;\n        for (int i = 0; i < N; ++i) {\n            int dx = coords[i].first - cx;\n            int dy = coords[i].second - cy;\n            int dist = dx*dx + dy*dy;\n            if (dist < min_dist) {\n                min_dist = dist;\n                center = i;\n            }\n        }\n        \n        // BFS from center, prioritizing spatial proximity\n        queue<pair<int, int>> q;\n        q.push({center, 0});\n        assigned[center] = true;\n        depth[center] = 0;\n        parent[center] = -1;\n        \n        while (!q.empty()) {\n            auto [u, d] = q.front(); q.pop();\n            if (d >= H) continue;\n            \n            vector<pair<double, int>> neighbors_with_score;\n            for (int w : adj[u]) {\n                if (assigned[w]) continue;\n                int dx = coords[u].first - coords[w].first;\n                int dy = coords[u].second - coords[w].second;\n                double dist = sqrt(dx*dx + dy*dy);\n                double score = A[w] / (dist + 1.0);\n                neighbors_with_score.push_back({score, w});\n            }\n            sort(neighbors_with_score.begin(), neighbors_with_score.end(), \n                 [](const pair<double, int>& a, const pair<double, int>& b) {\n                     return a.first > b.first;\n                 });\n            \n            for (auto [score, w] : neighbors_with_score) {\n                assigned[w] = true;\n                parent[w] = u;\n                depth[w] = d + 1;\n                if (d + 1 < H) {\n                    q.push({w, d + 1});\n                }\n            }\n        }\n        \n        // Cover any remaining vertices\n        for (int v : order_desc) {\n            if (assigned[v]) continue;\n            queue<pair<int, int>> q;\n            q.push({v, 0});\n            assigned[v] = true;\n            depth[v] = 0;\n            parent[v] = -1;\n            \n            while (!q.empty()) {\n                auto [u, d] = q.front(); q.pop();\n                if (d >= H) continue;\n                \n                for (int w : adj[u]) {\n                    if (!assigned[w]) {\n                        assigned[w] = true;\n                        parent[w] = u;\n                        depth[w] = d + 1;\n                        if (d + 1 < H) {\n                            q.push({w, d + 1});\n                        }\n                    }\n                }\n            }\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_greedy(const vector<int>& order) {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        vector<int> depth(N, 0);\n        \n        for (int v : order) {\n            if (assigned[v]) continue;\n            \n            int best_u = -1;\n            int best_depth = -1;\n            \n            for (int u : adj[v]) {\n                if (assigned[u] && depth[u] < H) {\n                    if (depth[u] > best_depth) {\n                        best_depth = depth[u];\n                        best_u = u;\n                    }\n                }\n            }\n            \n            if (best_u != -1) {\n                parent[v] = best_u;\n                depth[v] = best_depth + 1;\n            } else {\n                parent[v] = -1;\n                depth[v] = 0;\n            }\n            assigned[v] = true;\n        }\n        \n        return parent;\n    }\n\n    vector<int> build_degree_weighted(double weight) {\n        vector<int> parent(N, -1);\n        vector<bool> assigned(N, false);\n        vector<int> depth(N, 0);\n        \n        vector<int> vertices(N);\n        iota(vertices.begin(), vertices.end(), 0);\n        sort(vertices.begin(), vertices.end(), [&](int a, int b) {\n            double score_a = (double)A[a] / (adj[a].size() + 1) * weight;\n            double score_b = (double)A[b] / (adj[b].size() + 1) * weight;\n            return score_a > score_b;\n        });\n        \n        for (int v : vertices) {\n            if (assigned[v]) continue;\n            \n            int best_u = -1;\n            int best_depth = -1;\n            \n            for (int u : adj[v]) {\n                if (assigned[u] && depth[u] < H) {\n                    if (depth[u] > best_depth) {\n                        best_depth = depth[u];\n                        best_u = u;\n                    }\n                }\n            }\n            \n            if (best_u != -1) {\n                parent[v] = best_u;\n                depth[v] = best_depth + 1;\n            } else {\n                parent[v] = -1;\n                depth[v] = 0;\n            }\n            assigned[v] = true;\n        }\n        \n        return parent;\n    }\n\n    void improve_safe(vector<int>& parent) {\n        const int MAX_ITER = 200;\n        bool changed = true;\n        int iter = 0;\n        \n        while (changed && iter < MAX_ITER) {\n            changed = false;\n            iter++;\n            \n            // Build tree structure\n            vector<int> depth(N, 0);\n            vector<vector<int>> children(N);\n            for (int v = 0; v < N; ++v) {\n                if (parent[v] != -1) {\n                    children[parent[v]].push_back(v);\n                }\n            }\n            \n            // Compute depth\n            function<void(int)> compute_depth = [&](int v) {\n                for (int c : children[v]) {\n                    depth[c] = depth[v] + 1;\n                    compute_depth(c);\n                }\n            };\n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) {\n                    depth[v] = 0;\n                    compute_depth(v);\n                }\n            }\n            \n            // Compute subtree info with preorder/postorder\n            vector<int> subtree_sum(N, 0);\n            vector<int> max_depth(N, 0);\n            vector<int> preorder(N), postorder(N);\n            int timer = 0;\n            \n            function<void(int)> dfs = [&](int v) {\n                preorder[v] = timer++;\n                subtree_sum[v] = A[v];\n                max_depth[v] = 0;\n                for (int c : children[v]) {\n                    dfs(c);\n                    subtree_sum[v] += subtree_sum[c];\n                    max_depth[v] = max(max_depth[v], max_depth[c] + 1);\n                }\n                postorder[v] = timer - 1;\n            };\n            \n            for (int v = 0; v < N; ++v) {\n                if (parent[v] == -1) {\n                    dfs(v);\n                }\n            }\n            \n            // Find best move\n            int best_v = -1, best_u = -1;\n            long long best_gain = 0;\n            \n            for (int v : order_desc) {\n                if (parent[v] == -1) continue;\n                \n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    \n                    // O(1) cycle check\n                    if (preorder[v] <= preorder[u] && preorder[u] <= postorder[v]) {\n                        continue;\n                    }\n                    \n                    int new_depth = depth[u] + 1;\n                    if (new_depth > H) continue;\n                    if (new_depth + max_depth[v] > H) continue;\n                    \n                    int delta = new_depth - depth[v];\n                    if (delta <= 0) continue;\n                    \n                    long long gain = (long long)delta * subtree_sum[v];\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_v = v;\n                        best_u = u;\n                    }\n                }\n            }\n            \n            if (best_v != -1) {\n                parent[best_v] = best_u;\n                changed = true;\n            }\n        }\n    }\n\n    long long compute_score(const vector<int>& parent) {\n        vector<int> depth(N, 0);\n        vector<vector<int>> children(N);\n        \n        for (int v = 0; v < N; ++v) {\n            if (parent[v] != -1) {\n                children[parent[v]].push_back(v);\n            }\n        }\n        \n        function<void(int)> compute_depth = [&](int v) {\n            for (int c : children[v]) {\n                depth[c] = depth[v] + 1;\n                compute_depth(c);\n            }\n        };\n        \n        for (int v = 0; v < N; ++v) {\n            if (parent[v] == -1) {\n                depth[v] = 0;\n                compute_depth(v);\n            }\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; ++v) {\n            score += (long long)(depth[v] + 1) * A[v];\n        }\n        return score;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver solver;\n    solver.read_input();\n    vector<int> result = solver.solve();\n\n    for (int i = 0; i < (int)result.size(); ++i) {\n        if (i > 0) cout << ' ';\n        cout << result[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>> operations;\n    const int MAX_OPERATIONS = 4 * N * N;\n\n    while (operations.size() < MAX_OPERATIONS) {\n        bool hasOni = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'x') {\n                    hasOni = true;\n                    break;\n                }\n            }\n            if (hasOni) break;\n        }\n        if (!hasOni) break;\n\n        bool removed = false;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == 'x') {\n                operations.push_back({'L', i});\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[i][N-1] == 'x') {\n                operations.push_back({'R', i});\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == 'x') {\n                operations.push_back({'U', j});\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n                removed = true;\n                break;\n            }\n            else if (board[N-1][j] == 'x') {\n                operations.push_back({'D', j});\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n                removed = true;\n                break;\n            }\n        }\n        if (removed) continue;\n\n        int best_dist = 1000000;\n        char best_dir = 0;\n        int best_index = -1;\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][0] == '.') {\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        if (j < best_dist) {\n                            best_dist = j;\n                            best_dir = 'L';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (board[i][N-1] == '.') {\n                for (int j = N-1; j >= 0; j--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - j;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'R';\n                            best_index = i;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[0][j] == '.') {\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        if (i < best_dist) {\n                            best_dist = i;\n                            best_dir = 'U';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int j = 0; j < N; j++) {\n            if (board[N-1][j] == '.') {\n                for (int i = N-1; i >= 0; i--) {\n                    if (board[i][j] == 'x') {\n                        int dist = N - 1 - i;\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_dir = 'D';\n                            best_index = j;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (best_index != -1) {\n            operations.push_back({best_dir, best_index});\n            if (best_dir == 'L') {\n                int i = best_index;\n                for (int j = 0; j < N-1; j++) {\n                    board[i][j] = board[i][j+1];\n                }\n                board[i][N-1] = '.';\n            } else if (best_dir == 'R') {\n                int i = best_index;\n                for (int j = N-2; j >= 0; j--) {\n                    board[i][j+1] = board[i][j];\n                }\n                board[i][0] = '.';\n            } else if (best_dir == 'U') {\n                int j = best_index;\n                for (int i = 0; i < N-1; i++) {\n                    board[i][j] = board[i+1][j];\n                }\n                board[N-1][j] = '.';\n            } else if (best_dir == 'D') {\n                int j = best_index;\n                for (int i = N-2; i >= 0; i--) {\n                    board[i+1][j] = board[i][j];\n                }\n                board[0][j] = '.';\n            }\n        } else {\n            break;\n        }\n    }\n\n    for (auto op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\nusing namespace std;\n\nint main() {\n    int N, L;\n    cin >> N >> L;\n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    // Identify employees with significantly high targets\n    vector<int> high_targets;\n    for (int i = 0; i < N; i++) {\n        if (T[i] > 6000) {\n            high_targets.push_back(i);\n        }\n    }\n\n    // Start with the simple cyclic assignment\n    vector<pair<int, int>> assignments(N);\n    for (int i = 0; i < N; i++) {\n        assignments[i] = {(i + 1) % N, (i + 2) % N};\n    }\n\n    // For high-target employees, modify the second transition to point to another high-target employee\n    // This creates a \"shortcut\" that increases their visit frequency\n    if (high_targets.size() >= 2) {\n        for (int i = 0; i < high_targets.size(); i++) {\n            int emp = high_targets[i];\n            int other = high_targets[(i + 1) % high_targets.size()];\n            assignments[emp].second = other;\n        }\n    }\n\n    // Output the assignments\n    for (int i = 0; i < N; i++) {\n        cout << assignments[i].first << \" \" << assignments[i].second << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cmath>\n\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<int> cx, cy, wx, hy;\nint queries_used = 0;\n\nvector<pair<int, int>> do_query(vector<int> cities) {\n    sort(cities.begin(), cities.end());\n    cout << \"? \" << cities.size();\n    for (int c : cities) {\n        cout << \" \" << c;\n    }\n    cout << endl;\n    vector<pair<int, int>> edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.push_back(make_pair(a, b));\n    }\n    queries_used++;\n    return edges;\n}\n\nvector<pair<int, int>> build_tree(vector<int> cities) {\n    int n = cities.size();\n    if (n == 1) {\n        return {};\n    }\n    if (n == 2) {\n        return {make_pair(cities[0], cities[1])};\n    }\n    if (n <= L) {\n        if (queries_used < Q) {\n            return do_query(cities);\n        } else {\n            vector<pair<int, int>> edges;\n            for (int i = 0; i < n - 1; i++) {\n                edges.push_back(make_pair(cities[i], cities[i + 1]));\n            }\n            return edges;\n        }\n    } else {\n        // Find the split point with the largest gap in spatial coordinates\n        int best_split = 0;\n        int max_gap = -1;\n        for (int i = 0; i < n - 1; i++) {\n            // Use Euclidean distance between centers for gap calculation\n            int dx = cx[cities[i+1]] - cx[cities[i]];\n            int dy = cy[cities[i+1]] - cy[cities[i]];\n            int gap = dx*dx + dy*dy;\n            if (gap > max_gap) {\n                max_gap = gap;\n                best_split = i;\n            }\n        }\n\n        // Ensure both halves have at least 2 cities\n        if (best_split < 1) best_split = 1;\n        if (n - best_split - 1 < 1) best_split = n - 2;\n\n        vector<int> A(cities.begin(), cities.begin() + best_split + 1);\n        vector<int> B(cities.begin() + best_split + 1, cities.end());\n\n        vector<pair<int, int>> treeA = build_tree(A);\n        vector<pair<int, int>> treeB = build_tree(B);\n\n        vector<pair<int, int>> edges_connect;\n        if (queries_used < Q) {\n            // Select cities from the boundary region\n            int k = min((int)A.size(), L / 2);\n            int l = L - k;\n            if (l > (int)B.size()) {\n                l = B.size();\n                k = L - l;\n            }\n            vector<int> S;\n            for (int i = A.size() - k; i < A.size(); i++) {\n                S.push_back(A[i]);\n            }\n            for (int i = 0; i < l; i++) {\n                S.push_back(B[i]);\n            }\n            vector<pair<int, int>> edges_S = do_query(S);\n            set<int> setA(A.begin(), A.end());\n            set<int> setB(B.begin(), B.end());\n            pair<int, int> connect_edge = make_pair(-1, -1);\n            for (auto& e : edges_S) {\n                int u = e.first, v = e.second;\n                if ((setA.count(u) && setB.count(v)) || (setA.count(v) && setB.count(u))) {\n                    connect_edge = e;\n                    break;\n                }\n            }\n            if (connect_edge.first == -1) {\n                // Find the closest pair between A and B\n                int best_u = A.back(), best_v = B[0];\n                int min_dist = 1e9;\n                for (int u : A) {\n                    for (int v : B) {\n                        int dx = cx[u] - cx[v];\n                        int dy = cy[u] - cy[v];\n                        int dist = dx*dx + dy*dy;\n                        if (dist < min_dist) {\n                            min_dist = dist;\n                            best_u = u;\n                            best_v = v;\n                        }\n                    }\n                }\n                connect_edge = make_pair(best_u, best_v);\n            }\n            edges_connect.push_back(connect_edge);\n        } else {\n            // No queries left, find the closest pair between A and B\n            int best_u = A.back(), best_v = B[0];\n            int min_dist = 1e9;\n            for (int u : A) {\n                for (int v : B) {\n                    int dx = cx[u] - cx[v];\n                    int dy = cy[u] - cy[v];\n                    int dist = dx*dx + dy*dy;\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_u = u;\n                        best_v = v;\n                    }\n                }\n            }\n            edges_connect.push_back(make_pair(best_u, best_v));\n        }\n\n        vector<pair<int, int>> result;\n        result.reserve(treeA.size() + treeB.size() + edges_connect.size());\n        result.insert(result.end(), treeA.begin(), treeA.end());\n        result.insert(result.end(), treeB.begin(), treeB.end());\n        result.insert(result.end(), edges_connect.begin(), edges_connect.end());\n        return result;\n    }\n}\n\nint main() {\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> G[i];\n    }\n    cx.resize(N);\n    cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        // Use weighted center: closer to the actual true coordinate\n        cx[i] = (lx + rx) / 2;\n        cy[i] = (ly + ry) / 2;\n    }\n\n    // Sort by (cx + cy) which worked best\n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        int di = cx[i] + cy[i];\n        int dj = cx[j] + cy[j];\n        if (di != dj) return di < dj;\n        if (cx[i] != cx[j]) return cx[i] < cx[j];\n        return cy[i] < cy[j];\n    });\n\n    // Split into groups\n    vector<vector<int>> groups(M);\n    int start = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i] = vector<int>(indices.begin() + start, indices.begin() + start + G[i]);\n        start += G[i];\n    }\n\n    // Build spanning trees for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    for (int i = 0; i < M; i++) {\n        group_edges[i] = build_tree(groups[i]);\n    }\n\n    // Output\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < groups[i].size(); j++) {\n            if (j) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <string>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets;\n    int r0, c0;\n    cin >> r0 >> c0;\n    for (int i = 0; i < M; i++) {\n        int r, c;\n        cin >> r >> c;\n        targets.push_back({r, c});\n    }\n\n    int r = r0, c = c0;\n    vector<string> actions;\n\n    for (int idx = 0; idx < M; idx++) {\n        int tr = targets[idx].first;\n        int tc = targets[idx].second;\n\n        while (r != tr || c != tc) {\n            int cost_manhattan = abs(r - tr) + abs(c - tc);\n            int best_cost = cost_manhattan;\n            vector<string> best_actions;\n\n            // Strategy 1: Slide to top boundary then move down\n            int cost_top = abs(c - tc) + 1 + tr;\n            if (cost_top < best_cost) {\n                best_cost = cost_top;\n                best_actions.clear();\n                if (c < tc) {\n                    for (int i = 0; i < tc - c; i++) best_actions.push_back(\"M R\");\n                } else if (c > tc) {\n                    for (int i = 0; i < c - tc; i++) best_actions.push_back(\"M L\");\n                }\n                best_actions.push_back(\"S U\");\n                for (int i = 0; i < tr; i++) best_actions.push_back(\"M D\");\n            }\n\n            // Strategy 2: Slide to bottom boundary then move up\n            int cost_bottom = abs(c - tc) + 1 + (N-1 - tr);\n            if (cost_bottom < best_cost) {\n                best_cost = cost_bottom;\n                best_actions.clear();\n                if (c < tc) {\n                    for (int i = 0; i < tc - c; i++) best_actions.push_back(\"M R\");\n                } else if (c > tc) {\n                    for (int i = 0; i < c - tc; i++) best_actions.push_back(\"M L\");\n                }\n                best_actions.push_back(\"S D\");\n                for (int i = 0; i < N-1 - tr; i++) best_actions.push_back(\"M U\");\n            }\n\n            // Strategy 3: Slide to left boundary then move right\n            int cost_left = abs(r - tr) + 1 + tc;\n            if (cost_left < best_cost) {\n                best_cost = cost_left;\n                best_actions.clear();\n                if (r < tr) {\n                    for (int i = 0; i < tr - r; i++) best_actions.push_back(\"M D\");\n                } else if (r > tr) {\n                    for (int i = 0; i < r - tr; i++) best_actions.push_back(\"M U\");\n                }\n                best_actions.push_back(\"S L\");\n                for (int i = 0; i < tc; i++) best_actions.push_back(\"M R\");\n            }\n\n            // Strategy 4: Slide to right boundary then move left\n            int cost_right = abs(r - tr) + 1 + (N-1 - tc);\n            if (cost_right < best_cost) {\n                best_cost = cost_right;\n                best_actions.clear();\n                if (r < tr) {\n                    for (int i = 0; i < tr - r; i++) best_actions.push_back(\"M D\");\n                } else if (r > tr) {\n                    for (int i = 0; i < r - tr; i++) best_actions.push_back(\"M U\");\n                }\n                best_actions.push_back(\"S R\");\n                for (int i = 0; i < N-1 - tc; i++) best_actions.push_back(\"M L\");\n            }\n\n            if (best_cost < cost_manhattan) {\n                for (const string& action : best_actions) {\n                    actions.push_back(action);\n                    if (action == \"M U\") r--;\n                    else if (action == \"M D\") r++;\n                    else if (action == \"M L\") c--;\n                    else if (action == \"M R\") c++;\n                    else if (action == \"S U\") r = 0;\n                    else if (action == \"S D\") r = N-1;\n                    else if (action == \"S L\") c = 0;\n                    else if (action == \"S R\") c = N-1;\n                }\n                continue;\n            }\n\n            // Step-by-step moves\n            int dr = tr - r;\n            int dc = tc - c;\n            int adr = abs(dr);\n            int adc = abs(dc);\n\n            if (adr > adc) {\n                if (dr > 0) {\n                    actions.push_back(\"M D\");\n                    r++;\n                } else {\n                    actions.push_back(\"M U\");\n                    r--;\n                }\n            } else if (adc > adr) {\n                if (dc > 0) {\n                    actions.push_back(\"M R\");\n                    c++;\n                } else {\n                    actions.push_back(\"M L\");\n                    c--;\n                }\n            } else {\n                if (tr == N-1 || tr == 0) {\n                    if (dr > 0) {\n                        actions.push_back(\"M D\");\n                        r++;\n                    } else if (dr < 0) {\n                        actions.push_back(\"M U\");\n                        r--;\n                    } else {\n                        if (dc > 0) {\n                            actions.push_back(\"M R\");\n                            c++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            c--;\n                        }\n                    }\n                } else if (tc == N-1 || tc == 0) {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else if (dc < 0) {\n                        actions.push_back(\"M L\");\n                        c--;\n                    } else {\n                        if (dr > 0) {\n                            actions.push_back(\"M D\");\n                            r++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            r--;\n                        }\n                    }\n                } else {\n                    if (dc > 0) {\n                        actions.push_back(\"M R\");\n                        c++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        c--;\n                    }\n                }\n            }\n        }\n    }\n\n    for (const string& action : actions) {\n        cout << action << endl;\n    }\n\n    return 0;\n}"}}}