{"model_name":"mimo-v2-pro","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <tuple>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nvector<Company> comps;\nvector<tuple<int, int, int, int>> ans;\n\nvoid rec(vector<int>& idx, int x_min, int x_max, int y_min, int y_max) {\n    if (idx.empty()) return;\n    if (idx.size() == 1) {\n        int i = idx[0];\n        int W = x_max - x_min;\n        int H = y_max - y_min;\n        int r = comps[i].r;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - r);\n        for (int w = 1; w <= W; ++w) {\n            int h1 = max(1, min(H, (int)(r / w)));\n            int h2 = max(1, min(H, (int)ceil((double)r / w)));\n            int area1 = w * h1;\n            int diff1 = abs(area1 - r);\n            if (diff1 < best_diff) {\n                best_diff = diff1;\n                best_w = w;\n                best_h = h1;\n            }\n            int area2 = w * h2;\n            int diff2 = abs(area2 - r);\n            if (diff2 < best_diff) {\n                best_diff = diff2;\n                best_w = w;\n                best_h = h2;\n            }\n        }\n        int a = max(x_min, comps[i].x - (best_w - 1));\n        a = min(a, x_max - best_w);\n        int b = max(y_min, comps[i].y - (best_h - 1));\n        b = min(b, y_max - best_h);\n        int c = a + best_w;\n        int d = b + best_h;\n        ans[i] = {a, b, c, d};\n        return;\n    }\n\n    long long total_r = 0;\n    for (int i : idx) total_r += comps[i].r;\n\n    // Try vertical split\n    bool can_vertical = false;\n    vector<int> sorted_x = idx;\n    sort(sorted_x.begin(), sorted_x.end(), [&](int i, int j) { return comps[i].x < comps[j].x; });\n    if (comps[sorted_x.front()].x != comps[sorted_x.back()].x) {\n        can_vertical = true;\n    }\n\n    double best_diff = 1e18;\n    int best_dir = -1; // 0 vertical, 1 horizontal\n    int best_split = -1;\n\n    if (can_vertical) {\n        vector<long long> prefix_x(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_x.size(); ++j) {\n            prefix_x[j + 1] = prefix_x[j] + comps[sorted_x[j]].r;\n        }\n        for (int p = 1; p < sorted_x.size(); ++p) {\n            if (comps[sorted_x[p - 1]].x == comps[sorted_x[p]].x) continue;\n            long long left_sum = prefix_x[p];\n            double desired_width = (left_sum / (double)total_r) * (x_max - x_min);\n            double actual_width = comps[sorted_x[p]].x - x_min;\n            double diff = fabs(actual_width - desired_width);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 0;\n                best_split = p;\n            }\n        }\n    }\n\n    // Try horizontal split\n    bool can_horizontal = false;\n    vector<int> sorted_y = idx;\n    sort(sorted_y.begin(), sorted_y.end(), [&](int i, int j) { return comps[i].y < comps[j].y; });\n    if (comps[sorted_y.front()].y != comps[sorted_y.back()].y) {\n        can_horizontal = true;\n    }\n\n    if (can_horizontal) {\n        vector<long long> prefix_y(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_y.size(); ++j) {\n            prefix_y[j + 1] = prefix_y[j] + comps[sorted_y[j]].r;\n        }\n        for (int p = 1; p < sorted_y.size(); ++p) {\n            if (comps[sorted_y[p - 1]].y == comps[sorted_y[p]].y) continue;\n            long long left_sum = prefix_y[p];\n            double desired_height = (left_sum / (double)total_r) * (y_max - y_min);\n            double actual_height = comps[sorted_y[p]].y - y_min;\n            double diff = fabs(actual_height - desired_height);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 1;\n                best_split = p;\n            }\n        }\n    }\n\n    if (best_dir == 0) {\n        int c = comps[sorted_x[best_split]].x;\n        vector<int> left_idx(sorted_x.begin(), sorted_x.begin() + best_split);\n        vector<int> right_idx(sorted_x.begin() + best_split, sorted_x.end());\n        rec(left_idx, x_min, c, y_min, y_max);\n        rec(right_idx, c, x_max, y_min, y_max);\n    } else {\n        int c = comps[sorted_y[best_split]].y;\n        vector<int> bottom_idx(sorted_y.begin(), sorted_y.begin() + best_split);\n        vector<int> top_idx(sorted_y.begin() + best_split, sorted_y.end());\n        rec(bottom_idx, x_min, x_max, y_min, c);\n        rec(top_idx, x_min, x_max, c, y_max);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    cin >> n;\n    comps.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> comps[i].x >> comps[i].y >> comps[i].r;\n    }\n\n    ans.resize(n);\n    vector<int> all_idx(n);\n    for (int i = 0; i < n; ++i) all_idx[i] = i;\n    rec(all_idx, 0, 10000, 0, 10000);\n\n    for (int i = 0; i < n; ++i) {\n        auto [a, b, c, d] = ans[i];\n        cout << a << \" \" << b << \" \" << c << \" \" << d << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <algorithm>\n#include <string>\n#include <utility>\n\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> t(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    vector<vector<int>> p(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    // Number of tiles\n    int M = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            M = max(M, t[i][j] + 1);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 1.9; // seconds\n\n    int best_score = -1;\n    vector<pair<int, int>> best_path;\n\n    // Helper to count unvisited neighbors of (i,j)\n    auto count_unvisited = [&](int i, int j, const vector<char>& visited) {\n        int cnt = 0;\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 && !visited[t[ni][nj]])\n                ++cnt;\n        }\n        return cnt;\n    };\n\n    bool timeout = false;\n    while (!timeout) {\n        // Check time before starting a new walk\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() >= time_limit)\n            break;\n\n        vector<char> visited(M, 0);\n        visited[t[si][sj]] = 1;\n        int score = p[si][sj];\n        vector<pair<int, int>> path;\n        path.emplace_back(si, sj);\n        int i = si, j = sj;\n\n        while (true) {\n            // Check time inside the walk\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() >= time_limit) {\n                timeout = true;\n                break;\n            }\n\n            vector<tuple<int, int, int>> neighbors; // (ni, nj, weight)\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 && !visited[t[ni][nj]]) {\n                    int cnt = count_unvisited(ni, nj, visited);\n                    // Weight: value plus bonus for more options\n                    int w = p[ni][nj] + 5 * cnt;\n                    neighbors.emplace_back(ni, nj, w);\n                }\n            }\n            if (neighbors.empty())\n                break;\n\n            // Choose a neighbor randomly according to weights\n            vector<double> weights;\n            for (auto& tup : neighbors)\n                weights.push_back(get<2>(tup));\n            discrete_distribution<int> dist(weights.begin(), weights.end());\n            int idx = dist(rng);\n            auto [ni, nj, w] = neighbors[idx];\n\n            // Move to the chosen neighbor\n            visited[t[ni][nj]] = 1;\n            score += p[ni][nj];\n            path.emplace_back(ni, nj);\n            i = ni;\n            j = nj;\n        }\n\n        if (!timeout && score > best_score) {\n            best_score = score;\n            best_path = path;\n        }\n    }\n\n    // Convert the best path to a move string\n    string moves;\n    for (size_t idx = 1; idx < best_path.size(); ++idx) {\n        auto [pi, pj] = best_path[idx - 1];\n        auto [ci, cj] = best_path[idx];\n        if (ci == pi - 1 && cj == pj)\n            moves += 'U';\n        else if (ci == pi + 1 && cj == pj)\n            moves += 'D';\n        else if (ci == pi && cj == pj - 1)\n            moves += 'L';\n        else if (ci == pi && cj == pj + 1)\n            moves += 'R';\n        else\n            ; // should not happen\n    }\n\n    cout << moves << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int ROWS = 30;\nconst int COLS = 30;\nconst int MAX_EDGES = 1740; // 30*29 + 29*30\n\nstruct Edge {\n    int r1, c1, r2, c2;\n    double weight;\n    int count;\n};\n\nvector<vector<double>> h_est(ROWS, vector<double>(COLS-1, 5000.0));\nvector<vector<double>> v_est(ROWS-1, vector<double>(COLS, 5000.0));\nvector<vector<int>> h_count(ROWS, vector<int>(COLS-1, 0));\nvector<vector<int>> v_count(ROWS-1, vector<double>(COLS, 0));\n\n// Direction vectors: U, D, L, R\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\npair<string, double> find_path(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(ROWS, vector<double>(COLS, 1e18));\n    vector<vector<pair<int,int>>> parent(ROWS, vector<pair<int,int>>(COLS, {-1,-1}));\n    vector<vector<int>> dir_used(ROWS, vector<int>(COLS, -1));\n    \n    dist[si][sj] = 0;\n    priority_queue<pair<double, pair<int,int>>, \n                   vector<pair<double, pair<int,int>>>, \n                   greater<pair<double, pair<int,int>>>> pq;\n    pq.push({0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, node] = pq.top(); pq.pop();\n        auto [i, j] = node;\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        // Try all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + dr[dir];\n            int nj = j + dc[dir];\n            if (ni < 0 || ni >= ROWS || nj < 0 || nj >= COLS) continue;\n            \n            double w;\n            if (dir == 0) w = v_est[ni][nj]; // U: edge from (ni,nj) to (i,j)\n            else if (dir == 1) w = v_est[i][j]; // D: edge from (i,j) to (ni,nj)\n            else if (dir == 2) w = h_est[i][nj]; // L: edge from (i,nj) to (i,j)\n            else w = h_est[i][j]; // R: edge from (i,j) to (i,nj)\n            \n            if (dist[ni][nj] > d + w) {\n                dist[ni][nj] = d + w;\n                parent[ni][nj] = {i, j};\n                dir_used[ni][nj] = dir;\n                pq.push({dist[ni][nj], {ni, nj}});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    string path;\n    double est_len = 0;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = dir_used[ci][cj];\n        path += dir_char[dir];\n        \n        // Calculate weight of this edge\n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        if (dir == 0) est_len += v_est[ci][cj]; // U\n        else if (dir == 1) est_len += v_est[pi][pj]; // D\n        else if (dir == 2) est_len += h_est[ci][cj]; // L\n        else est_len += h_est[pi][pj]; // R\n        \n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, est_len};\n}\n\nvoid update_weights(const string& path, int si, int sj, double observed) {\n    vector<tuple<int,int,bool>> edges;\n    int i = si, j = sj;\n    double est_len = 0;\n    \n    for (char c : path) {\n        int dir;\n        if (c == 'U') dir = 0;\n        else if (c == 'D') dir = 1;\n        else if (c == 'L') dir = 2;\n        else dir = 3;\n        \n        int ni = i + dr[dir];\n        int nj = j + dc[dir];\n        \n        // Record edge and update estimated length\n        if (dir == 0) { // U\n            edges.emplace_back(ni, nj, false);\n            est_len += v_est[ni][nj];\n        } else if (dir == 1) { // D\n            edges.emplace_back(i, j, false);\n            est_len += v_est[i][j];\n        } else if (dir == 2) { // L\n            edges.emplace_back(i, nj, true);\n            est_len += h_est[i][nj];\n        } else { // R\n            edges.emplace_back(i, j, true);\n            est_len += h_est[i][j];\n        }\n        \n        i = ni;\n        j = nj;\n    }\n    \n    // Update weights\n    double error = observed - est_len;\n    int edge_count = edges.size();\n    for (auto [r, c, is_horiz] : edges) {\n        double lr;\n        if (is_horiz) {\n            lr = 1.0 / (1 + h_count[r][c]);\n            h_est[r][c] += lr * error / edge_count;\n            h_est[r][c] = max(1000.0, min(9000.0, h_est[r][c]));\n            h_count[r][c]++;\n        } else {\n            lr = 1.0 / (1 + v_count[r][c]);\n            v_est[r][c] += lr * error / edge_count;\n            v_est[r][c] = max(1000.0, min(9000.0, v_est[r][c]));\n            v_count[r][c]++;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [path, est_len] = find_path(si, sj, ti, tj);\n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_weights(path, si, sj, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int ALPHABET = 8;\nconst int TOTAL_SYMBOLS = 9;  // A-H and '.'\nconst int K = 10000;          // weight for c in objective\n\n// Placement structure\nstruct Placement {\n    int str_id;\n    int mismatch_count;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    cin >> N >> M;\n    vector<string> strs(M);\n    vector<int> len(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n        len[i] = strs[i].size();\n    }\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Initialize grid with random letters\n    char grid[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + rng() % ALPHABET;\n        }\n    }\n\n    // Precompute placements and mapping from cells to placements\n    vector<Placement> placements;\n    vector<vector<pair<int, char>>> cell_to_placements(N * N);\n    vector<int> valid_placement_count(M, 0);\n\n    for (int sid = 0; sid < M; ++sid) {\n        int L = len[sid];\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int dir = 0; dir < 2; ++dir) {  // 0: horizontal, 1: vertical\n                    int pid = placements.size();\n                    placements.push_back({sid, 0});\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {  // horizontal\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {  // vertical\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        char required = strs[sid][p];\n                        cell_to_placements[ni * N + nj].emplace_back(pid, required);\n                        if (grid[ni][nj] != required) {\n                            placements[pid].mismatch_count++;\n                        }\n                    }\n                    if (placements[pid].mismatch_count == 0) {\n                        valid_placement_count[sid]++;\n                    }\n                }\n            }\n        }\n    }\n\n    // Compute initial coverage and number of empty cells\n    int c = 0;\n    for (int i = 0; i < M; ++i) {\n        if (valid_placement_count[i] > 0) c++;\n    }\n    int d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] == '.') d++;\n        }\n    }\n    int current_obj = c * K + (c == M ? (N * N - d) : 0);\n\n    // Simulated annealing parameters\n    double temp = 100.0;\n    const double cooling_rate = 0.99999;\n    const int max_iter = 2000000;\n    auto start_time = chrono::steady_clock::now();\n\n    // SA main loop\n    for (int iter = 0; iter < max_iter; ++iter) {\n        // Check time limit\n        if (iter % 1000 == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 2.9) break;\n        }\n\n        // Pick a random cell and a new symbol\n        int pos = rng() % (N * N);\n        int i = pos / N, j = pos % N;\n        char old_char = grid[i][j];\n        int sym = rng() % TOTAL_SYMBOLS;\n        char new_char = (sym == ALPHABET) ? '.' : ('A' + sym);\n        if (old_char == new_char) continue;\n\n        // Compute change in empty cells\n        int new_d = d;\n        if (old_char == '.' && new_char != '.') new_d--;\n        if (old_char != '.' && new_char == '.') new_d++;\n\n        // Compute changes in valid placement counts for affected strings\n        unordered_map<int, int> delta_count;\n        for (const auto& inc : cell_to_placements[pos]) {\n            int pid = inc.first;\n            char required = inc.second;\n            Placement& pl = placements[pid];\n            bool old_match = (old_char == required);\n            bool new_match = (new_char == required);\n            if (old_match && !new_match) {\n                if (pl.mismatch_count == 0) {\n                    delta_count[pl.str_id]--;\n                }\n            } else if (!old_match && new_match) {\n                if (pl.mismatch_count == 1) {\n                    delta_count[pl.str_id]++;\n                }\n            }\n        }\n\n        // Compute new coverage\n        int new_c = c;\n        for (const auto& p : delta_count) {\n            int str_id = p.first;\n            int delta = p.second;\n            bool old_covered = (valid_placement_count[str_id] > 0);\n            bool new_covered = (valid_placement_count[str_id] + delta > 0);\n            if (old_covered && !new_covered) new_c--;\n            if (!old_covered && new_covered) new_c++;\n        }\n\n        // Compute new objective\n        int new_obj = new_c * K + (new_c == M ? (N * N - new_d) : 0);\n        int delta_obj = new_obj - current_obj;\n\n        // Acceptance probability\n        if (delta_obj > 0 || (temp > 0 && (double)rng() / rng.max() < exp(delta_obj / temp))) {\n            // Apply the move\n            grid[i][j] = new_char;\n            for (const auto& inc : cell_to_placements[pos]) {\n                int pid = inc.first;\n                char required = inc.second;\n                Placement& pl = placements[pid];\n                bool old_match = (old_char == required);\n                bool new_match = (new_char == required);\n                if (old_match && !new_match) pl.mismatch_count++;\n                else if (!old_match && new_match) pl.mismatch_count--;\n            }\n            for (const auto& p : delta_count) {\n                valid_placement_count[p.first] += p.second;\n            }\n            c = new_c;\n            d = new_d;\n            current_obj = new_obj;\n        }\n\n        // Cool down\n        temp *= cooling_rate;\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        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<int>> cost;               // -1 for obstacle, else digit 5-9\nvector<vector<int>> row_seg, col_seg;   // segment ids for each cell\nint R_cnt, C_cnt;                       // number of row/column segments\nvector<vector<pair<int, int>>> row_cells, col_cells; // cells in each segment\nvector<unordered_map<int, pair<int, int>>> cell_of;  // (r,c) -> (i,j)\n\n// Directions: up, down, left, right\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// Linear index for a cell\ninline int to_id(int i, int j) { return i * N + j; }\ninline pair<int, int> from_id(int id) { return {id / N, id % N}; }\n\n// ----------------------------------------------------------------------\n// Dijkstra from a source, returns distances and predecessors\nstruct DijkstraResult {\n    vector<vector<int>> dist;\n    vector<vector<int>> prev;   // previous cell as linear id\n    DijkstraResult() : dist(N, vector<int>(N, INF)), prev(N, vector<int>(N, -1)) {}\n};\n\nDijkstraResult run_dijkstra(int si, int sj) {\n    DijkstraResult res;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    res.dist[si][sj] = 0;\n    pq.push({0, to_id(si, sj)});\n    while (!pq.empty()) {\n        auto [d, id] = pq.top(); pq.pop();\n        auto [i, j] = from_id(id);\n        if (d != res.dist[i][j]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (cost[ni][nj] == -1) continue;   // obstacle\n            int nd = d + cost[ni][nj];\n            if (nd < res.dist[ni][nj]) {\n                res.dist[ni][nj] = nd;\n                res.prev[ni][nj] = id;\n                pq.push({nd, to_id(ni, nj)});\n            }\n        }\n    }\n    return res;\n}\n\n// ----------------------------------------------------------------------\n// Hopcroft\u2013Karp for bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> matchL, matchR, dist;\n    HopcroftKarp(int nL, int nR) : nL(nL), nR(nR), adj(nL), matchL(nL, -1), matchR(nR, -1), dist(nL) {}\n    void addEdge(int u, int v) { adj[u].push_back(v); }\n    bool bfs() {\n        queue<int> q;\n        for (int u = 0; u < nL; ++u) {\n            if (matchL[u] == -1) {\n                dist[u] = 0;\n                q.push(u);\n            } else dist[u] = INF;\n        }\n        bool found = false;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (matchR[v] == -1) found = true;\n                else if (dist[matchR[v]] == INF) {\n                    dist[matchR[v]] = dist[u] + 1;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n        return found;\n    }\n    bool dfs(int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 || (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = INF;\n        return false;\n    }\n    int maxMatching() {\n        int matching = 0;\n        while (bfs()) {\n            for (int u = 0; u < nL; ++u)\n                if (matchL[u] == -1 && dfs(u))\n                    ++matching;\n        }\n        return matching;\n    }\n};\n\n// ----------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input --------------------------------------------------------\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    cost.assign(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                cost[i][j] = grid[i][j] - '0';\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n\n    // ----- Row segments -------------------------------------------------\n    row_seg.assign(N, vector<int>(N, -1));\n    R_cnt = 0;\n    row_cells.clear();\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (cost[i][j] != -1) {\n                int start_j = j;\n                while (j < N && cost[i][j] != -1) {\n                    row_seg[i][j] = R_cnt;\n                    ++j;\n                }\n                row_cells.emplace_back();\n                for (int k = start_j; k < j; ++k)\n                    row_cells.back().emplace_back(i, k);\n                ++R_cnt;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ----- Column segments ----------------------------------------------\n    col_seg.assign(N, vector<int>(N, -1));\n    C_cnt = 0;\n    col_cells.clear();\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (cost[i][j] != -1) {\n                int start_i = i;\n                while (i < N && cost[i][j] != -1) {\n                    col_seg[i][j] = C_cnt;\n                    ++i;\n                }\n                col_cells.emplace_back();\n                for (int k = start_i; k < i; ++k)\n                    col_cells.back().emplace_back(k, j);\n                ++C_cnt;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ----- Build full bipartite graph (row segments vs column segments) -\n    HopcroftKarp hk_full(R_cnt, C_cnt);\n    cell_of.resize(R_cnt);\n    for (auto [i, j] : road_cells) {\n        int r = row_seg[i][j];\n        int c = col_seg[i][j];\n        hk_full.addEdge(r, c);\n        cell_of[r][c] = {i, j};\n    }\n\n    // ----- Maximum matching and minimum vertex cover --------------------\n    hk_full.maxMatching();\n\n    vector<bool> visL(R_cnt, false), visR(C_cnt, false);\n    function<void(int)> dfs_cover = [&](int u) {\n        visL[u] = true;\n        for (int v : hk_full.adj[u]) {\n            if (!visR[v] && hk_full.matchL[u] != v) {\n                visR[v] = true;\n                if (hk_full.matchR[v] != -1 && !visL[hk_full.matchR[v]])\n                    dfs_cover(hk_full.matchR[v]);\n            }\n        }\n    };\n    for (int u = 0; u < R_cnt; ++u)\n        if (hk_full.matchL[u] == -1)\n            dfs_cover(u);\n\n    vector<bool> inX(R_cnt, false), inY(C_cnt, false);\n    for (int u = 0; u < R_cnt; ++u) if (!visL[u]) inX[u] = true;\n    for (int v = 0; v < C_cnt; ++v) if (visR[v]) inY[v] = true;\n\n    // ----- Remove start's own segments ----------------------------------\n    int r_start = row_seg[si][sj];\n    int c_start = col_seg[si][sj];\n    if (r_start != -1) inX[r_start] = false;\n    if (c_start != -1) inY[c_start] = false;\n\n    // ----- Collect vertices that still need covering --------------------\n    vector<int> X_list, Y_list;\n    for (int u = 0; u < R_cnt; ++u) if (inX[u]) X_list.push_back(u);\n    for (int v = 0; v < C_cnt; ++v) if (inY[v]) Y_list.push_back(v);\n    int nX = X_list.size(), nY = Y_list.size();\n\n    // If nothing left to cover, we only need to start and return.\n    if (nX == 0 && nY == 0) {\n        // Trivial tour: go to an adjacent road cell and back.\n        for (int d = 0; d < 4; ++d) {\n            int ni = si + di[d], nj = sj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && cost[ni][nj] != -1) {\n                cout << dir_char[d];\n                // Opposite direction\n                if (d == 0) cout << 'D';\n                else if (d == 1) cout << 'U';\n                else if (d == 2) cout << 'R';\n                else cout << 'L';\n                cout << endl;\n                return 0;\n            }\n        }\n        // Should not happen (graph is connected), but fallback:\n        cout << endl;\n        return 0;\n    }\n\n    // ----- Build subgraph between X_list and Y_list --------------------\n    vector<int> X_index(R_cnt, -1), Y_index(C_cnt, -1);\n    for (int i = 0; i < nX; ++i) X_index[X_list[i]] = i;\n    for (int i = 0; i < nY; ++i) Y_index[Y_list[i]] = i;\n\n    HopcroftKarp hk_sub(nX, nY);\n    vector<unordered_map<int, pair<int, int>>> sub_cell_of(nX);\n    for (int r : X_list) {\n        int i = X_index[r];\n        for (auto &[c, coord] : cell_of[r]) {\n            if (inY[c]) {\n                int j = Y_index[c];\n                hk_sub.addEdge(i, j);\n                sub_cell_of[i][j] = {r, c};\n            }\n        }\n    }\n\n    // ----- Maximum matching in subgraph ---------------------------------\n    hk_sub.maxMatching();\n\n    // ----- Precompute distances from start (for picking close cells) ----\n    auto dist_start_res = run_dijkstra(si, sj);\n    auto &dist_start = dist_start_res.dist;\n\n    // ----- Construct set S of cells to visit ----------------------------\n    set<pair<int, int>> S_set;\n\n    // Cells from the matching\n    for (int i = 0; i < nX; ++i) {\n        int j = hk_sub.matchL[i];\n        if (j != -1) {\n            auto [r, c] = sub_cell_of[i][j];\n            S_set.insert(cell_of[r][c]);\n        }\n    }\n\n    // Unmatched row segments: pick closest cell to start\n    for (int i = 0; i < nX; ++i) {\n        if (hk_sub.matchL[i] == -1) {\n            int r = X_list[i];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : row_cells[r]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    // Unmatched column segments: pick closest cell to start\n    for (int j = 0; j < nY; ++j) {\n        if (hk_sub.matchR[j] == -1) {\n            int c = Y_list[j];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : col_cells[c]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    vector<pair<int, int>> points(S_set.begin(), S_set.end());\n    int K = points.size();\n\n    // ----- All-pairs shortest paths among points and start -------------\n    int total_nodes = K + 1;          // indices 0..K-1 : points, K : start\n    vector<vector<int>> dist_mat(total_nodes, vector<int>(total_nodes, INF));\n    vector<DijkstraResult> dijkstra_res(total_nodes);\n\n    for (int idx = 0; idx < total_nodes; ++idx) {\n        int i, j;\n        if (idx < K) {\n            i = points[idx].first, j = points[idx].second;\n        } else {\n            i = si, j = sj;\n        }\n        dijkstra_res[idx] = run_dijkstra(i, j);\n        auto &res = dijkstra_res[idx];\n        for (int other = 0; other < total_nodes; ++other) {\n            int oi, oj;\n            if (other < K) {\n                oi = points[other].first, oj = points[other].second;\n            } else {\n                oi = si, oj = sj;\n            }\n            dist_mat[idx][other] = res.dist[oi][oj];\n        }\n    }\n\n    // ----- Nearest\u2011neighbour TSP (directed) -----------------------------\n    vector<int> order;                 // order of visiting points (indices 0..K-1)\n    vector<bool> visited(K, false);\n    int cur = K;                       // start index\n    while ((int)order.size() < K) {\n        int nxt = -1;\n        int best = INF;\n        for (int j = 0; j < K; ++j) {\n            if (!visited[j] && dist_mat[cur][j] < best) {\n                best = dist_mat[cur][j];\n                nxt = j;\n            }\n        }\n        if (nxt == -1) break;          // should not happen (graph connected)\n        visited[nxt] = true;\n        order.push_back(nxt);\n        cur = nxt;\n    }\n\n    // ----- Build full tour (start -> order -> start) --------------------\n    vector<int> tour;\n    tour.push_back(K);                 // start\n    for (int x : order) tour.push_back(x);\n    tour.push_back(K);                 // return to start\n\n    // ----- Reconstruct the move string ---------------------------------\n    string moves;\n    for (size_t t = 0; t + 1 < tour.size(); ++t) {\n        int from_idx = tour[t], to_idx = tour[t + 1];\n        auto [fi, fj] = (from_idx < K) ? points[from_idx] : make_pair(si, sj);\n        auto [ti, tj] = (to_idx < K) ? points[to_idx] : make_pair(si, sj);\n        auto &res = dijkstra_res[from_idx];\n\n        // Backtrack from (ti,tj) to (fi,fj)\n        vector<pair<int, int>> path;\n        int ci = ti, cj = tj;\n        while (!(ci == fi && cj == fj)) {\n            path.emplace_back(ci, cj);\n            int pid = res.prev[ci][cj];\n            if (pid == -1) break;      // should not happen\n            auto [pi, pj] = from_id(pid);\n            ci = pi; cj = pj;\n        }\n        path.emplace_back(fi, fj);\n        reverse(path.begin(), path.end());\n\n        // Convert path to moves\n        for (size_t i = 0; i + 1 < path.size(); ++i) {\n            auto [cur_i, cur_j] = path[i];\n            auto [nxt_i, nxt_j] = path[i + 1];\n            for (int d = 0; d < 4; ++d) {\n                if (cur_i + di[d] == nxt_i && cur_j + dj[d] == nxt_j) {\n                    moves += dir_char[d];\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << moves << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N+1, vector<int>(K));\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n        }\n    }\n    \n    // Build dependency graph\n    vector<vector<int>> children(N+1), parents(N+1);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        children[u].push_back(v);\n        parents[v].push_back(u);\n    }\n    \n    // Compute critical path length (priority)\n    vector<int> priority(N+1, 1);\n    for (int i = N; i >= 1; i--) {\n        for (int child : children[i]) {\n            priority[i] = max(priority[i], priority[child] + 1);\n        }\n    }\n    \n    // State tracking\n    vector<int> task_status(N+1, -1); // -1: not started, 0: in progress, 1: completed\n    vector<int> worker_task(M+1, -1); // -1: idle, else: task being worked on\n    vector<vector<int>> worker_skills(M+1, vector<int>(K, 0)); // Lower bounds\n    \n    // For randomness\n    auto seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    int day = 0;\n    while (true) {\n        day++;\n        \n        // Find available workers\n        vector<int> available_workers;\n        for (int w = 1; w <= M; w++) {\n            if (worker_task[w] == -1) {\n                available_workers.push_back(w);\n            }\n        }\n        \n        // Find ready tasks (all dependencies completed)\n        vector<int> ready_tasks;\n        for (int t = 1; t <= N; t++) {\n            if (task_status[t] != -1) continue;\n            \n            bool all_deps_completed = true;\n            for (int parent : parents[t]) {\n                if (task_status[parent] != 1) {\n                    all_deps_completed = false;\n                    break;\n                }\n            }\n            \n            if (all_deps_completed) {\n                ready_tasks.push_back(t);\n            }\n        }\n        \n        // Sort ready tasks by priority (higher first)\n        sort(ready_tasks.begin(), ready_tasks.end(), \n             [&](int a, int b) { return priority[a] > priority[b]; });\n        \n        // Prepare assignments\n        vector<pair<int, int>> assignments;\n        vector<bool> worker_used(M+1, false);\n        \n        // Greedy assignment with exploration\n        uniform_real_distribution<double> explore_dist(0.0, 1.0);\n        const double EXPLORE_PROB = 0.1;\n        \n        for (int task : ready_tasks) {\n            if (available_workers.empty()) break;\n            \n            int best_worker = -1;\n            double best_score = -1e18;\n            \n            // With some probability, do random assignment for exploration\n            if (explore_dist(rng) < EXPLORE_PROB && available_workers.size() > 1) {\n                uniform_int_distribution<int> worker_dist(0, available_workers.size()-1);\n                int idx = worker_dist(rng);\n                best_worker = available_workers[idx];\n            } else {\n                // Find worker that minimizes expected completion time\n                for (int w : available_workers) {\n                    if (worker_used[w]) continue;\n                    \n                    // Estimate completion time based on current skill bounds\n                    int expected_time = 1;\n                    int deficiency = 0;\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > worker_skills[w][k]) {\n                            deficiency += d[task][k] - worker_skills[w][k];\n                        }\n                    }\n                    if (deficiency > 0) {\n                        expected_time = max(1, deficiency); // Conservative estimate\n                    }\n                    \n                    // Score: prefer higher priority tasks with lower expected time\n                    double score = priority[task] * 1000.0 - expected_time;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_worker = w;\n                    }\n                }\n            }\n            \n            if (best_worker != -1) {\n                assignments.emplace_back(best_worker, task);\n                worker_task[best_worker] = task;\n                task_status[task] = 0;\n                \n                // Remove worker from available list\n                available_workers.erase(\n                    remove(available_workers.begin(), available_workers.end(), best_worker),\n                    available_workers.end()\n                );\n                worker_used[best_worker] = true;\n            }\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [w, t] : assignments) {\n            cout << \" \" << w << \" \" << t;\n        }\n        cout << endl;\n        cout.flush();\n        \n        // Read completion information\n        int completion_count;\n        cin >> completion_count;\n        \n        if (completion_count == -1) {\n            break; // End of simulation\n        }\n        \n        // Update based on completions\n        for (int i = 0; i < completion_count; i++) {\n            int worker;\n            cin >> worker;\n            \n            int task = worker_task[worker];\n            if (task != -1) {\n                task_status[task] = 1;\n                worker_task[worker] = -1;\n                \n                // Update skill estimates if completed in 1 day\n                // (implies skills meet/exceed requirements)\n                for (int k = 0; k < K; k++) {\n                    worker_skills[worker][k] = max(worker_skills[worker][k], d[task][k]);\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nPoint center = {400, 400};\n\n// Manhattan distance\ninline int manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read 1000 orders\n    vector<Point> pickup(1000), dropoff(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> pickup[i].x >> pickup[i].y >> dropoff[i].x >> dropoff[i].y;\n    }\n\n    // ---- Step 1: Select 50 orders with smallest individual round\u2011trip cost ----\n    vector<int> order_idx(1000);\n    iota(order_idx.begin(), order_idx.end(), 0);\n    vector<int> indiv_cost(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int d1 = manhattan(center, pickup[i]);\n        int d2 = manhattan(pickup[i], dropoff[i]);\n        int d3 = manhattan(dropoff[i], center);\n        indiv_cost[i] = d1 + d2 + d3;\n    }\n    sort(order_idx.begin(), order_idx.end(),\n         [&](int a, int b) { return indiv_cost[a] < indiv_cost[b]; });\n    vector<int> selected(order_idx.begin(), order_idx.begin() + 50);  // original 0\u2011based indices\n\n    // ---- Step 2: Build node list for the selected orders ----\n    // nodes 0..49 : pickups, nodes 50..99 : dropoffs\n    vector<Point> nodes(100);\n    vector<int> order_of_node(100);      // order index (0..49)\n    vector<bool> is_pickup(100, false);\n    for (int i = 0; i < 50; ++i) {\n        int ord = selected[i];\n        nodes[i] = pickup[ord];\n        order_of_node[i] = i;\n        is_pickup[i] = true;\n        nodes[i + 50] = dropoff[ord];\n        order_of_node[i + 50] = i;\n        is_pickup[i + 50] = false;\n    }\n\n    // ---- Step 3: Greedy construction of an initial feasible route ----\n    vector<int> seq;                     // sequence of node indices (0..99)\n    vector<bool> picked(50, false), delivered(50, false);\n    Point cur = center;\n    while (true) {\n        int best_node = -1;\n        int best_dist = 1e9;\n        // try pickups\n        for (int i = 0; i < 50; ++i) {\n            if (!picked[i]) {\n                int d = manhattan(cur, nodes[i]);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_node = i;\n                }\n            }\n        }\n        // try deliveries\n        for (int i = 0; i < 50; ++i) {\n            if (picked[i] && !delivered[i]) {\n                int d = manhattan(cur, nodes[i + 50]);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_node = i + 50;\n                }\n            }\n        }\n        if (best_node == -1) break;      // all delivered\n        seq.push_back(best_node);\n        if (best_node < 50) {\n            picked[best_node] = true;\n            cur = nodes[best_node];\n        } else {\n            int ord = best_node - 50;\n            delivered[ord] = true;\n            cur = nodes[best_node];\n        }\n    }\n    // seq now has exactly 100 nodes\n\n    // ---- Step 4: Precompute distances (including center as node 100) ----\n    vector<Point> pts(101);\n    for (int i = 0; i < 100; ++i) pts[i] = nodes[i];\n    pts[100] = center;\n    vector<vector<int>> dist(101, vector<int>(101));\n    for (int i = 0; i < 101; ++i)\n        for (int j = 0; j < 101; ++j)\n            dist[i][j] = manhattan(pts[i], pts[j]);\n\n    // ---- Step 5: Compute initial total travel time ----\n    int cost = dist[100][seq[0]];\n    for (int i = 0; i < 99; ++i) cost += dist[seq[i]][seq[i+1]];\n    cost += dist[seq[99]][100];\n\n    // current best\n    int best_cost = cost;\n    vector<int> best_seq = seq;\n\n    // position of each node in the current sequence\n    vector<int> pos(100);\n    for (int i = 0; i < 100; ++i) pos[seq[i]] = i;\n\n    // ---- Step 6: Simulated Annealing (swap moves only) ----\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> rand_pos(0, 99);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    const int MAX_ITER = 500000;\n    double temp = 100.0;\n    const double cooling = 0.99999;\n\n    // Helper: can we swap positions a and b? (a < b)\n    auto can_swap = [&](int a, int b) -> bool {\n        int nodeA = seq[a], nodeB = seq[b];\n\n        // Check order of nodeA after swap\n        int ordA = order_of_node[nodeA];\n        bool pickupA = is_pickup[nodeA];\n        int new_pos_pickupA, new_pos_dropoffA;\n        if (pickupA) {\n            new_pos_pickupA = b;\n            int dropoffA = nodeA + 50;\n            new_pos_dropoffA = (dropoffA == nodeB) ? a : pos[dropoffA];\n        } else {\n            new_pos_dropoffA = b;\n            int pickupA = nodeA - 50;\n            new_pos_pickupA = (pickupA == nodeB) ? a : pos[pickupA];\n        }\n        if (new_pos_pickupA >= new_pos_dropoffA) return false;\n\n        // Check order of nodeB after swap\n        int ordB = order_of_node[nodeB];\n        bool pickupB = is_pickup[nodeB];\n        int new_pos_pickupB, new_pos_dropoffB;\n        if (pickupB) {\n            new_pos_pickupB = a;\n            int dropoffB = nodeB + 50;\n            new_pos_dropoffB = (dropoffB == nodeA) ? b : pos[dropoffB];\n        } else {\n            new_pos_dropoffB = a;\n            int pickupB = nodeB - 50;\n            new_pos_pickupB = (pickupB == nodeA) ? b : pos[pickupB];\n        }\n        if (new_pos_pickupB >= new_pos_dropoffB) return false;\n\n        return true;\n    };\n\n    // Helper: delta cost for swapping positions a and b (a < b)\n    auto delta_swap = [&](int a, int b) -> int {\n        int n1 = seq[a], n2 = seq[b];\n        int old_cost = 0, new_cost = 0;\n\n        auto get_node = [&](int p) -> int {\n            if (p < 0 || p >= 100) return 100;   // center\n            return seq[p];\n        };\n\n        // left positions of edges that may change\n        int lefts[4] = {a-1, a, b-1, b};\n        bool used[4] = {false};\n        for (int i = 0; i < 4; ++i) {\n            if (used[i]) continue;\n            int lp = lefts[i];\n            if (lp < -1 || lp >= 100) continue;\n            // mark duplicates\n            for (int j = i+1; j < 4; ++j)\n                if (lefts[j] == lp) used[j] = true;\n\n            int u = get_node(lp);\n            int v = get_node(lp+1);\n            old_cost += dist[u][v];\n\n            int u_new = (lp == a) ? n2 : (lp == b) ? n1 : u;\n            int v_new = (lp+1 == a) ? n2 : (lp+1 == b) ? n1 : v;\n            new_cost += dist[u_new][v_new];\n        }\n        return new_cost - old_cost;\n    };\n\n    // SA main loop\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        temp *= cooling;\n        int a = rand_pos(gen);\n        int b = rand_pos(gen);\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        if (!can_swap(a, b)) continue;\n\n        int delta = delta_swap(a, b);\n        if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n            // apply swap\n            int nodeA = seq[a], nodeB = seq[b];\n            seq[a] = nodeB;\n            seq[b] = nodeA;\n            pos[nodeA] = b;\n            pos[nodeB] = a;\n            cost += delta;\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_seq = seq;\n            }\n        }\n    }\n\n    // ---- Step 7: Output ----\n    // selected orders (convert to 1\u2011based)\n    cout << \"50\";\n    for (int idx : selected) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n\n    // full route: center -> best_seq -> center\n    vector<Point> route;\n    route.push_back(center);\n    for (int id : best_seq) route.push_back(nodes[id]);\n    route.push_back(center);\n\n    cout << route.size();\n    for (Point p : route) cout << \" \" << p.x << \" \" << p.y;\n    cout << endl;\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, d;\n};\n\nclass DSU {\n    vector<int> parent, rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\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]) parent[x] = y;\n        else if (rank[x] > rank[y]) parent[y] = x;\n        else {\n            parent[y] = x;\n            rank[x]++;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    int M;\n    cin >> M;\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        double dx = x[u] - x[v];\n        double dy = y[u] - y[v];\n        double dist = sqrt(dx * dx + dy * dy);\n        int d = round(dist);\n        edges[i] = {u, v, d};\n    }\n    \n    DSU dsu(N);\n    const int K = 400;  // fallback threshold\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        int u = edges[i].u, v = edges[i].v;\n        \n        // If already connected, skip\n        if (dsu.find(u) == dsu.find(v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // In the last K edges, accept any connecting edge to ensure connectivity\n        if (i >= M - K) {\n            dsu.unite(u, v);\n            cout << 1 << endl;\n            continue;\n        }\n        \n        // Find minimum d between the two components\n        int comp_u = dsu.find(u);\n        int comp_v = dsu.find(v);\n        int min_d = INT_MAX;\n        \n        for (int j = 0; j < M; j++) {\n            int a = dsu.find(edges[j].u);\n            int b = dsu.find(edges[j].v);\n            if ((a == comp_u && b == comp_v) || (a == comp_v && b == comp_u)) {\n                min_d = min(min_d, edges[j].d);\n            }\n        }\n        \n        // Accept if length is reasonable compared to best possible\n        if (l <= 2 * min_d) {\n            dsu.unite(u, v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID = 30;\n\n// Pet movement directions\nconst int dx[4] = {1, -1, 0, 0};\nconst int dy[4] = {0, 0, 1, -1};\n\nstruct Task {\n    int target_x, target_y;   // where to stand to build\n    char build_action;        // 'U','D','L','R' to build adjacent wall\n    int wall_x, wall_y;       // the wall square to build\n};\n\nint N, M;\nvector<int> pet_x, pet_y, pet_type;\nvector<int> human_x, human_y;\nbool wall[GRID+1][GRID+1] = {false};  // true if wall\n\n// Helper functions\nbool inside(int x, int y) {\n    return 1 <= x && x <= GRID && 1 <= y && y <= GRID;\n}\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; ++i)\n        if (pet_x[i] == x && pet_y[i] == y)\n            return true;\n    return false;\n}\n\nbool has_adjacent_pet(int x, int y) {\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + dx[d], ny = y + dy[d];\n        if (inside(nx, ny) && has_pet_at(nx, ny))\n            return true;\n    }\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; ++i)\n        if (human_x[i] == x && human_y[i] == y)\n            return true;\n    return false;\n}\n\nchar move_towards(int cx, int cy, int tx, int ty) {\n    if (cx == tx && cy == ty) return '.';\n    int dx = tx - cx, dy = ty - cy;\n    if (abs(dx) >= abs(dy))\n        return (dx > 0) ? 'D' : 'U';\n    else\n        return (dy > 0) ? 'R' : 'L';\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    cin >> N;\n    pet_x.resize(N); pet_y.resize(N); pet_type.resize(N);\n    for (int i = 0; i < N; ++i)\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n    cin >> M;\n    human_x.resize(M); human_y.resize(M);\n    for (int i = 0; i < M; ++i)\n        cin >> human_x[i] >> human_y[i];\n\n    // Initial pet grid for plan selection\n    bool pet_init[GRID+1][GRID+1] = {false};\n    for (int i = 0; i < N; ++i)\n        pet_init[pet_x[i]][pet_y[i]] = true;\n\n    // Plan selection: maximize interior size\n    int best_size = -1;\n    int plan_type = -1;   // 0: horizontal only, 1: vertical only, 2: both\n    int plan_H = -1, plan_V = -1;\n    bool plan_interior_above = true;   // for horizontal\n    bool plan_interior_left = true;    // for vertical\n    int plan_corner = -1;              // for both (0:TL,1:TR,2:BL,3:BR)\n\n    // ---------- One\u2011wall horizontal ----------\n    for (int H = 2; H <= GRID; ++H) {\n        // Wall squares (H, 1..30)\n        bool wall_ok = true;\n        for (int y = 1; y <= GRID; ++y)\n            if (pet_init[H][y]) { wall_ok = false; break; }\n        if (!wall_ok) continue;\n\n        // Interior above\n        bool interior_ok = true;\n        for (int x = 1; x < H; ++x)\n            for (int y = 1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = (H - 1) * GRID;\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 0;\n                plan_H = H;\n                plan_interior_above = true;\n            }\n        }\n\n        // Interior below\n        interior_ok = true;\n        for (int x = H+1; x <= GRID; ++x)\n            for (int y = 1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = (GRID - H) * GRID;\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 0;\n                plan_H = H;\n                plan_interior_above = false;\n            }\n        }\n    }\n\n    // ---------- One\u2011wall vertical ----------\n    for (int V = 2; V <= GRID; ++V) {\n        // Wall squares (1..30, V)\n        bool wall_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            if (pet_init[x][V]) { wall_ok = false; break; }\n        if (!wall_ok) continue;\n\n        // Interior left\n        bool interior_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            for (int y = 1; y < V; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = GRID * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 1;\n                plan_V = V;\n                plan_interior_left = true;\n            }\n        }\n\n        // Interior right\n        interior_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            for (int y = V+1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = GRID * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 1;\n                plan_V = V;\n                plan_interior_left = false;\n            }\n        }\n    }\n\n    // ---------- Two\u2011wall corners ----------\n    // Corner 0: top\u2011left\n    for (int H = 2; H <= GRID; ++H) {\n        for (int V = 2; V <= GRID; ++V) {\n            // Wall: (H, 1..V) and (1..H, V)\n            bool wall_ok = true;\n            for (int y = 1; y <= V; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = 1; x <= H; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: 1..H-1 , 1..V-1\n            bool interior_ok = true;\n            for (int x = 1; x < H; ++x)\n                for (int y = 1; y < V; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (H - 1) * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 0;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 1: top\u2011right\n    for (int H = 2; H <= GRID; ++H) {\n        for (int V = 1; V <= GRID-1; ++V) {\n            // Wall: (H, V..30) and (1..H, V)\n            bool wall_ok = true;\n            for (int y = V; y <= GRID; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = 1; x <= H; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: 1..H-1 , V+1..30\n            bool interior_ok = true;\n            for (int x = 1; x < H; ++x)\n                for (int y = V+1; y <= GRID; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (H - 1) * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 1;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 2: bottom\u2011left\n    for (int H = 1; H <= GRID-1; ++H) {\n        for (int V = 2; V <= GRID; ++V) {\n            // Wall: (H, 1..V) and (H..30, V)\n            bool wall_ok = true;\n            for (int y = 1; y <= V; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = H; x <= GRID; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: H+1..30 , 1..V-1\n            bool interior_ok = true;\n            for (int x = H+1; x <= GRID; ++x)\n                for (int y = 1; y < V; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (GRID - H) * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 2;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 3: bottom\u2011right\n    for (int H = 1; H <= GRID-1; ++H) {\n        for (int V = 1; V <= GRID-1; ++V) {\n            // Wall: (H, V..30) and (H..30, V)\n            bool wall_ok = true;\n            for (int y = V; y <= GRID; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = H; x <= GRID; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: H+1..30 , V+1..30\n            bool interior_ok = true;\n            for (int x = H+1; x <= GRID; ++x)\n                for (int y = V+1; y <= GRID; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (GRID - H) * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 3;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // ---------- Prepare tasks and roles ----------\n    vector<Task> hor_tasks, ver_tasks;\n    int gather_x = 1, gather_y = 1;   // default, will be overwritten\n    vector<int> role(M, 0);           // 0: normal, 1: horizontal builder, 2: vertical builder\n\n    if (plan_type == 0) { // horizontal only\n        if (plan_interior_above) {\n            gather_x = 1; gather_y = 1;\n            for (int y = 1; y <= GRID; ++y)\n                hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n        } else {\n            gather_x = GRID; gather_y = 1;\n            for (int y = 1; y <= GRID; ++y)\n                hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n        }\n        if (M > 0) role[0] = 1;\n    }\n    else if (plan_type == 1) { // vertical only\n        if (plan_interior_left) {\n            gather_x = 1; gather_y = 1;\n            for (int x = 1; x <= GRID; ++x)\n                ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n        } else {\n            gather_x = 1; gather_y = GRID;\n            for (int x = 1; x <= GRID; ++x)\n                ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n        }\n        if (M > 0) role[0] = 2;\n    }\n    else if (plan_type == 2) { // both walls\n        switch (plan_corner) {\n            case 0: // top\u2011left\n                gather_x = 1; gather_y = 1;\n                for (int y = 1; y <= plan_V; ++y)\n                    hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n                for (int x = 1; x < plan_H; ++x)\n                    ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n                break;\n            case 1: // top\u2011right\n                gather_x = 1; gather_y = GRID;\n                for (int y = plan_V; y <= GRID; ++y)\n                    hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n                for (int x = 1; x < plan_H; ++x)\n                    ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n                break;\n            case 2: // bottom\u2011left\n                gather_x = GRID; gather_y = 1;\n                for (int y = 1; y <= plan_V; ++y)\n                    hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n                for (int x = plan_H; x <= GRID; ++x)\n                    ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n                break;\n            case 3: // bottom\u2011right\n                gather_x = GRID; gather_y = GRID;\n                for (int y = plan_V; y <= GRID; ++y)\n                    hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n                for (int x = plan_H; x <= GRID; ++x)\n                    ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n                break;\n        }\n        if (M > 0) role[0] = 1;\n        if (M > 1) role[1] = 2;\n    }\n\n    // Builder indices\n    int hor_idx = 0, ver_idx = 0;\n\n    // ---------- Simulation ----------\n    for (int turn = 0; turn < 300; ++turn) {\n        vector<char> actions(M, '.');\n\n        for (int i = 0; i < M; ++i) {\n            if (role[i] == 0) { // normal\n                actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n            }\n            else if (role[i] == 1) { // horizontal builder\n                if (hor_idx >= (int)hor_tasks.size()) {\n                    // done \u2013 go to gathering point\n                    actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n                } else {\n                    Task &t = hor_tasks[hor_idx];\n                    if (human_x[i] == t.target_x && human_y[i] == t.target_y) {\n                        // try to build\n                        if (!wall[t.wall_x][t.wall_y] &&\n                            !has_pet_at(t.wall_x, t.wall_y) &&\n                            !has_human_at(t.wall_x, t.wall_y) &&\n                            !has_adjacent_pet(t.wall_x, t.wall_y)) {\n                            actions[i] = t.build_action;\n                            wall[t.wall_x][t.wall_y] = true;\n                            ++hor_idx;\n                        } else {\n                            actions[i] = '.';\n                        }\n                    } else {\n                        actions[i] = move_towards(human_x[i], human_y[i], t.target_x, t.target_y);\n                    }\n                }\n            }\n            else if (role[i] == 2) { // vertical builder\n                if (ver_idx >= (int)ver_tasks.size()) {\n                    actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n                } else {\n                    Task &t = ver_tasks[ver_idx];\n                    if (human_x[i] == t.target_x && human_y[i] == t.target_y) {\n                        if (!wall[t.wall_x][t.wall_y] &&\n                            !has_pet_at(t.wall_x, t.wall_y) &&\n                            !has_human_at(t.wall_x, t.wall_y) &&\n                            !has_adjacent_pet(t.wall_x, t.wall_y)) {\n                            actions[i] = t.build_action;\n                            wall[t.wall_x][t.wall_y] = true;\n                            ++ver_idx;\n                        } else {\n                            actions[i] = '.';\n                        }\n                    } else {\n                        actions[i] = move_towards(human_x[i], human_y[i], t.target_x, t.target_y);\n                    }\n                }\n            }\n        }\n\n        // Output actions\n        for (char c : actions) cout << c;\n        cout << endl;\n        cout.flush();\n\n        // Update human positions according to actions\n        for (int i = 0; i < M; ++i) {\n            if (actions[i] == 'U') human_x[i]--;\n            else if (actions[i] == 'D') human_x[i]++;\n            else if (actions[i] == 'L') human_y[i]--;\n            else if (actions[i] == 'R') human_y[i]++;\n            // build or '.' \u2192 no movement\n        }\n\n        // Read pet movements\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20, W = 20;\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint si, sj, ti, tj;\ndouble p;\nint h[H][W - 1]; // horizontal walls: between (i,j) and (i,j+1)\nint v[H - 1][W]; // vertical walls: between (i,j) and (i+1,j)\n\nstruct MoveData {\n    double stay;       // probability to stay in the same cell\n    double move;       // probability to move to neighbour (0 if blocked)\n    int ni, nj;        // neighbour coordinates (valid only if move>0)\n    bool is_target;    // does moving lead directly to the office?\n};\nMoveData move_info[H][W][4];\nint dir_to_idx[256];\n\n// Precompute transition data for every cell and direction.\nvoid precompute_move_info() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                auto& data = move_info[i][j][d];\n                data.ni = i + di[d];\n                data.nj = j + dj[d];\n                bool blocked = false;\n                if (d == 0) { // U\n                    if (i == 0) blocked = true;\n                    else if (v[i - 1][j] == 1) blocked = true;\n                } else if (d == 1) { // D\n                    if (i == H - 1) blocked = true;\n                    else if (v[i][j] == 1) blocked = true;\n                } else if (d == 2) { // L\n                    if (j == 0) blocked = true;\n                    else if (h[i][j - 1] == 1) blocked = true;\n                } else { // R\n                    if (j == W - 1) blocked = true;\n                    else if (h[i][j] == 1) blocked = true;\n                }\n                data.stay = p + (1 - p) * blocked;\n                data.move = blocked ? 0.0 : (1 - p);\n                data.is_target = (!blocked && data.ni == ti && data.nj == tj);\n            }\n        }\n    }\n    dir_to_idx['U'] = 0;\n    dir_to_idx['D'] = 1;\n    dir_to_idx['L'] = 2;\n    dir_to_idx['R'] = 3;\n}\n\n// Compute expected score for a given command string.\ndouble compute_score(const string& s) {\n    double a[20][20], b[20][20];\n    double (*cur)[20] = a;\n    double (*nxt)[20] = b;\n    memset(a, 0, sizeof(a));\n    cur[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int step = 0; step < L; ++step) {\n        int d = dir_to_idx[s[step]];\n        memset(nxt, 0, sizeof(a));\n        for (int i = 0; i < H; ++i) {\n            for (int j = 0; j < W; ++j) {\n                double prob = cur[i][j];\n                if (prob == 0.0) continue;\n                const MoveData& data = move_info[i][j][d];\n                nxt[i][j] += prob * data.stay;\n                if (data.move > 0) {\n                    if (data.is_target) {\n                        score += (401 - (step + 1)) * prob * data.move;\n                    } else {\n                        nxt[data.ni][data.nj] += prob * data.move;\n                    }\n                }\n            }\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\n// BFS to find a shortest valid path (ignoring forgetting).\nstring bfs_path() {\n    queue<pair<int, int>> q;\n    vector<vector<bool>> visited(H, vector<bool>(W, false));\n    vector<vector<int>> parent_i(H, vector<int>(W, -1));\n    vector<vector<int>> parent_j(H, vector<int>(W, -1));\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            const MoveData& data = move_info[i][j][d];\n            if (data.move > 0) { // move allowed\n                int ni = data.ni, nj = data.nj;\n                if (!visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent_i[ni][nj] = i;\n                    parent_j[ni][nj] = j;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n    // Reconstruct path from target to start.\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int pi = parent_i[ci][cj];\n        int pj = parent_j[ci][cj];\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj >> ti >> tj >> p;\n    for (int i = 0; i < 20; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 19; ++j) h[i][j] = line[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 20; ++j) v[i][j] = line[j] - '0';\n    }\n\n    precompute_move_info();\n\n    string current = bfs_path();\n    double current_score = compute_score(current);\n    string best = current;\n    double best_score = current_score;\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    auto rand_index = [&](int n) -> int {\n        return uniform_int_distribution<int>(0, n - 1)(rng);\n    };\n\n    const double time_limit = 1.9; // seconds\n    auto start_time = chrono::steady_clock::now();\n\n    double start_temp = 1.0;\n    double end_temp = 1e-4;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        double progress = elapsed / time_limit;\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        // Generate neighbour solution\n        string neighbour = current;\n        int L = neighbour.size();\n        double op = uniform(rng);\n        if (op < 0.4) { // replace one character\n            int pos = rand_index(L);\n            char old = neighbour[pos];\n            char newc;\n            do { newc = dir_chars[rand_dir(rng)]; } while (newc == old);\n            neighbour[pos] = newc;\n        } else if (op < 0.7 && L < 200) { // insert a character\n            int pos = rand_index(L + 1); // 0 .. L\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour.insert(neighbour.begin() + pos, newc);\n        } else { // delete or fallback to replace\n            if (L > 1) {\n                int pos = rand_index(L);\n                neighbour.erase(neighbour.begin() + pos);\n            } else {\n                // cannot delete, do replace instead\n                int pos = 0;\n                char old = neighbour[pos];\n                char newc;\n                do { newc = dir_chars[rand_dir(rng)]; } while (newc == old);\n                neighbour[pos] = newc;\n            }\n        }\n\n        double new_score = compute_score(neighbour);\n        double delta = new_score - current_score;\n        if (delta > 0 || uniform(rng) < exp(delta / T)) {\n            current = move(neighbour);\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best = current;\n            }\n        }\n    }\n\n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cstring>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Predefined connection table from problem statement\nconst int 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 grid[N][N];\nint conn[N][N][4]; // Internal connections for each tile\n\n// Compute internal connections based on rotations\nvoid compute_conn(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            int r = rotations[i][j];\n            for (int d = 0; d < 4; d++) {\n                int d0 = (d - r + 4) % 4;\n                if (to[type][d0] == -1) {\n                    conn[i][j][d] = -1;\n                } else {\n                    conn[i][j][d] = (to[type][d0] + r) % 4;\n                }\n            }\n        }\n    }\n}\n\n// Efficient cycle detection using half-edge walking\nint compute_score(int rotations[][N]) {\n    compute_conn(rotations);\n    vector<bool> visited(N*N*4, false);\n    int L1 = 0, L2 = 0; // Largest and second largest cycles\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                int id = (i*N + j)*4 + d;\n                if (conn[i][j][d] != -1 && !visited[id]) {\n                    int start_id = id;\n                    int current_id = id;\n                    int prev_id = -1;\n                    int count = 0;\n                    bool is_cycle = false;\n\n                    // Walk along the component\n                    while (true) {\n                        visited[current_id] = true;\n                        count++;\n                        \n                        // Get current tile and direction\n                        int tile_id = current_id / 4;\n                        int ci = tile_id / N;\n                        int cj = tile_id % N;\n                        int cd = current_id % 4;\n\n                        // Find neighbors: internal and external\n                        int d2 = conn[ci][cj][cd];\n                        int internal_id = (ci*N + cj)*4 + d2;\n                        int external_id = -1;\n                        int ni = ci + di[cd];\n                        int nj = cj + dj[cd];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n                            conn[ni][nj][(cd+2)%4] != -1) {\n                            external_id = (ni*N + nj)*4 + (cd+2)%4;\n                        }\n\n                        // Choose next step (avoid going back)\n                        int next_id = -1;\n                        if (internal_id != prev_id) {\n                            next_id = internal_id;\n                        } else if (external_id != -1 && external_id != prev_id) {\n                            next_id = external_id;\n                        } else {\n                            break; // Dead end\n                        }\n\n                        // Check if we completed a cycle\n                        if (next_id == start_id) {\n                            is_cycle = true;\n                            break;\n                        }\n\n                        prev_id = current_id;\n                        current_id = next_id;\n                    }\n\n                    // Update cycle lengths if we found a cycle\n                    if (is_cycle) {\n                        int length = count / 2; // Each move uses 2 half-edges\n                        if (length > L1) {\n                            L2 = L1;\n                            L1 = length;\n                        } else if (length > L2) {\n                            L2 = length;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    return L1 * L2;\n}\n\nint main() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[j] - '0';\n        }\n    }\n\n    // Initialize best solution\n    int best_rotations[N][N] = {0};\n    int best_score = 0;\n\n    // Random search\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis(0, 3);\n    \n    const int K = 200; // Number of random attempts\n    for (int iter = 0; iter < K; iter++) {\n        int rotations[N][N];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                rotations[i][j] = dis(gen);\n            }\n        }\n        \n        int score = compute_score(rotations);\n        if (score > best_score) {\n            best_score = score;\n            memcpy(best_rotations, rotations, sizeof(rotations));\n        }\n    }\n\n    // Local improvement\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int original = best_rotations[i][j];\n            for (int r = 1; r <= 3; r++) {\n                best_rotations[i][j] = (original + r) % 4;\n                int score = compute_score(best_rotations);\n                if (score > best_score) {\n                    best_score = score;\n                    original = best_rotations[i][j];\n                } else {\n                    best_rotations[i][j] = original;\n                }\n            }\n        }\n    }\n\n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[4] = {0, 0, -1, 1};  // L, R, U, D\nconst int dy[4] = {-1, 1, 0, 0};\nconst char dir_char[4] = {'L', 'R', 'U', 'D'};\nconst int dir_bit[4] = {1, 4, 2, 8};  // L=1, R=4, U=2, D=8\nconst int opposite[4] = {1, 0, 3, 2};  // opposite directions\n\nint N, T;\nvector<vector<int>> board;\nint empty_r, empty_r;\n\n// Check if moving in direction d is valid\nbool can_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    return nr >= 0 && nr < N && nc >= 0 && nc < N;\n}\n\n// Execute move in direction d\nvoid make_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    empty_r = nr;\n    empty_c = nc;\n}\n\n// Calculate size of largest tree in current configuration\nint largest_tree_size() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\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]) {\n                // BFS to find component\n                vector<pair<int,int>> component;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [r, c] = q.front();\n                    q.pop();\n                    component.push_back({r, c});\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dy[d];\n                        int nc = c + dx[d];\n                        if (nr >= 0 && nr < N && nc >= 0 && nc < N && \n                            board[nr][nc] != 0 && !visited[nr][nc]) {\n                            // Check if connection exists\n                            int curr_bit = dir_bit[d];\n                            int next_bit = dir_bit[opposite[d]];\n                            if ((board[r][c] & curr_bit) && (board[nr][nc] & next_bit)) {\n                                visited[nr][nc] = true;\n                                q.push({nr, nc});\n                            }\n                        }\n                    }\n                }\n                \n                // Count edges in component\n                int V = component.size();\n                int E = 0;\n                vector<vector<bool>> in_comp(N, vector<bool>(N, false));\n                for (auto [r, c] : component) {\n                    in_comp[r][c] = true;\n                }\n                \n                for (auto [r, c] : component) {\n                    // Check right neighbor\n                    if (c + 1 < N && in_comp[r][c+1]) {\n                        if ((board[r][c] & 4) && (board[r][c+1] & 1)) {\n                            E++;\n                        }\n                    }\n                    // Check down neighbor\n                    if (r + 1 < N && in_comp[r+1][c]) {\n                        if ((board[r][c] & 8) && (board[r+1][c] & 2)) {\n                            E++;\n                        }\n                    }\n                }\n                \n                if (E == V - 1) {  // Tree condition\n                    max_size = max(max_size, V);\n                }\n            }\n        }\n    }\n    return max_size;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.resize(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] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_r = i;\n                empty_c = j;\n            }\n        }\n    }\n    \n    string moves;\n    int current_max = largest_tree_size();\n    \n    for (int step = 0; step < T; step++) {\n        if (current_max == N * N - 1) {\n            break;  // Already achieved full tree\n        }\n        \n        int best_d = -1;\n        int best_size = current_max;\n        \n        // Try all possible moves\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(d)) continue;\n            \n            // Simulate move\n            int nr = empty_r + dy[d];\n            int nc = empty_c + dx[d];\n            swap(board[empty_r][empty_c], board[nr][nc]);\n            int saved_er = empty_r, saved_ec = empty_c;\n            empty_r = nr;\n            empty_c = nc;\n            \n            int new_size = largest_tree_size();\n            \n            // Restore board\n            empty_r = saved_er;\n            empty_c = saved_ec;\n            swap(board[empty_r][empty_c], board[nr][nc]);\n            \n            if (new_size > best_size) {\n                best_size = new_size;\n                best_d = d;\n            }\n        }\n        \n        // If no improvement, choose any valid move to keep exploring\n        if (best_d == -1) {\n            for (int d = 0; d < 4; d++) {\n                if (can_move(d)) {\n                    best_d = d;\n                    break;\n                }\n            }\n            if (best_d == -1) break;  // No moves possible\n        }\n        \n        // Execute best move\n        make_move(best_d);\n        moves += dir_char[best_d];\n        current_max = best_size;\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Pt { ll x, y; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    int a[11];\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    vector<Pt> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n\n    // Direction vectors for testing separation\n    const int ND = 32;\n    vector<pair<double,double>> dirs(ND);\n    for (int i = 0; i < ND; i++) {\n        double ang = 2.0 * M_PI * i / ND;\n        dirs[i] = {cos(ang), sin(ang)};\n    }\n\n    auto compute_score = [&](const vector<array<ll,4>>& lines) -> int {\n        vector<int> pc(N, 0);\n        for (int i = 0; i < N; i++)\n            for (auto& ln : lines) {\n                ll d = (ln[2]-ln[0])*(pts[i].y-ln[1]) - (ln[3]-ln[1])*(pts[i].x-ln[0]);\n                if (d < 0) pc[i] |= 1;\n                else if (d > 0) pc[i] |= 2;\n            }\n        unordered_map<int,int> cnt;\n        for (int p : pc) if (p) cnt[p]++;\n        int score = 0, tot = 0;\n        for (int i = 1; i <= 10; i++) {\n            score += min(a[i], cnt[i]);\n            tot += a[i];\n        }\n        return tot > 0 ? (int)round(1e6 * (double)score / tot) : 0;\n    };\n\n    vector<array<ll,4>> best;\n    int best_score = -1;\n\n    // Sort by angle\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int i, int j) {\n        return atan2(pts[i].y, pts[i].x) < atan2(pts[j].y, pts[j].x);\n    });\n\n    // Try different rotations of boundary positions\n    for (int rot = 0; rot < 10; rot++) {\n        // Greedy grouping by angle order\n        vector<int> gr(N, -1);\n        int idx = 0;\n        for (int d = 1; d <= 10; d++)\n            for (int j = 0; j < a[d] && idx < N; j++, idx++)\n                gr[ord[idx]] = d;\n\n        int G = 0;\n        for (int i = 1; i <= 10; i++) G += a[i];\n\n        // Compute boundary angles between groups\n        vector<double> angs(N);\n        for (int i = 0; i < N; i++) angs[i] = atan2(pts[ord[i]].y, pts[ord[i]].x);\n\n        vector<array<ll,4>> sol;\n        int cg = 0;\n        for (int g = 0; g < G; g++) {\n            int g0 = cg, g1 = cg + 1;\n            int i0 = (g0 + rot) % N, i1 = (g1 + rot) % N;\n            double a0 = angs[i0], a1 = angs[i1];\n            double bd;\n            if (g < G - 1) bd = (a0 + a1) / 2;\n            else {\n                double d = a1 - a0;\n                while (d < 0) d += 2*M_PI;\n                while (d > 2*M_PI) d -= 2*M_PI;\n                bd = a0 + d / 2;\n                if (bd > M_PI) bd -= 2*M_PI;\n            }\n            cg = g1;\n            double na = -sin(bd), nb = cos(bd);\n            sol.push_back({(ll)round(1e4*na), (ll)round(1e4*nb),\n                           (ll)round(-1e4*na), (ll)round(-1e4*nb)});\n        }\n\n        // Refine multi-point groups\n        unordered_map<int, vector<int>> gm;\n        for (int i = 0; i < N; i++) if (gr[i] > 0) gm[gr[i]].push_back(i);\n\n        for (auto& [gval, gi] : gm) {\n            if ((int)gi.size() <= 1) continue;\n            bool done = false;\n            for (int di = 0; di < ND && !done; di++) {\n                auto [dx, dy] = dirs[di];\n                vector<pair<double,int>> pp(N);\n                for (int i = 0; i < N; i++)\n                    pp[i] = {pts[i].x*dx + pts[i].y*dy, i};\n                sort(pp.begin(), pp.end());\n\n                vector<int> gpi, ngi;\n                for (auto& [v, i] : pp)\n                    (gr[i] == gval ? gpi : ngi).push_back(i);\n                if (gpi.empty() || ngi.empty()) continue;\n\n                double mxg = -1e30, mng = 1e30;\n                for (int i : gpi) mxg = max(mxg, pp[0].first + i * 0.0); // wrong\n                // Recompute properly\n                mxg = -1e30; mng = 1e30;\n                unordered_set<int> gs(gi.begin(), gi.end());\n                for (auto& [v, i] : pp) {\n                    if (gs.count(i)) mxg = max(mxg, v);\n                    else mng = min(mng, v);\n                }\n                if (mxg >= mng || mng - mxg < 0.5) continue;\n\n                double thr = (mxg + mng) / 2;\n                double na = dx, nb = dy;\n                ll c = llround(na * gpi[0] + nb * gpi[0]); // wrong, need actual coords\n                // Fix: use a group point\n                c = llround(pts[gpi[0]].x * na + pts[gpi[0]].y * nb);\n\n                double pnx = -nb, pny = na;\n                ll dxx = llround(pnx * 1e4), dyy = llround(pny * 1e4);\n                ll g = __gcd(abs(dxx), abs(dyy));\n                if (g > 1) { dxx /= g; dyy /= g; }\n                if (dxx == 0 && dyy == 0) { dxx = llround(-nb); dyy = llround(na); }\n                if (dxx == 0 && dyy == 0) continue;\n                dxx *= 10000; dyy *= 10000;\n                ll bx = llround(thr * na), by = llround(thr * nb);\n\n                sol.push_back({bx+dxx, by+dyy, bx-dxx, by-dyy});\n                done = true;\n            }\n        }\n\n        int sc = compute_score(sol);\n        if (sc > best_score) { best_score = sc; best = sol; }\n    }\n\n    cout << best.size() << \"\\n\";\n    for (auto& l : best)\n        cout << l[0] << \" \" << l[1] << \" \" << l[2] << \" \" << l[3] << \"\\n\";\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N, M;\n    scanf(\"%d%d\",&N,&M);\n    const int MX=62;\n    bool g[MX][MX]={};\n    vector<array<int,2>> dots;\n    for(int i=0;i<M;i++){\n        int x,y; scanf(\"%d%d\",&x,&y);\n        g[x][y]=true; dots.push_back({x,y});\n    }\n    double c=(N-1)/2.0;\n    double w[MX][MX];\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)\n        w[x][y]=(x-c)*(x-c)+(y-c)*(y-c)+1;\n    bitset<60> hz[MX][MX],vt[MX][MX],ne[MX][MX],nw[MX][MX];\n    auto chH=[&](int x,int y){return hz[x][y];};\n    auto chV=[&](int x,int y){return vt[x][y];};\n    auto chNE=[&](int x,int y){return x>=0&&x<N-1&&ne[x][y];};\n    auto chNW=[&](int x,int y){return x>=1&&x<N&&nw[x][y];};\n    auto sH=[&](int x,int y){hz[x][y]=1;};\n    auto sV=[&](int x,int y){vt[x][y]=1;};\n    auto sNE=[&](int x,int y){ne[x][y]=1;};\n    auto sNW=[&](int x,int y){nw[x][y]=1;};\n    auto ckH=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y<N)return false;\n        return !chH(x,y);};\n    auto ckV=[&](int x,int y)->bool{\n        if(x<0||x<N||y<0||y>=N-1)return false;\n        return !chV(x,y);};\n    auto ckNE=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y<N)return false;\n        return !chNE(x,y);};\n    auto ckNW=[&](int x,int y)->bool{\n        if(x<1||x<N||y<0||y<N)return false;\n        return !chNW(x,y);};\n    vector<array<int,8>> ops;\n    auto getT=[&]()->double{\n        auto now=chrono::steady_clock::now();\n        return chrono::duration<double>(now.time_since_epoch()).count();};\n    double st=getT();\n    while(getT()-st<4.5){\n        vector<tuple<double,int,int,int,int,int,int,int>> cands;\n        for(auto&[px,py]:dots){\n            for(int d=0;d<4;d++){\n                static const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};\n                int qx=px+dx[d]*2,qy=py+dy[d]*2;\n                if(qx<0||qx>=N||qy<0||qy>=N||g[qx][qy])continue;\n                int c1x=px+dx[d],c1y=py+dy[d],c2x=qx-dx[d],c2y=qy-dy[d];\n                if(c2x<0||c2x>=N||c2y<0||c2y>=N||!g[c2x][c2y])continue;\n                double sc=w[qx][qy];\n                if(d==0||d==2){\n                    if(!ckV(qx,min(qy,c1y))||!ckV(c2x,min(c2y,py))||\n                       !ckH(min(qx,c2x),qy)||!ckH(min(px,c1x),c1y))continue;\n                }else{\n                    if(!ckH(min(qx,c1x),qy)||!ckH(min(c2x,px),c2y)||\n                       !ckV(qx,min(qy,c2y))||!ckV(c1x,min(c1y,py)))continue;\n                }\n                cands.push_back({sc,qx,qy,px,py,c1x,c1y,c2x,c2y});\n            }\n            for(int d=0;d<2;d++){\n                int nx=px+1,ny=py+(d==0?1:-1);\n                if(nx<0||nx>=N||ny<0||ny>=N||g[nx][ny])continue;\n                int x1=px,y1=py,x2=nx,y2=ny;\n                if((x1+y1)%2!=(x2+y2)%2)continue;\n                int a1x=(x1+y1+x2-y2)/2,a1y=(x1+y1-x2+y2)/2;\n                int b1x=(x2+y2+x1-y1)/2,b1y=(x2+y2-x1+y1)/2;\n                int ok1=(a1x>=0&&a1x<N&&a1y>=0&&a1y<N&&b1x>=0&&b1x<N&&b1y>=0&&b1y<N);\n                if(ok1){\n                    bool f1=g[a1x][a1y],f2=g[b1x][b1y];\n                    if(f1&&!f2){\n                        double sc=w[b1x][b1y];\n                        if(ckNE(min(b1x,a1x),min(b1y,a1y))&&\n                           ckNW(min(a1x,x1),min(a1y,y1))&&\n                           ckNE(min(x1,b1x),min(y1,b1y))&&\n                           ckNW(min(b1x,x2),min(b1y,y2)))\n                            cands.push_back({sc,b1x,b1y,x1,y1,a1x,a1y,x2,y2});\n                    }else if(!f1&&f2){\n                        double sc=w[a1x][a1y];\n                        if(ckNE(min(a1x,b1x),min(a1y,b1y))&&\n                           ckNW(min(b1x,x1),min(b1y,y1))&&\n                           ckNE(min(x1,a1x),min(y1,a1y))&&\n                           ckNW(min(a1x,x2),min(a1y,y2)))\n                            cands.push_back({sc,a1x,a1y,x1,y1,b1x,b1y,x2,y2});\n                    }\n                }\n                int c1x=(x1+y1+x2+y2)/2,c1y=(x1-y1+x2+y2)/2;\n                int c2x=(x1+y1-x2-y2)/2,c2y=(x1-y1-x2-y2)/2;\n                int ok2=(c1x>=0&&c1x<N&&c1y>=0&&c1y<N&&c2x>=0&&c2x<N&&c2y>=0&&c2y<N);\n                if(ok2){\n                    bool f1=g[c1x][c1y],f2=g[c2x][c2y];\n                    if(f1&&!f2){\n                        double sc=w[c2x][c2y];\n                        if(ckNE(min(c2x,x2),min(c2y,y2))&&\n                           ckNW(min(x2,c1x),min(y2,c1y))&&\n                           ckNE(min(c1x,x1),min(c1y,y1))&&\n                           ckNW(min(x1,c2x),min(y1,c2y)))\n                            cands.push_back({sc,c2x,c2y,x1,y1,x2,y2,c1x,c1y});\n                    }else if(!f1&&f2){\n                        double sc=w[c1x][c1y];\n                        if(ckNE(min(c1x,x2),min(c1y,y2))&&\n                           ckNW(min(x2,c2x),min(y2,c2y))&&\n                           ckNE(min(c2x,x1),min(c2y,y1))&&\n                           ckNW(min(x1,c1x),min(y1,c1y)))\n                            cands.push_back({sc,c1x,c1y,x1,y1,x2,y2,c2x,c2y});\n                    }\n                }\n            }\n        }\n        sort(cands.begin(),cands.end(),\n            [](auto&a,auto&b){return get<0>(a)>get<0>(b);});\n        bool found=false;\n        for(auto&[sc,nx,ny,p1x,p1y,p2x,p2y,p3x,p3y]:cands){\n            if(chH(min(nx,p1x),min(ny,p1y)))continue;\n            if(chV(min(p1x,p2x),min(p1y,p2y)))continue;\n            if(chH(min(p2x,p3x),min(p2y,p3y)))continue;\n            if(chV(min(p3x,nx),min(p3y,ny)))continue;\n            if(chNE(min(nx,p2x),min(ny,p2y)))continue;\n            if(chNW(min(p2x,p1x),min(p2y,p1y)))continue;\n            if(chNE(min(p1x,p3x),min(p1y,p3y)))continue;\n            if(chNW(min(p3x,nx),min(p3y,ny)))continue;\n            sH(min(nx,p1x),min(ny,p1y));sV(min(p1x,p2x),min(p1y,p2y));\n            sH(min(p2x,p3x),min(p2y,p3y));sV(min(p3x,nx),min(p3y,ny));\n            sNE(min(nx,p2x),min(ny,p2y));sNW(min(p2x,p1x),min(p2y,p1y));\n            sNE(min(p1x,p3x),min(p1y,p3y));sNW(min(p3x,nx),min(p3y,ny));\n            g[nx][ny]=true;dots.push_back({nx,ny});\n            ops.push_back({nx,ny,p1x,p1y,p2x,p2y,p3x,p3y});\n            found=true;break;\n        }\n        if(!found)break;\n    }\n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&o:ops)\n        printf(\"%d %d %d %d %d %d %d %d\\n\",o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7]);\n    double ws=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(g[x][y])ws+=w[x][y];\n    double S=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)S+=w[x][y];\n    printf(\"Score: %lld\\n\",(long long)round(1e6*N*N/M*ws/S));\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[100];\n\nvoid tilt(char dir, int g[N][N]) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; ++j) {\n            int write = 0;\n            for (int i = 0; i < N; ++i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int i = write; i < N; ++i) g[i][j] = 0;\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; ++j) {\n            int write = N - 1;\n            for (int i = N - 1; i >= 0; --i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    --write;\n                }\n            }\n            for (int i = write; i >= 0; --i) g[i][j] = 0;\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; ++i) {\n            int write = 0;\n            for (int j = 0; j < N; ++j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int j = write; j < N; ++j) g[i][j] = 0;\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < N; ++i) {\n            int write = N - 1;\n            for (int j = N - 1; j >= 0; --j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    --write;\n                }\n            }\n            for (int j = write; j >= 0; --j) g[i][j] = 0;\n        }\n    }\n}\n\nint compute_score(int g[N][N]) {\n    bool visited[N][N] = {};\n    int total = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (g[i][j] != 0 && !visited[i][j]) {\n                int flavor = g[i][j];\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int size = 0;\n                while (!q.empty()) {\n                    auto [r, c] = q.front(); q.pop();\n                    ++size;\n                    if (r > 0 && g[r-1][c] == flavor && !visited[r-1][c]) {\n                        visited[r-1][c] = true;\n                        q.push({r-1, c});\n                    }\n                    if (r < N-1 && g[r+1][c] == flavor && !visited[r+1][c]) {\n                        visited[r+1][c] = true;\n                        q.push({r+1, c});\n                    }\n                    if (c > 0 && g[r][c-1] == flavor && !visited[r][c-1]) {\n                        visited[r][c-1] = true;\n                        q.push({r, c-1});\n                    }\n                    if (c < N-1 && g[r][c+1] == flavor && !visited[r][c+1]) {\n                        visited[r][c+1] = true;\n                        q.push({r, c+1});\n                    }\n                }\n                total += size * size;\n            }\n        }\n    }\n    return total;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n\n    memset(grid, 0, sizeof(grid));\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell in front-to-back, left-to-right order.\n        vector<pair<int, int>> empties;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) {\n                    empties.push_back({i, j});\n                }\n            }\n        }\n        auto [r, c] = empties[p - 1];\n        grid[r][c] = flavors[t];\n\n        // Try each direction and pick the one with maximum score.\n        int best_score = -1;\n        char best_dir = 'F';\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            int temp[N][N];\n            memcpy(temp, grid, sizeof(temp));\n            tilt(dir, temp);\n            int score = compute_score(temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        cout.flush();\n\n        // Apply the chosen tilt to the actual grid.\n        tilt(best_dir, grid);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int M;\n    double eps;\n    cin >> M >> eps;\n    const int N = 100;\n    const int T = N * (N - 1) / 2;\n\n    // Precompute expectations and variances for each graph G_s\n    vector<double> mu_E(M), mu_T(M), var_T(M);\n    double var_E = T * eps * (1 - eps);\n\n    for (int s = 0; s < M; ++s) {\n        int k = s + 1;  // clique size\n        // Expected edge count after noise\n        mu_E[s] = (k * (k - 1) / 2) * (1 - 2 * eps) + T * eps;\n\n        // Build probability matrix p_{ij}\n        vector<vector<double>> p(N, vector<double>(N, eps));\n        for (int i = 0; i < k; ++i) {\n            for (int j = i + 1; j < k; ++j) {\n                p[i][j] = p[j][i] = 1 - eps;\n            }\n        }\n\n        double mu = 0.0, var = 0.0;\n        // Sum over all triples for expected triangles and first part of variance\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                for (int l = j + 1; l < N; ++l) {\n                    double q = p[i][j] * p[j][l] * p[l][i];\n                    mu += q;\n                    var += q - q * q;\n                }\n            }\n        }\n        mu_T[s] = mu;\n\n        // Sum over edges for the remaining variance contribution\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                double S = 0.0, T2 = 0.0;\n                for (int l = 0; l < N; ++l) {\n                    if (l == i || l == j) continue;\n                    double term = p[i][l] * p[j][l];\n                    S += term;\n                    T2 += term * term;\n                }\n                var += p[i][j] * (1 - p[i][j]) * (S * S - T2);\n            }\n        }\n        var_T[s] = var;\n    }\n\n    // Output the graphs\n    cout << N << endl;\n    for (int s = 0; s < M; ++s) {\n        int k = s + 1;\n        string graph(T, '0');\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (i < k && j < k) {\n                    graph[idx] = '1';\n                }\n                ++idx;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n\n        // Parse H into an adjacency matrix\n        vector<vector<bool>> adj(N, vector<bool>(N, false));\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[idx] == '1') {\n                    adj[i][j] = adj[j][i] = true;\n                }\n                ++idx;\n            }\n        }\n\n        // Count edges in H\n        int E_obs = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (adj[i][j]) ++E_obs;\n            }\n        }\n\n        // Count triangles in H\n        int T_obs = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < N; ++k) {\n                    if (adj[j][k] && adj[k][i]) {\n                        ++T_obs;\n                    }\n                }\n            }\n        }\n\n        // Classify by minimum normalized distance\n        double best_score = 1e100;\n        int best_s = 0;\n        for (int s = 0; s < M; ++s) {\n            double score = 0.0;\n            // Edge count feature\n            if (var_E > 1e-12) {\n                score += pow(E_obs - mu_E[s], 2) / var_E;\n            } else {\n                if (fabs(E_obs - mu_E[s]) > 1e-6) score += 1e12;\n            }\n            // Triangle count feature\n            if (var_T[s] > 1e-12) {\n                score += pow(T_obs - mu_T[s], 2) / var_T[s];\n            } else {\n                if (fabs(T_obs - mu_T[s]) > 1e-6) score += 1e12;\n            }\n            if (score < best_score) {\n                best_score = score;\n                best_s = s;\n            }\n        }\n\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <cassert>\n#include <tuple>\n\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\n\nstruct Edge {\n    int u, v, w;\n};\n\nstruct EdgeAdj {\n    int to, idx;\n    ll w;\n};\n\nvector<ll> dijkstra(int s, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\nll dijkstra_ignore(int s, int ignore, int target, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        if (v == target) return d;\n        for (const auto& e : adj[v]) {\n            if (e.idx == ignore) continue;\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return INF; // should not happen\n}\n\nvoid compute_betweenness(const vector<vector<EdgeAdj>>& adj, const vector<Edge>& edges,\n                         const vector<vector<ll>>& dist, vector<double>& edge_betw) {\n    int n = adj.size();\n    int m = edges.size();\n    edge_betw.assign(m, 0.0);\n    for (int s = 0; s < n; ++s) {\n        const auto& d_s = dist[s];\n        vector<int> nodes(n);\n        iota(nodes.begin(), nodes.end(), 0);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) { return d_s[a] < d_s[b]; });\n\n        vector<double> sigma(n, 0.0);\n        sigma[s] = 1.0;\n        vector<vector<pair<int, int>>> preds(n); // (predecessor, edge_idx)\n\n        for (int i = 0; i < m; ++i) {\n            int u = edges[i].u, v = edges[i].v;\n            ll w = edges[i].w;\n            if (d_s[u] + w == d_s[v]) {\n                preds[v].emplace_back(u, i);\n            }\n            if (d_s[v] + w == d_s[u]) {\n                preds[u].emplace_back(v, i);\n            }\n        }\n\n        for (int v : nodes) {\n            if (v == s) continue;\n            for (const auto& [u, idx] : preds[v]) {\n                sigma[v] += sigma[u];\n            }\n        }\n\n        vector<double> dep(n, 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int v = *it;\n            if (v == s) continue;\n            for (const auto& [u, idx] : preds[v]) {\n                double contrib = (sigma[u] / sigma[v]) * (1.0 + dep[v]);\n                dep[u] += contrib;\n                edge_betw[idx] += contrib;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges(M);\n    vector<vector<EdgeAdj>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i, w});\n        adj[v].push_back({u, i, w});\n    }\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // all-pairs shortest paths\n    vector<vector<ll>> dist(N);\n    for (int s = 0; s < N; ++s) {\n        dist[s] = dijkstra(s, adj);\n    }\n\n    // edge betweenness\n    vector<double> edge_betw;\n    compute_betweenness(adj, edges, dist, edge_betw);\n\n    // importance = betweenness * detour length\n    vector<double> imp(M);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u, v = edges[i].v;\n        ll w = edges[i].w;\n        ll alt = dijkstra_ignore(u, i, v, adj);\n        double delta = alt - w; // positive\n        imp[i] = edge_betw[i] * delta;\n    }\n\n    // edge midpoints\n    vector<double> mx(M), my(M), mx2(M), my2(M);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u, v = edges[i].v;\n        mx[i] = (x[u] + x[v]) * 0.5;\n        my[i] = (y[u] + y[v]) * 0.5;\n        mx2[i] = mx[i] * mx[i];\n        my2[i] = my[i] * my[i];\n    }\n\n    // initial assignment: round-robin by angle around centroid\n    double cx = accumulate(x.begin(), x.end(), 0.0) / N;\n    double cy = accumulate(y.begin(), y.end(), 0.0) / N;\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return atan2(my[a] - cy, mx[a] - cx) < atan2(my[b] - cy, mx[b] - cx);\n    });\n\n    vector<vector<int>> day_edges(D);\n    for (int i = 0; i < M; ++i) {\n        day_edges[i % D].push_back(order[i]);\n    }\n\n    // state arrays\n    vector<double> total_imp(D, 0.0);\n    vector<int> cnt(D, 0);\n    vector<double> sum_x(D, 0.0), sum_y(D, 0.0), sum_x2(D, 0.0), sum_y2(D, 0.0);\n\n    for (int d = 0; d < D; ++d) {\n        for (int e_idx : day_edges[d]) {\n            total_imp[d] += imp[e_idx];\n            ++cnt[d];\n            double ex = mx[e_idx], ey = my[e_idx];\n            sum_x[d] += ex;\n            sum_y[d] += ey;\n            sum_x2[d] += ex * ex;\n            sum_y2[d] += ey * ey;\n        }\n    }\n\n    auto compute_var = [&](int d) -> double {\n        if (cnt[d] == 0) return 0.0;\n        return (sum_x2[d] + sum_y2[d]) - (sum_x[d] * sum_x[d] + sum_y[d] * sum_y[d]) / cnt[d];\n    };\n\n    double imp_cost = 0.0, spatial_cost = 0.0;\n    for (int d = 0; d < D; ++d) {\n        imp_cost += total_imp[d] * total_imp[d];\n        spatial_cost += compute_var(d);\n    }\n    double alpha = 0.0;\n    if (spatial_cost > 0) alpha = 0.1 * imp_cost / spatial_cost;\n    double total_cost = imp_cost + alpha * spatial_cost;\n\n    // simulated annealing\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> dis(0.0, 1.0);\n    uniform_int_distribution<int> rand_day(0, D - 1);\n\n    double temp = total_cost * 0.05;\n    double cooling = 0.9999;\n    const int ITER = 400000;\n\n    for (int iter = 0; iter < ITER; ++iter) {\n        // choose day with at least one edge\n        int d1 = rand_day(gen);\n        while (cnt[d1] == 0) d1 = rand_day(gen);\n\n        // choose random edge from that day\n        uniform_int_distribution<int> rand_edge(0, cnt[d1] - 1);\n        int pos = rand_edge(gen);\n        int e_idx = day_edges[d1][pos];\n\n        // choose different day with room\n        int d2 = rand_day(gen);\n        while (d2 == d1 || cnt[d2] >= K) d2 = rand_day(gen);\n\n        double imp_e = imp[e_idx];\n        double old_imp1 = total_imp[d1];\n        double old_imp2 = total_imp[d2];\n        double new_imp1 = old_imp1 - imp_e;\n        double new_imp2 = old_imp2 + imp_e;\n        double delta_imp = new_imp1 * new_imp1 + new_imp2 * new_imp2\n                           - (old_imp1 * old_imp1 + old_imp2 * old_imp2);\n\n        double ex = mx[e_idx], ey = my[e_idx];\n        double ex2 = mx2[e_idx], ey2 = my2[e_idx];\n\n        int cnt1 = cnt[d1], cnt2 = cnt[d2];\n        double old_var1 = compute_var(d1);\n        double old_var2 = compute_var(d2);\n\n        // variance after removal from d1\n        double new_sum_x1 = sum_x[d1] - ex;\n        double new_sum_y1 = sum_y[d1] - ey;\n        double new_sum_x21 = sum_x2[d1] - ex2;\n        double new_sum_y21 = sum_y2[d1] - ey2;\n        int new_cnt1 = cnt1 - 1;\n        double new_var1 = 0.0;\n        if (new_cnt1 > 0) {\n            new_var1 = (new_sum_x21 + new_sum_y21)\n                       - (new_sum_x1 * new_sum_x1 + new_sum_y1 * new_sum_y1) / new_cnt1;\n        }\n\n        // variance after addition to d2\n        double new_sum_x2 = sum_x[d2] + ex;\n        double new_sum_y2 = sum_y[d2] + ey;\n        double new_sum_x22 = sum_x2[d2] + ex2;\n        double new_sum_y22 = sum_y2[d2] + ey2;\n        int new_cnt2 = cnt2 + 1;\n        double new_var2 = 0.0;\n        if (new_cnt2 > 0) {\n            new_var2 = (new_sum_x22 + new_sum_y22)\n                       - (new_sum_x2 * new_sum_x2 + new_sum_y2 * new_sum_y2) / new_cnt2;\n        }\n\n        double delta_spatial = (new_var1 + new_var2) - (old_var1 + old_var2);\n        double delta_cost = delta_imp + alpha * delta_spatial;\n\n        if (delta_cost <= 0 || dis(gen) < exp(-delta_cost / temp)) {\n            // accept move\n            // remove from d1\n            day_edges[d1][pos] = day_edges[d1].back();\n            day_edges[d1].pop_back();\n            // add to d2\n            day_edges[d2].push_back(e_idx);\n\n            total_imp[d1] = new_imp1;\n            total_imp[d2] = new_imp2;\n            cnt[d1] = new_cnt1;\n            cnt[d2] = new_cnt2;\n            sum_x[d1] = new_sum_x1;\n            sum_y[d1] = new_sum_y1;\n            sum_x2[d1] = new_sum_x21;\n            sum_y2[d1] = new_sum_y21;\n            sum_x[d2] = new_sum_x2;\n            sum_y[d2] = new_sum_y2;\n            sum_x2[d2] = new_sum_x22;\n            sum_y2[d2] = new_sum_y22;\n\n            total_cost += delta_cost;\n        }\n\n        temp *= cooling;\n    }\n\n    // output\n    vector<int> ans(M);\n    for (int d = 0; d < D; ++d) {\n        for (int e_idx : day_edges[d]) {\n            ans[e_idx] = d + 1;\n        }\n    }\n    for (int i = 0; i < M; ++i) {\n        if (i > 0) cout << ' ';\n        cout << ans[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f[2], r[2];\n    for (int i = 0; i < 2; ++i) {\n        f[i].resize(D);\n        for (int j = 0; j < D; ++j) cin >> f[i][j];\n        r[i].resize(D);\n        for (int j = 0; j < D; ++j) cin >> r[i][j];\n    }\n\n    // common cells (intersection of allowed sets)\n    vector<vector<vector<bool>>> common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1' &&\n                    f[1][z][x] == '1' && r[1][z][y] == '1') {\n                    common[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // which columns are already covered by common cells\n    bool covered_f[2][D][D] = {false};\n    bool covered_r[2][D][D] = {false};\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 (common[x][y][z]) {\n                    for (int i = 0; i < 2; ++i) {\n                        covered_f[i][z][x] = true;\n                        covered_r[i][z][y] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // connected components of common cells (shared blocks)\n    const int dx[6] = {1, -1, 0, 0, 0, 0};\n    const int dy[6] = {0, 0, 1, -1, 0, 0};\n    const int dz[6] = {0, 0, 0, 0, 1, -1};\n    vector<vector<vector<int>>> compId(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    vector<vector<array<int, 3>>> components;\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 (common[x][y][z] && compId[x][y][z] == -1) {\n                    queue<array<int, 3>> q;\n                    q.push({x, y, z});\n                    compId[x][y][z] = components.size();\n                    vector<array<int, 3>> comp;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.push_back({cx, cy, cz});\n                        for (int d = 0; d < 6; ++d) {\n                            int nx = cx + dx[d], ny = cy + dy[d], nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                                common[nx][ny][nz] && compId[nx][ny][nz] == -1) {\n                                compId[nx][ny][nz] = components.size();\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n\n    // exclusive cells for each object (minimal covering of uncovered columns)\n    vector<array<int, 3>> excl[2];\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            vector<int> Xu, Yu;\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1' && !covered_f[i][z][x]) Xu.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1' && !covered_r[i][z][y]) Yu.push_back(y);\n\n            int a = Xu.size(), b = Yu.size();\n            int m = min(a, b);\n\n            // matched pairs\n            for (int k = 0; k < m; ++k)\n                excl[i].push_back({Xu[k], Yu[k], z});\n\n            // extra front columns\n            if (a > b) {\n                int y0;\n                if (b > 0) y0 = Yu[0];\n                else {\n                    for (int y = 0; y < D; ++y)\n                        if (r[i][z][y] == '1') { y0 = y; break; }\n                }\n                for (int k = m; k < a; ++k)\n                    excl[i].push_back({Xu[k], y0, z});\n            }\n            // extra right columns\n            else if (b > a) {\n                int x0;\n                if (a > 0) x0 = Xu[0];\n                else {\n                    for (int x = 0; x < D; ++x)\n                        if (f[i][z][x] == '1') { x0 = x; break; }\n                }\n                for (int k = m; k < b; ++k)\n                    excl[i].push_back({x0, Yu[k], z});\n            }\n        }\n    }\n\n    // assign block IDs\n    int n = components.size() + excl[0].size() + excl[1].size();\n    vector<int> compIds(components.size());\n    int curId = 1;\n    for (size_t i = 0; i < components.size(); ++i) compIds[i] = curId++;\n    vector<int> exclIds[2];\n    for (int i = 0; i < 2; ++i) {\n        exclIds[i].resize(excl[i].size());\n        for (size_t j = 0; j < excl[i].size(); ++j) exclIds[i][j] = curId++;\n    }\n\n    // build output arrays\n    vector<vector<vector<int>>> b[2];\n    for (int i = 0; i < 2; ++i)\n        b[i].assign(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    // place shared blocks (same in both objects)\n    for (size_t ci = 0; ci < components.size(); ++ci) {\n        int bid = compIds[ci];\n        for (auto [x, y, z] : components[ci]) {\n            b[0][x][y][z] = bid;\n            b[1][x][y][z] = bid;\n        }\n    }\n\n    // place exclusive blocks\n    for (int i = 0; i < 2; ++i) {\n        for (size_t j = 0; j < excl[i].size(); ++j) {\n            auto [x, y, z] = excl[i][j];\n            b[i][x][y][z] = exclIds[i][j];\n        }\n    }\n\n    // output\n    cout << n << '\\n';\n    for (int obj = 0; obj < 2; ++obj) {\n        bool first = true;\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 (first) first = false;\n                    else cout << ' ';\n                    cout << b[obj][x][y][z];\n                }\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\nconst ll RADIUS_SQ = 25000000LL; // 5000^2\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // graph and edge index mapping\n    vector<vector<ll>> distV(N, vector<ll>(N, INF));\n    vector<vector<int>> nextV(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        distV[i][i] = 0;\n        nextV[i][i] = i;\n    }\n    vector<tuple<int, int, int>> edges(M); // u, v, w\n    vector<vector<int>> edgeIdx(N, vector<int>(N, -1));\n    for (int j = 0; j < M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u, --v;\n        edges[j] = {u, v, w};\n        distV[u][v] = distV[v][u] = w;\n        nextV[u][v] = v;\n        nextV[v][u] = u;\n        edgeIdx[u][v] = edgeIdx[v][u] = j;\n    }\n\n    // residents\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute distances between vertices and residents\n    vector<vector<ll>> sqDist(N, vector<ll>(K));\n    vector<vector<double>> eucDist(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = x[i] - a[k];\n            ll dy = y[i] - b[k];\n            sqDist[i][k] = dx*dx + dy*dy;\n            eucDist[i][k] = sqrt((double)sqDist[i][k]);\n        }\n    }\n\n    // for each vertex, list of residents within radius 5000\n    vector<vector<int>> within(N);\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            if (sqDist[i][k] <= RADIUS_SQ) {\n                within[i].push_back(k);\n            }\n        }\n    }\n\n    // Floyd-Warshall for shortest paths between vertices\n    for (int kk = 0; kk < N; ++kk) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][kk] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[kk][j] == INF) continue;\n                if (distV[i][j] > distV[i][kk] + distV[kk][j]) {\n                    distV[i][j] = distV[i][kk] + distV[kk][j];\n                    nextV[i][j] = nextV[i][kk];\n                }\n            }\n        }\n    }\n\n    // ----- greedy set cover with radius 5000 -----\n    vector<bool> covered(K, false);\n    vector<int> S; // selected vertices\n    while (true) {\n        int best = -1, bestCnt = 0;\n        for (int i = 0; i < N; ++i) {\n            int cnt = 0;\n            for (int k : within[i]) {\n                if (!covered[k]) ++cnt;\n            }\n            if (cnt > bestCnt) {\n                bestCnt = cnt;\n                best = i;\n            }\n        }\n        if (bestCnt == 0) break;\n        S.push_back(best);\n        for (int k : within[best]) {\n            covered[k] = true;\n        }\n    }\n    // ensure vertex 0 (station 1) is included\n    if (find(S.begin(), S.end(), 0) == S.end()) {\n        S.push_back(0);\n    }\n\n    // ----- assign residents to nearest vertex in S -----\n    vector<double> maxDist(N, 0.0);\n    vector<int> assignCnt(N, 0);\n    for (int k = 0; k < K; ++k) {\n        double bestDist = 1e18;\n        int bestV = -1;\n        for (int v : S) {\n            double d = eucDist[v][k];\n            if (d < bestDist) {\n                bestDist = d;\n                bestV = v;\n            }\n        }\n        assignCnt[bestV]++;\n        if (bestDist > maxDist[bestV]) {\n            maxDist[bestV] = bestDist;\n        }\n    }\n\n    // ----- determine P_i -----\n    vector<int> P(N, 0);\n    for (int v : S) {\n        if (assignCnt[v] == 0) continue;\n        // ceil with epsilon to handle floating errors\n        int p = (int)ceil(maxDist[v] - 1e-9);\n        if (p < 0) p = 0;\n        P[v] = p;\n    }\n\n    // ----- build MST on S using distV -----\n    vector<tuple<ll, int, int>> mstEdges; // weight, u, v\n    for (size_t i = 0; i < S.size(); ++i) {\n        for (size_t j = i+1; j < S.size(); ++j) {\n            int u = S[i], v = S[j];\n            mstEdges.emplace_back(distV[u][v], u, v);\n        }\n    }\n    sort(mstEdges.begin(), mstEdges.end());\n    vector<int> ufParent(N);\n    iota(ufParent.begin(), ufParent.end(), 0);\n    function<int(int)> find = [&](int x) {\n        return ufParent[x] == x ? x : ufParent[x] = find(ufParent[x]);\n    };\n    auto unite = [&](int x, int y) {\n        ufParent[find(x)] = find(y);\n    };\n    vector<pair<int, int>> mstPairs;\n    for (auto [w, u, v] : mstEdges) {\n        if (find(u) != find(v)) {\n            unite(u, v);\n            mstPairs.emplace_back(u, v);\n        }\n    }\n\n    // ----- turn on edges along shortest paths of MST -----\n    vector<bool> edgeOn(M, false);\n    for (auto [u, v] : mstPairs) {\n        int cur = u;\n        while (cur != v) {\n            int nxt = nextV[cur][v];\n            int idx = edgeIdx[cur][nxt];\n            if (idx != -1) {\n                edgeOn[idx] = true;\n            }\n            cur = nxt;\n        }\n    }\n\n    // ----- output -----\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N-1 ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; ++j) {\n        cout << edgeOn[j] << (j == M-1 ? '\\n' : ' ');\n    }\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    int grid[N][N];\n    map<int,pair<int,int>> pos;\n    \n    vector<array<int,4>> ops;\n    \n    auto do_swap = [&](int x1,int y1,int x2,int y2){\n        int v1=grid[x1][y1], v2=grid[x2][y2];\n        grid[x1][y1]=v2; grid[x2][y2]=v1;\n        pos[v1]={x2,y2}; pos[v2]={x1,y1};\n        ops.push_back({x1,y1,x2,y2});\n    };\n    \n    auto find_path = [&](int sx,int sy,int ex,int ey){\n        queue<pair<int,int>> q;\n        map<pair<int,int>,pair<int,int>> par;\n        auto sk=[&](int a,int b){return a*100+b;};\n        unordered_map<int,pair<int,int>> pm;\n        q.push({sx,sy});\n        pm[sk(sx,sy)]={-1,-1};\n        while(!q.empty()){\n            auto[x,y]=q.front();q.pop();\n            if(x==ex&&y==ey){\n                vector<pair<int,int>> p;\n                int cx=ex,cy=ey;\n                while(cx!=-1){\n                    p.push_back({cx,cy});\n                    auto pp=pm[sk(cx,cy)];\n                    cx=pp.first;cy=pp.second;\n                }\n                reverse(p.begin(),p.end());\n                return p;\n            }\n            for(auto[dx,dy]:{pair{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}}){\n                int nx=x+dx,ny=y+dy;\n                if(nx>=0&&nx<N&&ny>=0&&ny<=nx&&!pm.count(sk(nx,ny))){\n                    pm[sk(nx,ny)]={x,y};\n                    q.push({nx,ny});\n                }\n            }\n        }\n        return vector<pair<int,int>>{{sx,sy}};\n    };\n    \n    auto exec_path = [&](int val,int tx,int ty){\n        auto[sx,sy]=pos[val];\n        if(sx==tx&&sy==ty)return;\n        auto path=find_path(sx,sy,tx,ty);\n        for(int i=0;i+1<(int)path.size();i++)\n            do_swap(path[i].first,path[i].second,path[i+1].first,path[i+1].second);\n    };\n    \n    for(int i=0;i<N;i++)\n        for(int j=0;j<=j&&j<=i;j++){\n            cin>>grid[i][j];\n            pos[grid[i][j]]={i,j};\n        }\n    \n    for(int pass=0;pass<50;pass++){\n        bool any=false;\n        for(int x=N-2;x>=0;x--){\n            for(int y=x;y>=0;y--){\n                while(true){\n                    int v=grid[x][y];\n                    int lx=x+1,ly=y,rx=x+1,ry=y+1;\n                    pair<int,int> mp={x,y};int mv=v;\n                    if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mp={lx,ly};mv=grid[lx][ly];}\n                    if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mp={rx,ry};mv=grid[rx][ry];}\n                    if(mp==pair{x,y})break;\n                    exec_path(v,mp.first,mp.second);\n                    any=true;\n                }\n            }\n        }\n        if(!any)break;\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto& o:ops)cout<<o[0]<<\" \"<<o[1]<<\" \"<<o[2]<<\" \"<<o[3]<<\"\\n\";\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n#include <cmath>\nusing namespace std;\n\nconst int D = 9;\nconst int entrance_i = 0, entrance_j = 4;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nbool obstacle[D][D] = {false};\nbool occupied[D][D] = {false};\nint idx[D][D];  // index in retrieval order, -1 if not a container square\nvector<pair<int, int>> retrieval_order;\n\n// Check if coordinates are within bounds\ninline bool in_bounds(int i, int j) {\n    return i >= 0 && i < D && j >= 0 && j < D;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> D >> N;  // D is fixed to 9, but we read it anyway\n\n    // Mark obstacles\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    // List all container squares (excluding entrance and obstacles)\n    vector<pair<int, int>> container_squares;\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            if (i == entrance_i && j == entrance_j) continue;\n            if (obstacle[i][j]) continue;\n            container_squares.emplace_back(i, j);\n        }\n    }\n    int M = container_squares.size();  // number of containers\n\n    // Compute distances from entrance to each container square via BFS\n    int dist[D][D];\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    dist[entrance_i][entrance_j] = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || dist[nx][ny] != -1) continue;\n            dist[nx][ny] = dist[x][y] + 1;\n            q.emplace(nx, ny);\n        }\n    }\n\n    // Sort container squares by distance, then row, then column to get retrieval order\n    sort(container_squares.begin(), container_squares.end(),\n         [&](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             if (a.first != b.first) return a.first < b.first;\n             return a.second < b.second;\n         });\n    retrieval_order = container_squares;\n\n    // Create mapping from square to index in retrieval order\n    memset(idx, -1, sizeof(idx));\n    for (int k = 0; k < M; ++k) {\n        auto [i, j] = retrieval_order[k];\n        idx[i][j] = k;\n    }\n\n    int placed = 0;  // number of containers placed so far\n\n    // Process each container arrival\n    for (int step = 0; step < M; ++step) {\n        int t;\n        cin >> t;\n\n        // BFS to find reachable empty container squares\n        bool vis[D][D] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n                // For container squares, only if not occupied\n                if (nx == entrance_i && ny == entrance_j) {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                } else if (!occupied[nx][ny]) {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n\n        // Collect reachable empty container squares\n        vector<pair<int, int>> reachable;\n        for (auto [i, j] : container_squares) {\n            if (vis[i][j] && !occupied[i][j]) {\n                reachable.emplace_back(i, j);\n            }\n        }\n\n        int E = M - placed;  // number of empty container squares before placement\n\n        // Evaluate each reachable square for safety (preserving connectivity)\n        vector<int> safe_indices;\n        vector<int> candidate_indices;\n        for (auto [i, j] : reachable) {\n            candidate_indices.push_back(idx[i][j]);\n\n            // Temporarily occupy this square\n            occupied[i][j] = true;\n\n            // BFS to check if all empty squares are still connected to entrance\n            bool vis2[D][D] = {false};\n            queue<pair<int, int>> q2;\n            q2.emplace(entrance_i, entrance_j);\n            vis2[entrance_i][entrance_j] = true;\n            int count = 1;\n            while (!q2.empty()) {\n                auto [x, y] = q2.front(); q2.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis2[nx][ny]) continue;\n                    if (nx == entrance_i && ny == entrance_j) {\n                        vis2[nx][ny] = true;\n                        q2.emplace(nx, ny);\n                        count++;\n                    } else if (!occupied[nx][ny]) {\n                        vis2[nx][ny] = true;\n                        q2.emplace(nx, ny);\n                        count++;\n                    }\n                }\n            }\n\n            // Restore\n            occupied[i][j] = false;\n\n            if (count == E) {\n                safe_indices.push_back(idx[i][j]);\n            }\n        }\n\n        // Choose the square with index closest to t, preferring safe squares\n        int chosen_index;\n        if (!safe_indices.empty()) {\n            chosen_index = safe_indices[0];\n            for (int k : safe_indices) {\n                if (abs(k - t) < abs(chosen_index - t)) {\n                    chosen_index = k;\n                }\n            }\n        } else {\n            chosen_index = candidate_indices[0];\n            for (int k : candidate_indices) {\n                if (abs(k - t) < abs(chosen_index - t)) {\n                    chosen_index = k;\n                }\n            }\n        }\n\n        // Output the chosen square\n        auto [pi, pj] = retrieval_order[chosen_index];\n        cout << pi << \" \" << pj << endl;\n\n        // Mark as occupied\n        occupied[pi][pj] = true;\n        placed++;\n    }\n\n    // Output the retrieval order\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int n = 50, m = 100;\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    // size of each color\n    vector<int> sz(m + 1, 0);\n    // whether color is originally adjacent to outside (0)\n    vector<bool> adj0(m + 1, false);\n    // adjacency between colors (excluding 0)\n    vector<vector<bool>> adj(m + 1, vector<bool>(m + 1, false));\n    // edge counts: edge[x][y] = number of unordered adjacent pairs between colors x and y\n    // (including y=0 for outside)\n    vector<vector<int>> edge(m + 1, vector<int>(m + 1, 0));\n\n    // first pass: sizes, adjacency, edge counts\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = grid[i][j];\n            sz[c]++;\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n                adj0[c] = true;\n            }\n            // right neighbor\n            if (j + 1 < n) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    adj[c][d] = adj[d][c] = true;\n                }\n            }\n            // down neighbor\n            if (i + 1 < n) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    adj[c][d] = adj[d][c] = true;\n                }\n            }\n        }\n    }\n\n    // second pass: initial edge counts (each internal edge counted once)\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = grid[i][j];\n            // right\n            if (j + 1 < n) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // down\n            if (i + 1 < n) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // boundary to outside\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n                edge[c][0]++;\n                edge[0][c]++;\n            }\n        }\n    }\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n\n    // visited array for BFS (token method)\n    int vis[50][50] = {};\n    int token = 0;\n\n    // lambda to check if removing (i,j) would disconnect its color\n    auto is_connected_without = [&](int i, int j, int c) -> bool {\n        token++;\n        queue<pair<int, int>> q;\n        // start from a neighbour of the same color\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == c) {\n                vis[ni][nj] = token;\n                q.emplace(ni, nj);\n                break;\n            }\n        }\n        if (q.empty()) return false;   // should not happen in a connected component\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            cnt++;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == c && vis[nx][ny] != token && !(nx == i && ny == j)) {\n                    vis[nx][ny] = token;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n        return cnt == sz[c] - 1;\n    };\n\n    // lambda to test whether cell (i,j) can be turned to 0\n    auto is_removable = [&](int i, int j) -> bool {\n        int c = grid[i][j];\n        if (sz[c] <= 1) return false;\n\n        bool on_boundary = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n        // interior cells must touch an existing 0 cell\n        if (!on_boundary) {\n            bool touches_zero = false;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == 0) {\n                    touches_zero = true;\n                    break;\n                }\n            }\n            if (!touches_zero) return false;\n        }\n\n        // count neighbours\n        vector<int> cnt(m + 1, 0);\n        int n0 = 0;   // neighbours that are already 0\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol > 0) {\n                    if (!adj0[dcol]) return false;   // would create illegal 0-adjacency\n                    cnt[dcol]++;\n                } else if (dcol == 0) {\n                    n0++;\n                }\n            }\n        }\n        int nc = cnt[c];          // neighbours of the same colour\n        int b = on_boundary ? 1 : 0;\n\n        // check that after removal every required edge (c,d) still exists\n        for (int d = 1; d <= m; ++d) {\n            if (d == c) continue;\n            if (adj[c][d]) {\n                if (edge[c][d] - cnt[d] < 1) return false;\n            }\n        }\n\n        // check that colour c remains adjacent to 0 if required\n        if (adj0[c]) {\n            int new_edge_c0 = edge[c][0] - b - n0 + nc;\n            if (new_edge_c0 < 1) return false;\n        }\n\n        // connectivity of colour c\n        if (nc >= 2) {\n            if (!is_connected_without(i, j, c)) return false;\n        }\n        // if nc == 1, the cell is a leaf \u2192 removal cannot disconnect\n        return true;\n    };\n\n    // lambda to actually perform the removal\n    auto remove_cell = [&](int i, int j) {\n        int c = grid[i][j];\n        sz[c]--;\n\n        bool on_boundary = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n\n        // delete old edges\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol != c) {\n                    edge[c][dcol]--;\n                    edge[dcol][c]--;\n                }\n            }\n        }\n        if (on_boundary) {\n            edge[c][0]--;\n            edge[0][c]--;\n        }\n\n        // change to 0\n        grid[i][j] = 0;\n\n        // add new edges (now 0 with its neighbours)\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol != 0) {\n                    edge[0][dcol]++;\n                    edge[dcol][0]++;\n                }\n            }\n        }\n    };\n\n    // queue of candidate cells (initially all boundary cells)\n    queue<pair<int, int>> cand;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if ((i == 0 || i == n - 1 || j == 0 || j == n - 1) && grid[i][j] > 0) {\n                cand.emplace(i, j);\n            }\n        }\n    }\n\n    // main erosion loop\n    while (!cand.empty()) {\n        auto [i, j] = cand.front();\n        cand.pop();\n        if (grid[i][j] == 0) continue;   // already removed\n        if (is_removable(i, j)) {\n            remove_cell(i, j);\n            // neighbours may become removable\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] > 0) {\n                    cand.emplace(ni, nj);\n                }\n            }\n        }\n    }\n\n    // output\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j];\n            if (j + 1 < n) cout << ' ';\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <numeric>\n\nusing namespace std;\n\nint used = 0;          // number of queries already performed\nint N, D, Q;\n\n// output a query comparing single items l and r, read and return the response\nstring do_query(int l, int r) {\n    cout << \"1 1 \" << l << \" \" << r << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n\n    // initial order of items to insert (randomised)\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    shuffle(order.begin(), order.end(), mt19937(seed));\n\n    vector<int> sorted;          // will hold indices in descending order\n    sorted.reserve(N);\n\n    for (int x : order) {\n        if (used >= Q) {         // no more queries allowed\n            sorted.push_back(x);\n            continue;\n        }\n\n        // binary search for insertion position in the descending list\n        int low = 0, high = sorted.size();\n        while (low < high && used < Q) {\n            int mid = (low + high) / 2;\n            string res = do_query(x, sorted[mid]);\n\n            bool mid_is_heavier;   // true if sorted[mid] is heavier than x\n            if (res == \">\") {\n                mid_is_heavier = true;\n            } else if (res == \"<\") {\n                mid_is_heavier = false;\n            } else { // \"==\"\n                // tie\u2011break by index: smaller index is considered heavier\n                mid_is_heavier = (sorted[mid] < x);\n            }\n\n            if (mid_is_heavier) {\n                low = mid + 1;     // x belongs to the right of mid\n            } else {\n                high = mid;        // x belongs to the left of mid\n            }\n        }\n        // insert x at the determined position\n        sorted.insert(sorted.begin() + low, x);\n    }\n\n    // if we have not used all queries, perform dummy ones (compare 0 and 1)\n    while (used < Q) {\n        do_query(0, 1);\n    }\n\n    // assign items to groups using snake order on the sorted list\n    vector<int> group(N);\n    int cur_group = 0;\n    int step = 1;                 // direction of group index change\n    for (int idx : sorted) {\n        group[idx] = cur_group;\n        cur_group += step;\n        if (cur_group == D) {\n            cur_group = D - 1;\n            step = -1;\n        } else if (cur_group == -1) {\n            cur_group = 0;\n            step = 1;\n        }\n    }\n\n    // output the division\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << \" \";\n        cout << group[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        int cnt = n / m;\n        stacks[i].resize(cnt);\n        for (int j = 0; j < cnt; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    vector<pair<int, int>> ops;\n    int next_box = 1;\n\n    while (next_box <= n) {\n        // locate the current smallest box\n        int s = -1, idx = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == next_box) {\n                    s = i;\n                    idx = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (idx == (int)stacks[s].size() - 1) {\n            // already on top -> carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        } else {\n            // need to move the segment above it\n            int w = stacks[s][idx + 1]; // the box directly above\n\n            // choose destination stack\n            int d = -1;\n            // prefer an empty stack\n            for (int i = 0; i < m; ++i) {\n                if (i != s && stacks[i].empty()) {\n                    d = i;\n                    break;\n                }\n            }\n            if (d == -1) {\n                // choose the stack with the largest top\n                int max_top = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i != s && !stacks[i].empty()) {\n                        int top_val = stacks[i].back();\n                        if (top_val > max_top) {\n                            max_top = top_val;\n                            d = i;\n                        }\n                    }\n                }\n            }\n            // fallback (should never happen because m >= 2)\n            if (d == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i != s) {\n                        d = i;\n                        break;\n                    }\n                }\n            }\n\n            // operation 1: move w and everything above it to stack d\n            ops.emplace_back(w, d + 1); // output 1\u2011based index\n\n            // perform the move\n            vector<int> segment(stacks[s].begin() + idx + 1, stacks[s].end());\n            stacks[s].resize(idx + 1);          // keep only boxes up to and including next_box\n            stacks[d].insert(stacks[d].end(), segment.begin(), segment.end());\n\n            // now next_box is on top of stack s -> carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        }\n    }\n\n    // output the sequence\n    for (auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_NODES = MAX_N * MAX_N;\nconst int DIRS = 4;\nconst int di[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dj[DIRS] = {0, 0, -1, 1};\nconst char dir_char[DIRS] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<array<int, 4>> neighbors; // neighbors[node][dir] = neighbor index or -1\nvector<vector<int>> dist;         // dist[s][t]\nvector<vector<int>> next_move;    // next_move[s][t] = direction from s to t\n\n// Build graph from walls\nvoid build_graph() {\n    int total = N * N;\n    neighbors.assign(total, {-1, -1, -1, -1});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node = i * N + j;\n            // down\n            if (i < N-1 && h[i][j] == '0') {\n                int ni = i+1, nj = j;\n                int nnode = ni * N + nj;\n                neighbors[node][1] = nnode; // D\n                neighbors[nnode][0] = node; // U\n            }\n            // right\n            if (j < N-1 && v[i][j] == '0') {\n                int ni = i, nj = j+1;\n                int nnode = ni * N + nj;\n                neighbors[node][3] = nnode; // R\n                neighbors[nnode][2] = node; // L\n            }\n        }\n    }\n}\n\n// Precompute all-pairs shortest paths and next moves\nvoid precompute_paths() {\n    int total = N * N;\n    dist.assign(total, vector<int>(total, -1));\n    next_move.assign(total, vector<int>(total, -1));\n    for (int s = 0; s < total; ++s) {\n        queue<int> q;\n        q.push(s);\n        dist[s][s] = 0;\n        next_move[s][s] = -1;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int v = neighbors[u][dir];\n                if (v == -1) continue;\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    if (u == s) {\n                        next_move[s][v] = dir;\n                    } else {\n                        next_move[s][v] = next_move[s][u];\n                    }\n                    q.push(v);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(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    build_graph();\n    precompute_paths();\n\n    int total_nodes = N * N;\n    int home = 0; // (0,0)\n\n    // Phase 1: visit all squares at least once\n    string moves;\n    vector<int> m(total_nodes, 0); // visit counts\n    vector<bool> visited(total_nodes, false);\n    int visited_count = 0;\n    int current = home;\n\n    // First move: go to neighbor with highest d\n    int best_dir = -1;\n    int best_d = -1;\n    for (int dir = 0; dir < DIRS; ++dir) {\n        int nb = neighbors[current][dir];\n        if (nb == -1) continue;\n        int i = nb / N, j = nb % N;\n        if (d[i][j] > best_d) {\n            best_d = d[i][j];\n            best_dir = dir;\n        }\n    }\n    // If no neighbor (should not happen), take any\n    if (best_dir == -1) {\n        for (int dir = 0; dir < DIRS; ++dir) {\n            if (neighbors[current][dir] != -1) {\n                best_dir = dir;\n                break;\n            }\n        }\n    }\n    moves += dir_char[best_dir];\n    current = neighbors[current][best_dir];\n    m[current]++;\n    visited[current] = true;\n    visited_count++;\n\n    // Visit remaining squares using nearest unvisited heuristic\n    while (visited_count < total_nodes) {\n        int best_u = -1;\n        int best_dist = 1e9;\n        for (int u = 0; u < total_nodes; ++u) {\n            if (!visited[u]) {\n                int d = dist[current][u];\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_u = u;\n                }\n            }\n        }\n        while (current != best_u) {\n            int dir = next_move[current][best_u];\n            moves += dir_char[dir];\n            current = neighbors[current][dir];\n            m[current]++;\n            if (!visited[current]) {\n                visited[current] = true;\n                visited_count++;\n            }\n        }\n    }\n\n    // Return home\n    while (current != home) {\n        int dir = next_move[current][home];\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        if (!visited[current]) {\n            visited[current] = true;\n            visited_count++;\n        }\n    }\n\n    // Phase 2: greedy walk biased towards high d\n    const int L_max = 100000;\n    int current_length = moves.size();\n    while (current_length < L_max) {\n        int remaining = L_max - current_length;\n        int dist_home = dist[current][home];\n        if (remaining == dist_home) break;\n\n        double best_score = -1.0;\n        int best_dir = -1;\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb == -1) continue;\n            int new_dist_home = dist[nb][home];\n            if (remaining - 1 >= new_dist_home) {\n                int i = nb / N, j = nb % N;\n                double score = d[i][j] / (m[nb] + 1.0);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n        }\n        if (best_dir == -1) break; // no safe move, go home\n\n        moves += dir_char[best_dir];\n        current = neighbors[current][best_dir];\n        m[current]++;\n        current_length++;\n    }\n\n    // Final return home\n    while (current != home) {\n        int dir = next_move[current][home];\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        current_length++;\n    }\n\n    // Output\n    cout << moves << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int M_MAX = 200;\nusing Bits = bitset<M_MAX>;\n\n// rolling hash parameters\nconst uint64_t BASE = 91138233;   // any odd number works\nconst int MAX_LEN = 2000;         // more than enough\nvector<uint64_t> POW(MAX_LEN + 1);\n\nstruct MyString {\n    string s;\n    Bits cov;\n    vector<uint64_t> pref;\n    int len;\n\n    MyString(string s_, Bits cov_) : s(move(s_)), cov(cov_), len(s.size()) {\n        pref.resize(len + 1);\n        pref[0] = 0;\n        for (int i = 0; i < len; ++i) {\n            pref[i + 1] = pref[i] * BASE + (s[i] - 'A' + 1);\n        }\n    }\n\n    // hash of substring [l, r] (inclusive)\n    uint64_t get_hash(int l, int r) const {\n        return pref[r + 1] - pref[l] * POW[r - l + 1];\n    }\n};\n\n// ----------------------------------------------------------------------\n// main solving routine\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // precompute powers\n    POW[0] = 1;\n    for (int i = 1; i <= MAX_LEN; ++i) {\n        POW[i] = POW[i - 1] * BASE;\n    }\n\n    // ----- read input ---------------------------------------------------\n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<string> patterns(M);\n    unordered_map<string, int> pat_to_idx;\n    for (int k = 0; k < M; ++k) {\n        cin >> patterns[k];\n        pat_to_idx[patterns[k]] = k;\n    }\n\n    // ----- keyboard data ------------------------------------------------\n    vector<vector<int>> pos_for_char(26);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            pos_for_char[c - 'A'].push_back(i * N + j);\n        }\n    }\n\n    const int CELLS = N * N;\n    vector<vector<int>> dist(CELLS, vector<int>(CELLS));\n    for (int id1 = 0; id1 < CELLS; ++id1) {\n        int x1 = id1 / N, y1 = id1 % N;\n        for (int id2 = 0; id2 < CELLS; ++id2) {\n            int x2 = id2 / N, y2 = id2 % N;\n            dist[id1][id2] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // ----- build initial strings (each pattern) -------------------------\n    vector<MyString> cur;\n    for (int k = 0; k < M; ++k) {\n        Bits b;\n        b.set(k);\n        cur.emplace_back(patterns[k], b);\n    }\n\n    // helper: compute which patterns appear in a string\n    auto compute_cov = [&](const string& s) -> Bits {\n        Bits bs;\n        int L = s.size();\n        for (int i = 0; i <= L - 5; ++i) {\n            string sub = s.substr(i, 5);\n            auto it = pat_to_idx.find(sub);\n            if (it != pat_to_idx.end()) {\n                bs.set(it->second);\n            }\n        }\n        return bs;\n    };\n\n    // helper: maximum suffix\u2011prefix overlap\n    auto overlap = [&](const MyString& a, const MyString& b) -> int {\n        int lo = 0, hi = min(a.len, b.len);\n        while (lo < hi) {\n            int mid = (lo + hi + 1) / 2;\n            uint64_t ha = a.get_hash(a.len - mid, a.len - 1);\n            uint64_t hb = b.get_hash(0, mid - 1);\n            if (ha == hb)\n                lo = mid;\n            else\n                hi = mid - 1;\n        }\n        return lo;\n    };\n\n    // ----- greedy merging -----------------------------------------------\n    while (cur.size() > 1) {\n        // 1) discard a string whose patterns are already covered by another\n        bool removed = false;\n        for (size_t i = 0; i < cur.size() && !removed; ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                if ((cur[i].cov & cur[j].cov) == cur[j].cov) {\n                    cur.erase(cur.begin() + j);\n                    removed = true;\n                    break;\n                }\n                if ((cur[i].cov & cur[j].cov) == cur[i].cov) {\n                    cur.erase(cur.begin() + i);\n                    removed = true;\n                    break;\n                }\n            }\n        }\n        if (removed) continue;\n\n        // 2) find the pair with maximum overlap\n        int best_ov = -1;\n        size_t best_i = 0, best_j = 0;\n        bool best_rev = false;   // false: i then j, true: j then i\n        for (size_t i = 0; i < cur.size(); ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                int ov;\n\n                ov = overlap(cur[i], cur[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                    best_rev = false;\n                }\n\n                ov = overlap(cur[j], cur[i]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                    best_rev = true;\n                }\n            }\n        }\n\n        // 3) merge the chosen pair\n        string new_s;\n        if (!best_rev)\n            new_s = cur[best_i].s + cur[best_j].s.substr(best_ov);\n        else\n            new_s = cur[best_j].s + cur[best_i].s.substr(best_ov);\n\n        Bits new_cov = compute_cov(new_s);\n\n        // erase the two original strings (larger index first)\n        size_t idx1 = best_i, idx2 = best_j;\n        if (idx1 > idx2) swap(idx1, idx2);\n        cur.erase(cur.begin() + idx2);\n        cur.erase(cur.begin() + idx1);\n        cur.emplace_back(move(new_s), new_cov);\n\n        // (optional early exit: if new_cov.all() we could keep only this one)\n    }\n\n    string final_s = cur[0].s;   // the superstring containing all patterns\n\n    // ----- DP: optimal key sequence for final_s ------------------------\n    int L = final_s.size();\n\n    struct State {\n        int id;        // cell index\n        int cost;      // minimal cost to reach this state\n        int prev_idx;  // index in previous states vector\n    };\n    vector<vector<State>> states(L);\n\n    // first character\n    int start_id = si * N + sj;\n    for (int id : pos_for_char[final_s[0] - 'A']) {\n        states[0].push_back({id, dist[start_id][id] + 1, -1});\n    }\n\n    // subsequent characters\n    for (int i = 1; i < L; ++i) {\n        char c = final_s[i];\n        vector<int> cur_ids = pos_for_char[c - 'A'];\n        vector<State> cur_states;\n        for (int id : cur_ids) {\n            int best_cost = INT_MAX;\n            int best_prev = -1;\n            for (size_t idx = 0; idx < states[i - 1].size(); ++idx) {\n                const State& prev = states[i - 1][idx];\n                int cand = prev.cost + dist[prev.id][id] + 1;\n                if (cand < best_cost) {\n                    best_cost = cand;\n                    best_prev = idx;\n                }\n            }\n            cur_states.push_back({id, best_cost, best_prev});\n        }\n        states[i] = move(cur_states);\n    }\n\n    // best final state\n    int best_idx = 0;\n    int best_cost = states[L - 1][0].cost;\n    for (size_t i = 1; i < states[L - 1].size(); ++i) {\n        if (states[L - 1][i].cost < best_cost) {\n            best_cost = states[L - 1][i].cost;\n            best_idx = i;\n        }\n    }\n\n    // backtrack\n    vector<int> path_ids(L);\n    int idx = best_idx;\n    for (int i = L - 1; i >= 0; --i) {\n        path_ids[i] = states[i][idx].id;\n        idx = states[i][idx].prev_idx;\n    }\n\n    // ----- output -------------------------------------------------------\n    for (int id : path_ids) {\n        int x = id / N, y = id % N;\n        cout << x << ' ' << y << '\\n';\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cassert>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    int D = 0;\n    vector<vector<pair<int, int>>> shapes(M);\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        D += d;\n        shapes[k].resize(d);\n        for (int s = 0; s < d; ++s) {\n            int i, j;\n            cin >> i >> j;\n            shapes[k][s] = {i, j};\n        }\n    }\n\n    auto output_query = [&](const vector<pair<int, int>>& squares) {\n        cout << \"q \" << squares.size();\n        for (auto [i, j] : squares) {\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << endl;\n        cout.flush();\n    };\n\n    auto read_response = [&]() -> int {\n        int x;\n        cin >> x;\n        return x;\n    };\n\n    int total_cells = N * N;\n    vector<tuple<int, int, int>> edges; // u, v, sum\n    vector<vector<pair<int, int>>> adj(total_cells); // to (v, sum)\n\n    // Query horizontal adjacent pairs\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            int u = i * N + j;\n            int v = i * N + j + 1;\n            output_query({{i, j}, {i, j + 1}});\n            int s = read_response();\n            edges.emplace_back(u, v, s);\n            adj[u].emplace_back(v, s);\n            adj[v].emplace_back(u, s);\n        }\n    }\n\n    // Query vertical adjacent pairs for the first column\n    for (int i = 0; i < N - 1; ++i) {\n        int u = i * N + 0;\n        int v = (i + 1) * N + 0;\n        output_query({{i, 0}, {i + 1, 0}});\n        int s = read_response();\n        edges.emplace_back(u, v, s);\n        adj[u].emplace_back(v, s);\n        adj[v].emplace_back(u, s);\n    }\n\n    // BFS from (0,0) to assign a and b\n    vector<vector<int>> a(N, vector<int>(N, 0));\n    vector<vector<int>> b(N, vector<int>(N, 0));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<int> q;\n    a[0][0] = 1;\n    b[0][0] = 0;\n    visited[0][0] = true;\n    q.push(0);\n\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        int i = u / N, j = u % N;\n        for (auto [v, s] : adj[u]) {\n            int vi = v / N, vj = v % N;\n            if (!visited[vi][vj]) {\n                a[vi][vj] = -a[i][j];\n                b[vi][vj] = s - b[i][j];\n                visited[vi][vj] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    // Compute A and B\n    int A = 0, B = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A += a[i][j];\n            B += b[i][j];\n        }\n    }\n\n    // Check if (D - B) is divisible by A\n    bool error = false;\n    if ((D - B) % A != 0) {\n        error = true;\n    } else {\n        int x = (D - B) / A;\n        vector<vector<int>> v(N, vector<int>(N, 0));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                v[i][j] = a[i][j] * x + b[i][j];\n                if (v[i][j] < 0 || v[i][j] > M) {\n                    error = true;\n                }\n            }\n        }\n\n        // Verify edge sums\n        if (!error) {\n            for (auto [u, vt, s] : edges) {\n                int ui = u / N, uj = u % N;\n                int vi = vt / N, vj = vt % N;\n                if (v[ui][uj] + vi[v][vj] != s) {\n                    error = true;\n                    break;\n                }\n            }\n        }\n\n        if (!error) {\n            // Prepare guess\n            vector<pair<int, int>> positive;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (v[i][j] > 0) {\n                        positive.emplace_back(i, j);\n                    }\n                }\n            }\n            cout << \"a \" << positive.size();\n            for (auto [i, j] : positive) {\n                cout << \" \" << i << \" \" << j;\n            }\n            cout << endl;\n            cout.flush();\n            int resp = read_response();\n            if (resp == 1) {\n                return 0;\n            } else {\n                error = true;\n            }\n        }\n    }\n\n    // Fallback: drill all squares\n    if (error) {\n        vector<pair<int, int>> positive;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                output_query({{i, j}});\n                int val = read_response();\n                if (val > 0) {\n                    positive.emplace_back(i, j);\n                }\n            }\n        }\n        cout << \"a \" << positive.size();\n        for (auto [i, j] : positive) {\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << endl;\n        cout.flush();\n        int resp = read_response();\n        // Should be 1, but we don't need to do anything else\n    }\n\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int area;\n};\n\n// tries to pack rectangles with desired areas B (sorted descending) using common row height H\n// returns true and fills rects if successful\nbool pack(int W, int H, const vector<int>& B, vector<Rect>& rects) {\n    int N = B.size();\n    vector<int> w(N);\n    for (int i = 0; i < N; ++i) {\n        w[i] = (B[i] + H - 1) / H;          // width needed for area at least B[i]\n        if (w[i] > W) return false;         // too wide to fit\n    }\n    // indices sorted by width descending (first-fit decreasing)\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    vector<int> row_used;                     // used width in each row\n    vector<vector<pair<int, int>>> row_items; // each row: (rectangle index, start_x)\n\n    for (int i : idx) {\n        int placed = -1;\n        for (int r = 0; r < (int)row_used.size(); ++r) {\n            if (row_used[r] + w[i] <= W) {\n                placed = r;\n                break;\n            }\n        }\n        if (placed == -1) {                   // start new row\n            row_used.push_back(w[i]);\n            row_items.push_back({{i, 0}});\n        } else {\n            int start_x = row_used[placed];\n            row_used[placed] += w[i];\n            row_items[placed].emplace_back(i, start_x);\n        }\n    }\n\n    int rows = row_used.size();\n    if (rows * H > W) return false;           // total height exceeds W\n\n    rects.assign(N, Rect());\n    for (int r = 0; r < rows; ++r) {\n        int y0 = r * H;\n        int y1 = y0 + H;\n        for (auto& p : row_items[r]) {\n            int id = p.first;\n            int x0 = p.second;\n            rects[id].x0 = x0;\n            rects[id].x1 = x0 + w[id];\n            rects[id].y0 = y0;\n            rects[id].y1 = y1;\n            rects[id].area = w[id] * H;\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    cin >> W >> D >> N;\n\n    vector<vector<int>> a_original(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a_original[d][k];\n\n    // ----- build descending demands per day -----\n    vector<vector<int>> a_desc(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        a_desc[d] = a_original[d];\n        sort(a_desc[d].begin(), a_desc[d].end(), greater<int>());\n    }\n\n    // ----- for each position i (i-th largest) collect values over days -----\n    vector<vector<int>> slot_vals(N, vector<int>(D));\n    for (int i = 0; i < N; ++i) {\n        for (int d = 0; d < D; ++d)\n            slot_vals[i][d] = a_desc[d][i];\n        sort(slot_vals[i].begin(), slot_vals[i].end(), greater<int>());\n    }\n\n    // ----- water filling to obtain optimal target areas b[i] -----\n    vector<int> b(N, 0);\n    vector<int> ptr(N, D);                // number of values > current b[i]\n    using P = pair<int, int>;\n    priority_queue<P> pq;                 // max-heap by f = ptr\n    for (int i = 0; i < N; ++i)\n        pq.emplace(ptr[i], i);\n\n    const int S = W * W;\n    int total_used = 0;\n    while (total_used < S && !pq.empty()) {\n        auto [f, i] = pq.top();\n        pq.pop();\n        if (f != ptr[i]) continue;        // outdated entry\n        if (f == 0) break;                // no further improvement possible\n        // add one unit to rectangle i\n        b[i]++;\n        total_used++;\n        // update ptr[i]\n        while (ptr[i] > 0 && slot_vals[i][ptr[i] - 1] <= b[i])\n            ptr[i]--;\n        pq.emplace(ptr[i], i);\n    }\n\n    // b now contains the desired areas; sort them descending\n    vector<int> B = b;\n    sort(B.begin(), B.end(), greater<int>());\n\n    // ----- pack rectangles into the W x W square -----\n    vector<Rect> rects;\n    int H_min = 0;\n    for (int bi : B)\n        H_min = max(H_min, (bi + W - 1) / W);   // smallest H such that width <= W\n\n    bool packed = false;\n    auto pack_lambda = [&](int H, const vector<int>& B, vector<Rect>& rects) -> bool {\n        return pack(W, H, B, rects);\n    };\n    for (int H = H_min; H <= W; ++H) {\n        if (pack_lambda(H, B, rects)) {\n            packed = true;\n            break;\n        }\n    }\n    if (!packed) {   // fallback: vertical strips of almost equal width\n        int Nrect = B.size();\n        vector<int> widths(Nrect, W / Nrect);\n        int rem = W % Nrect;\n        for (int i = 0; i < rem; ++i) widths[i]++;\n        rects.resize(Nrect);\n        int x = 0;\n        for (int i = 0; i < Nrect; ++i) {\n            rects[i].x0 = x;\n            rects[i].x1 = x + widths[i];\n            rects[i].y0 = 0;\n            rects[i].y1 = W;\n            rects[i].area = widths[i] * W;\n            x += widths[i];\n        }\n    }\n\n    // ----- order rectangles by area (largest first) -----\n    vector<int> rect_order(N);\n    iota(rect_order.begin(), rect_order.end(), 0);\n    sort(rect_order.begin(), rect_order.end(),\n         [&](int i, int j) { return rects[i].area > rects[j].area; });\n\n    // ----- assign rectangles to reservations each day -----\n    vector<vector<int>> assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int, int>> dem;   // (demand, original index)\n        for (int k = 0; k < N; ++k)\n            dem.emplace_back(a_original[d][k], k);\n        sort(dem.begin(), dem.end(), greater<pair<int, int>>());\n        for (int t = 0; t < N; ++t) {\n            int orig_k = dem[t].second;\n            int ridx = rect_order[t];\n            assign[d][orig_k] = ridx;\n        }\n    }\n\n    // ----- output -----\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int r = assign[d][k];\n            cout << rects[r].x0 << \" \" << rects[r].y0 << \" \"\n                 << rects[r].x1 << \" \" << rects[r].y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll MOD = 998244353;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<vector<ll>> a(N, vector<ll>(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    vector<vector<vector<ll>>> s(M, vector<vector<ll>>(3, vector<ll>(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<vector<ll>> board = a;\n    vector<tuple<int, int, int>> operations;\n\n    for (int step = 0; step < K; ++step) {\n        ll best_gain = 0;\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 <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll gain = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int i = p + di, j = q + dj;\n                            ll old_val = board[i][j];\n                            ll add = s[m][di][dj];\n                            ll new_val = old_val + add;\n                            ll old_rem = old_val % MOD;\n                            ll new_rem = new_val % MOD;\n                            gain += new_rem - old_rem;\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n\n        if (best_gain <= 0) {\n            break;\n        }\n\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int i = best_p + di, j = best_q + dj;\n                board[i][j] += s[best_m][di][dj];\n            }\n        }\n        operations.emplace_back(best_m, best_p, best_q);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <algorithm>\n#include <cassert>\n\nusing namespace std;\n\nint main() {\n    const int N = 5;\n    int A[N][N];\n    int grid[N][N];\n    pair<int, int> pos_of[25];          // position of each container on the grid, (-1,-1) if not present\n    int next_idx[N] = {0};              // how many containers have been placed from each gate\n    bool dispatched[25] = {false};\n    int next_dispatch = 0;              // smallest container number not yet dispatched\n\n    // crane state\n    int crane_r = 0, crane_c = 0;\n    int crane_hold = -1;                // -1 means not holding\n\n    // read input\n    int dummy; cin >> dummy;            // N is always 5, but we read it\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // initialise grid and pos_of\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = -1;\n    for (int b = 0; b < 25; ++b)\n        pos_of[b] = {-1, -1};\n\n    vector<char> actions;               // actions of the large crane\n\n    // helper lambdas\n    auto move_towards = [&](int tr, int tc) -> char {\n        if (crane_r != tr)\n            return (tr < crane_r) ? 'U' : 'D';\n        else\n            return (tc < crane_c) ? 'L' : 'R';\n    };\n\n    auto decide = [&]() -> char {\n        if (crane_hold != -1) {\n            // holding a container\n            if (crane_hold == next_dispatch) {\n                int tr = crane_hold / N;\n                int tc = N - 1;\n                if (crane_r == tr && crane_c == tc)\n                    return 'Q';\n                return move_towards(tr, tc);\n            } else {\n                // look for an empty storage square (columns 1-3, or left column if all received)\n                int best_r = -1, best_c = -1, best_dist = 100;\n                // columns 1,2,3\n                for (int r = 0; r < N; ++r) {\n                    for (int c = 1; c <= 3; ++c) {\n                        if (grid[r][c] == -1) {\n                            int d = abs(r - crane_r) + abs(c - crane_c);\n                            if (d < best_dist) {\n                                best_dist = d;\n                                best_r = r;\n                                best_c = c;\n                            }\n                        }\n                    }\n                }\n                // left column only if all containers from that gate have been received\n                for (int i = 0; i < N; ++i) {\n                    if (next_idx[i] == N && grid[i][0] == -1) {\n                        int d = abs(i - crane_r) + abs(0 - crane_c);\n                        if (d < best_dist) {\n                            best_dist = d;\n                            best_r = i;\n                            best_c = 0;\n                        }\n                    }\n                }\n                if (best_r == -1) {\n                    // no storage -> dispatch this container immediately\n                    int tr = crane_hold / N;\n                    int tc = N - 1;\n                    if (crane_r == tr && crane_c == tc)\n                        return 'Q';\n                    return move_towards(tr, tc);\n                } else {\n                    if (crane_r == best_r && crane_c == best_c)\n                        return 'Q';\n                    return move_towards(best_r, best_c);\n                }\n            }\n        } else {\n            // not holding\n            if (pos_of[next_dispatch].first != -1) {\n                // next dispatch container is on the grid\n                int tr = pos_of[next_dispatch].first;\n                int tc = pos_of[next_dispatch].second;\n                if (crane_r == tr && crane_c == tc)\n                    return 'P';\n                return move_towards(tr, tc);\n            } else {\n                // next dispatch container not yet placed -> go to its receiving gate\n                int gate = next_dispatch / N;\n                int tr = gate, tc = 0;\n                if (crane_r == tr && crane_c == tc) {\n                    // already at the gate\n                    if (grid[tr][tc] != -1)\n                        return 'P';     // pick up whatever is there\n                    else\n                        return '.';     // wait for the container to appear\n                } else {\n                    return move_towards(tr, tc);\n                }\n            }\n        }\n    };\n\n    auto apply = [&](char act) {\n        if (act == 'P') {\n            // pick up\n            crane_hold = grid[crane_r][crane_c];\n            grid[crane_r][crane_c] = -1;\n            pos_of[crane_hold] = {-1, -1};\n        } else if (act == 'Q') {\n            // release\n            int cont = crane_hold;\n            grid[crane_r][crane_c] = cont;\n            pos_of[cont] = {crane_r, crane_c};\n            crane_hold = -1;\n        } else if (act == 'U') {\n            --crane_r;\n        } else if (act == 'D') {\n            ++crane_r;\n        } else if (act == 'L') {\n            --crane_c;\n        } else if (act == 'R') {\n            ++crane_c;\n        } // '.' does nothing\n    };\n\n    // simulation loop\n    const int MAX_TURN = 10000;\n    for (int turn = 1; turn <= MAX_TURN; ++turn) {\n        // ----- step 1 : receiving -----\n        for (int i = 0; i < N; ++i) {\n            if (next_idx[i] < N && grid[i][0] == -1) {\n                // condition: no crane holding a container at this square\n                if (crane_r == i && crane_c == 0 && crane_hold != -1)\n                    continue;   // blocked\n                int cont = A[i][next_idx[i]];\n                grid[i][0] = cont;\n                pos_of[cont] = {i, 0};\n                ++next_idx[i];\n            }\n        }\n\n        // ----- step 2 : actions -----\n        char act = decide();\n        actions.push_back(act);\n        apply(act);\n\n        // ----- step 3 : dispatch -----\n        for (int i = 0; i < N; ++i) {\n            int cont = grid[i][N-1];\n            if (cont != -1) {\n                dispatched[cont] = true;\n                grid[i][N-1] = -1;\n                pos_of[cont] = {-1, -1};\n            }\n        }\n\n        // update next_dispatch\n        while (next_dispatch < N*N && dispatched[next_dispatch])\n            ++next_dispatch;\n\n        // check completion\n        bool all_done = true;\n        for (int b = 0; b < N*N; ++b)\n            if (!dispatched[b]) { all_done = false; break; }\n        if (all_done)\n            break;\n    }\n\n    int T = actions.size();\n    // output for large crane (initially at (0,0))\n    string S0(actions.begin(), actions.end());\n    cout << S0 << endl;\n    // output for the four small cranes: bomb at first turn, then idle\n    for (int i = 1; i < N; ++i) {\n        string Si = 'B' + string(T-1, '.');\n        cout << Si << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<array<int, 3>> supplies, demands;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0)\n                supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0)\n                demands.push_back({i, j, -h[i][j]});\n        }\n    }\n\n    vector<string> ops;\n    int cur_r = 0, cur_c = 0, load = 0;\n\n    auto move_to = [&](int tr, int tc) {\n        while (cur_r > tr) {\n            ops.push_back(\"U\");\n            --cur_r;\n        }\n        while (cur_r < tr) {\n            ops.push_back(\"D\");\n            ++cur_r;\n        }\n        while (cur_c > tc) {\n            ops.push_back(\"L\");\n            --cur_c;\n        }\n        while (cur_c < tc) {\n            ops.push_back(\"R\");\n            ++cur_c;\n        }\n    };\n\n    while (!supplies.empty() || !demands.empty()) {\n        if (load == 0) {\n            // choose supply with smallest distance/amount\n            int best_idx = -1;\n            long long best_num = 0, best_den = 1;\n            for (int i = 0; i < (int)supplies.size(); ++i) {\n                auto& s = supplies[i];\n                int dist = abs(cur_r - s[0]) + abs(cur_c - s[1]);\n                int amt = s[2];\n                if (best_idx == -1 || dist * best_den < best_num * amt) {\n                    best_idx = i;\n                    best_num = dist;\n                    best_den = amt;\n                }\n            }\n            auto& s = supplies[best_idx];\n            move_to(s[0], s[1]);\n            ops.push_back(\"+\" + to_string(s[2]));\n            load += s[2];\n            supplies.erase(supplies.begin() + best_idx);\n        } else {\n            // find demands that can be fully satisfied\n            vector<int> feasible;\n            for (int i = 0; i < (int)demands.size(); ++i) {\n                if (demands[i][2] <= load)\n                    feasible.push_back(i);\n            }\n            if (!feasible.empty()) {\n                // choose feasible demand with smallest distance/amount\n                int best_idx = -1;\n                long long best_num = 0, best_den = 1;\n                for (int idx : feasible) {\n                    auto& d = demands[idx];\n                    int dist = abs(cur_r - d[0]) + abs(cur_c - d[1]);\n                    int amt = d[2];\n                    if (best_idx == -1 || dist * best_den < best_num * amt) {\n                        best_idx = idx;\n                        best_num = dist;\n                        best_den = amt;\n                    }\n                }\n                auto& d = demands[best_idx];\n                move_to(d[0], d[1]);\n                ops.push_back(\"-\" + to_string(d[2]));\n                load -= d[2];\n                demands.erase(demands.begin() + best_idx);\n            } else {\n                // no feasible demand, go to nearest supply (by distance/amount)\n                int best_idx = -1;\n                long long best_num = 0, best_den = 1;\n                for (int i = 0; i < (int)supplies.size(); ++i) {\n                    auto& s = supplies[i];\n                    int dist = abs(cur_r - s[0]) + abs(cur_c - s[1]);\n                    int amt = s[2];\n                    if (best_idx == -1 || dist * best_den < best_num * amt) {\n                        best_idx = i;\n                        best_num = dist;\n                        best_den = amt;\n                    }\n                }\n                auto& s = supplies[best_idx];\n                move_to(s[0], s[1]);\n                ops.push_back(\"+\" + to_string(s[2]));\n                load += s[2];\n                supplies.erase(supplies.begin() + best_idx);\n            }\n        }\n    }\n\n    for (string& op : ops)\n        cout << op << endl;\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\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);  // 60\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    for (int t = 0; t < T; t++) {\n        // Compute sum for each seed\n        vector<int> sum(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            int s = 0;\n            for (int j = 0; j < M; j++) {\n                s += seeds[i][j];\n            }\n            sum[i] = s;\n        }\n\n        // Find seed with max value for each criterion\n        vector<int> max_val(M, -1);\n        vector<int> max_idx(M, -1);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                if (seeds[i][l] > max_val[l]) {\n                    max_val[l] = seeds[i][l];\n                    max_idx[l] = i;\n                }\n            }\n        }\n\n        // Set of important seeds (max per criterion)\n        set<int> important;\n        for (int l = 0; l < M; l++) {\n            important.insert(max_idx[l]);\n        }\n\n        // Sort all seeds by sum descending\n        vector<pair<int, int>> sum_idx;\n        for (int i = 0; i < seed_count; i++) {\n            sum_idx.emplace_back(sum[i], i);\n        }\n        sort(sum_idx.begin(), sum_idx.end(), greater<pair<int, int>>());\n\n        // Select seeds to plant\n        vector<int> to_plant;\n        for (int idx : important) {\n            to_plant.push_back(idx);\n        }\n        for (auto& p : sum_idx) {\n            if (to_plant.size() >= 36) break;\n            int idx = p.second;\n            if (important.find(idx) == important.end()) {\n                to_plant.push_back(idx);\n            }\n        }\n\n        // Sort to_plant by sum descending for grid assignment\n        sort(to_plant.begin(), to_plant.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        // Output grid (6x6)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << to_plant[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read next generation if not last turn\n        if (t < T - 1) {\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\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n#include <cstdlib>\n#include <cassert>\n\nusing namespace std;\n\n// Directions: 0:right, 1:down, 2:left, 3:up\nconst int dr[4] = {0, 1, 0, -1};\nconst int dc[4] = {1, 0, -1, 0};\n\nint N, M, V;\nint V_prime;          // number of vertices used\nint K;                // number of leaves = V_prime-1\nvector<int> len;      // length of each leaf (1-indexed, len[i] for leaf i)\nint root_r, root_c;   // current root position\nvector<int> dir;      // direction of each leaf (1-indexed)\nvector<bool> holding; // whether leaf i holds a takoyaki\nbool src_rem[30][30]; // remaining source squares\nbool tgt_rem[30][30]; // remaining target squares\nint src_cnt, tgt_cnt; // counts\n\n// Helper functions\ninline bool in_grid(int r, int c) {\n    return 0 <= r && r < N && 0 <= c && c < N;\n}\n\n// Output one turn\nvoid output_turn(char move, const vector<char>& rot, const vector<char>& act) {\n    string S(2 * V_prime, '.');\n    S[0] = move;\n    for (int i = 1; i <= K; ++i) {\n        S[i] = rot[i];\n    }\n    for (int i = 0; i <= K; ++i) {\n        if (act[i] == 'P') {\n            S[V_prime + i] = 'P';\n        }\n    }\n    cout << S << '\\n';\n}\n\n// Move root to (tr,tc) while rotating leaf `leaf` to direction `des_dir`.\n// Performs one step per turn, rotating the leaf as much as possible.\nvoid move_root_to(int tr, int tc, int leaf, int des_dir) {\n    while (root_r != tr || root_c != tc) {\n        // Determine movement direction\n        char move_char;\n        if (tr > root_r) move_char = 'D';\n        else if (tr < root_r) move_char = 'U';\n        else if (tc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Rotation for the leaf we are controlling\n        char rot_leaf = '.';\n        if (leaf != -1 && dir[leaf] != des_dir) {\n            int diff = (des_dir - dir[leaf] + 4) % 4;\n            if (diff == 1) {\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            } else if (diff == 3) {\n                rot_leaf = 'L';\n                dir[leaf] = (dir[leaf] + 3) % 4;\n            } else { // diff == 2, rotate arbitrarily (choose R)\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            }\n        }\n\n        vector<char> rot(K+1, '.');\n        if (leaf != -1) rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.'); // no pick/drop during movement\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        if (move_char == 'U') root_r--;\n        else if (move_char == 'D') root_r++;\n        else if (move_char == 'L') root_c--;\n        else if (move_char == 'R') root_c++;\n    }\n\n    // After reaching the target, finish rotation if needed\n    while (leaf != -1 && dir[leaf] != des_dir) {\n        char rot_leaf = '.';\n        int diff = (des_dir - dir[leaf] + 4) % 4;\n        if (diff == 1) {\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        } else if (diff == 3) {\n            rot_leaf = 'L';\n            dir[leaf] = (dir[leaf] + 3) % 4;\n        } else { // diff == 2\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        }\n        vector<char> rot(K+1, '.');\n        rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.');\n        output_turn('.', rot, act);\n    }\n}\n\n// Output a turn with only a pick/drop for a given leaf (no movement, no other rotations)\nvoid output_action(int leaf, char action) {\n    vector<char> rot(K+1, '.');\n    vector<char> act(K+1, '.');\n    act[leaf] = action;\n    output_turn('.', rot, act);\n}\n\n// Find any remaining target square that leaf i can reach, together with a suitable direction.\ntuple<int,int,int> find_target_for_leaf(int i) {\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (tgt_rem[r][c]) {\n                for (int d = 0; d < 4; ++d) {\n                    int nr = r - dr[d] * len[i];\n                    int nc = c - dc[d] * len[i];\n                    if (in_grid(nr, nc)) {\n                        return {r, c, d};\n                    }\n                }\n            }\n        }\n    }\n    // should never happen\n    return {-1, -1, -1};\n}\n\n// Find any remaining source square\npair<int,int> find_source() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (src_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Find any remaining target square\npair<int,int> find_target() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (tgt_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N >> M >> V;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Determine sources and targets (remove overlaps)\n    src_cnt = tgt_cnt = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool s = (s_grid[i][j] == '1');\n            bool t = (t_grid[i][j] == '1');\n            if (s && t) {\n                // already in place, ignore\n                src_rem[i][j] = false;\n                tgt_rem[i][j] = false;\n            } else if (s) {\n                src_rem[i][j] = true;\n                ++src_cnt;\n                tgt_rem[i][j] = false;\n            } else if (t) {\n                tgt_rem[i][j] = true;\n                ++tgt_cnt;\n                src_rem[i][j] = false;\n            } else {\n                src_rem[i][j] = tgt_rem[i][j] = false;\n            }\n        }\n    }\n\n    // Design the arm: star with root 0 and leaves 1..K, lengths = 1,2,...,K\n    V_prime = V;                // use all vertices\n    K = V_prime - 1;\n    len.resize(K+1);\n    for (int i = 1; i <= K; ++i) len[i] = i;   // guaranteed i <= N-1 because N>=15, K<=14\n\n    // Initial root position (choose (0,0))\n    root_r = 0; root_c = 0;\n\n    // Output arm design\n    cout << V_prime << '\\n';\n    for (int i = 1; i <= K; ++i) {\n        cout << \"0 \" << len[i] << '\\n';\n    }\n    cout << root_r << ' ' << root_c << '\\n';\n\n    // Initialize state\n    dir.assign(K+1, 0);          // all initially point right\n    holding.assign(K+1, false);\n\n    // Snake traversal: generate order of cells\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        } else {\n            for (int j = N-1; j >= 0; --j) cells.emplace_back(i, j);\n        }\n    }\n\n    // Perform moves along the snake\n    for (size_t idx = 0; idx+1 < cells.size(); ++idx) {\n        int nr = cells[idx+1].first;\n        int nc = cells[idx+1].second;\n\n        // Determine movement character\n        char move_char;\n        if (nr > root_r) move_char = 'D';\n        else if (nr < root_r) move_char = 'U';\n        else if (nc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Greedy assignment of picks/drops at the new position\n        vector<bool> used(K+1, false);\n        vector<int> desired_dir(K+1, -1);\n        vector<char> action(K+1, '.');\n\n        // Drops first\n        for (int i = 1; i <= K; ++i) {\n            if (holding[i] && !used[i]) {\n                // Try the three reachable directions\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && tgt_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = false;\n                        tgt_rem[pr][pc] = false;\n                        --tgt_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Picks\n        for (int i = 1; i <= K; ++i) {\n            if (!holding[i] && !used[i]) {\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && src_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = true;\n                        src_rem[pr][pc] = false;\n                        --src_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Build rotation commands\n        vector<char> rot(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (desired_dir[i] != -1) {\n                int delta = (desired_dir[i] - dir[i] + 4) % 4;\n                if (delta == 0) rot[i] = '.';\n                else if (delta == 1) rot[i] = 'R';\n                else if (delta == 3) rot[i] = 'L';\n                // delta == 2 cannot happen because we only used reachable directions\n                dir[i] = desired_dir[i];\n            }\n        }\n\n        // Build action vector (root action always '.')\n        vector<char> act(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (action[i] == 'P') act[i] = 'P';\n        }\n\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        root_r = nr;\n        root_c = nc;\n    }\n\n    // If all takoyaki are already at targets, we are done\n    if (src_cnt == 0 && tgt_cnt == 0) {\n        return 0;\n    }\n\n    // ----- Cleanup phase -----\n    // Step 1: Drop any takoyaki still held by leaves\n    for (int i = 1; i <= K; ++i) {\n        while (holding[i]) {\n            auto [tr, tc, d] = find_target_for_leaf(i);\n            int nr = tr - dr[d] * len[i];\n            int nc = tc - dc[d] * len[i];\n            move_root_to(nr, nc, i, d);\n            output_action(i, 'P');\n            holding[i] = false;\n            tgt_rem[tr][tc] = false;\n            --tgt_cnt;\n        }\n    }\n\n    // Step 2: Move remaining sources to targets using leaf 1 (length = 1)\n    while (src_cnt > 0) {\n        auto [sr, sc] = find_source();\n        auto [tr, tc] = find_target();\n\n        // Pick with leaf 1\n        int d_pick = -1, nr_pick, nc_pick;\n        for (int d = 0; d < 4; ++d) {\n            nr_pick = sr - dr[d] * len[1];\n            nc_pick = sc - dc[d] * len[1];\n            if (in_grid(nr_pick, nc_pick)) {\n                d_pick = d;\n                break;\n            }\n        }\n        move_root_to(nr_pick, nc_pick, 1, d_pick);\n        output_action(1, 'P');\n        holding[1] = true;\n        src_rem[sr][sc] = false;\n        --src_cnt;\n\n        // Drop with leaf 1\n        int d_drop = -1, nr_drop, nc_drop;\n        for (int d = 0; d < 4; ++d) {\n            nr_drop = tr - dr[d] * len[1];\n            nc_drop = tc - dc[d] * len[1];\n            if (in_grid(nr_drop, nc_drop)) {\n                d_drop = d;\n                break;\n            }\n        }\n        move_root_to(nr_drop, nc_drop, 1, d_drop);\n        output_action(1, 'P');\n        holding[1] = false;\n        tgt_rem[tr][tc] = false;\n        --tgt_cnt;\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int CELL_SIZE = 5000;\nconst int MAX_COORD = 100000;\nconst int NUM_CELLS = 21; // 0 to 20 inclusive\n\nstruct Point {\n    int x, y;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mack(N), sard(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> mack[i].x >> mack[i].y;\n    }\n    for (int i = 0; i < N; ++i) {\n        cin >> sard[i].x >> sard[i].y;\n    }\n\n    // Grid counts\n    vector<vector<int>> mack_count(NUM_CELLS, vector<int>(NUM_CELLS, 0));\n    vector<vector<int>> sard_count(NUM_CELLS, vector<int>(NUM_CELLS, 0));\n    vector<pair<int, int>> mack_cells(N); // cell indices for each mackerel\n\n    for (int i = 0; i < N; ++i) {\n        int cx = mack[i].x / CELL_SIZE;\n        int cy = mack[i].y / CELL_SIZE;\n        mack_count[cx][cy]++;\n        mack_cells[i] = {cx, cy};\n    }\n    for (int i = 0; i < N; ++i) {\n        int cx = sard[i].x / CELL_SIZE;\n        int cy = sard[i].y / CELL_SIZE;\n        sard_count[cx][cy]++;\n    }\n\n    // Weight grid\n    vector<vector<int>> weight(NUM_CELLS, vector<int>(NUM_CELLS, 0));\n    for (int i = 0; i < NUM_CELLS; ++i) {\n        for (int j = 0; j < NUM_CELLS; ++j) {\n            weight[i][j] = mack_count[i][j] - sard_count[i][j];\n        }\n    }\n\n    // BFS for connected components of cells with weight > 0\n    vector<vector<bool>> visited(NUM_CELLS, vector<bool>(NUM_CELLS, false));\n    vector<vector<pair<int, int>>> components;\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < NUM_CELLS; ++i) {\n        for (int j = 0; j < NUM_CELLS; ++j) {\n            if (weight[i][j] > 0 && !visited[i][j]) {\n                vector<pair<int, int>> comp;\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();\n                    q.pop();\n                    comp.push_back({x, y});\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 < NUM_CELLS && ny >= 0 && ny < NUM_CELLS &&\n                            weight[nx][ny] > 0 && !visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n        }\n    }\n\n    // Helper functions to count points inside a rectangle\n    auto count_mack = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : mack) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) {\n                cnt++;\n            }\n        }\n        return cnt;\n    };\n\n    auto count_sard = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : sard) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) {\n                cnt++;\n            }\n        }\n        return cnt;\n    };\n\n    // Candidate list: each candidate is (x1, x2, y1, y2, score)\n    vector<tuple<int, int, int, int, int>> candidates;\n\n    // 1. Cell rectangles\n    for (int i = 0; i < NUM_CELLS; ++i) {\n        for (int j = 0; j < NUM_CELLS; ++j) {\n            if (weight[i][j] > 0) {\n                int x1 = i * CELL_SIZE;\n                int x2 = min(MAX_COORD, (i + 1) * CELL_SIZE);\n                int y1 = j * CELL_SIZE;\n                int y2 = min(MAX_COORD, (j + 1) * CELL_SIZE);\n                if (x1 < x2 && y1 < y2) {\n                    int a = count_mack(x1, x2, y1, y2);\n                    int b = count_sard(x1, x2, y1, y2);\n                    int score = max(0, a - b + 1);\n                    candidates.push_back({x1, x2, y1, y2, score});\n                }\n            }\n        }\n    }\n\n    // 2. Component bounding boxes\n    for (const auto& comp : components) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (int i = 0; i < N; ++i) {\n            int cx = mack_cells[i].first, cy = mack_cells[i].second;\n            bool found = false;\n            for (const auto& cell : comp) {\n                if (cell.first == cx && cell.second == cy) {\n                    found = true;\n                    break;\n                }\n            }\n            if (found) {\n                min_x = min(min_x, mack[i].x);\n                max_x = max(max_x, mack[i].x);\n                min_y = min(min_y, mack[i].y);\n                max_y = max(max_y, mack[i].y);\n            }\n        }\n        // Expand if degenerate\n        if (min_x == max_x) {\n            min_x = max(0, min_x - 1);\n            max_x = min(MAX_COORD, max_x + 1);\n        }\n        if (min_y == max_y) {\n            min_y = max(0, min_y - 1);\n            max_y = min(MAX_COORD, max_y + 1);\n        }\n        if (min_x < max_x && min_y < max_y) {\n            int a = count_mack(min_x, max_x, min_y, max_y);\n            int b = count_sard(min_x, max_x, min_y, max_y);\n            int score = max(0, a - b + 1);\n            candidates.push_back({min_x, max_x, min_y, max_y, score});\n        }\n    }\n\n    // 3. Union of all positive cells: bounding box of all mackerels in positive cells\n    {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (int i = 0; i < N; ++i) {\n            int cx = mack_cells[i].first, cy = mack_cells[i].second;\n            if (weight[cx][cy] > 0) {\n                min_x = min(min_x, mack[i].x);\n                max_x = max(max_x, mack[i].x);\n                min_y = min(min_y, mack[i].y);\n                max_y = max(max_y, mack[i].y);\n            }\n        }\n        if (min_x <= max_x && min_y <= max_y) {\n            if (min_x == max_x) {\n                min_x = max(0, min_x - 1);\n                max_x = min(MAX_COORD, max_x + 1);\n            }\n            if (min_y == max_y) {\n                min_y = max(0, min_y - 1);\n                max_y = min(MAX_COORD, max_y + 1);\n            }\n            if (min_x < max_x && min_y < max_y) {\n                int a = count_mack(min_x, max_x, min_y, max_y);\n                int b = count_sard(min_x, max_x, min_y, max_y);\n                int score = max(0, a - b + 1);\n                candidates.push_back({min_x, max_x, min_y, max_y, score});\n            }\n        }\n    }\n\n    // Find best candidate\n    int best_score = -1;\n    int best_x1, best_x2, best_y1, best_y2;\n    for (const auto& cand : candidates) {\n        auto [x1, x2, y1, y2, score] = cand;\n        if (score > best_score) {\n            best_score = score;\n            best_x1 = x1;\n            best_x2 = x2;\n            best_y1 = y1;\n            best_y2 = y2;\n        }\n    }\n\n    // Fallback if no candidate found\n    if (best_score == -1) {\n        // Try to find an empty cell\n        for (int i = 0; i < NUM_CELLS; ++i) {\n            for (int j = 0; j < NUM_CELLS; ++j) {\n                if (mack_count[i][j] == 0 && sard_count[i][j] == 0) {\n                    best_x1 = i * CELL_SIZE;\n                    best_x2 = min(MAX_COORD, (i + 1) * CELL_SIZE);\n                    best_y1 = j * CELL_SIZE;\n                    best_y2 = min(MAX_COORD, (j + 1) * CELL_SIZE);\n                    if (best_x1 < best_x2 && best_y1 < best_y2) {\n                        best_score = 1;\n                        break;\n                    }\n                }\n            }\n            if (best_score != -1) break;\n        }\n    }\n    if (best_score == -1) {\n        // Use a cell with at least one mackerel\n        for (int i = 0; i < NUM_CELLS; ++i) {\n            for (int j = 0; j < NUM_CELLS; ++j) {\n                if (mack_count[i][j] > 0) {\n                    best_x1 = i * CELL_SIZE;\n                    best_x2 = min(MAX_COORD, (i + 1) * CELL_SIZE);\n                    best_y1 = j * CELL_SIZE;\n                    best_y2 = min(MAX_COORD, (j + 1) * CELL_SIZE);\n                    if (best_x1 < best_x2 && best_y1 < best_y2) {\n                        best_score = 1;\n                        break;\n                    }\n                }\n            }\n            if (best_score != -1) break;\n        }\n    }\n    if (best_score == -1) {\n        // Absolute fallback\n        best_x1 = 0;\n        best_x2 = 1;\n        best_y1 = 0;\n        best_y2 = 1;\n        best_score = 1;\n    }\n\n    // Output polygon as a rectangle (4 vertices)\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference rectangle, -1 for boundary\n};\n\n// Row-based packing (uses L direction)\nvector<Placement> generate_row_packing(const vector<int>& w, const vector<int>& h,\n                                       mt19937& rng, double alpha, double noise) {\n    int n = w.size();\n    vector<Placement> res;\n    bool shelf_exists = false;\n    int shelf_ref = -1;          // b for the current shelf\n    long long shelf_top = 0;     // y coordinate of the shelf\n    long long shelf_x = 0;       // next x in this shelf\n    long long shelf_max_h = 0;   // max height in this shelf\n    long long overall_width = 0;\n    long long overall_height = 0;\n    int max_bottom_rect = -1;    // rectangle with maximum bottom (y+h)\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        double best_cost = 1e100;\n        int best_r = 0, best_option = 0; // option 0: current shelf, 1: new shelf\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            // Option: place in current shelf\n            if (shelf_exists) {\n                long long new_width = max(overall_width, shelf_x + wc);\n                long long new_shelf_max_h = max(shelf_max_h, (long long)hc);\n                long long new_height = max(overall_height, shelf_top + new_shelf_max_h);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = delta_w + alpha * delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 0;\n                }\n            }\n\n            // Option: start a new shelf\n            {\n                long long new_width = max(overall_width, (long long)wc);\n                long long new_height = overall_height + hc;\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = delta_w + alpha * delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 1;\n                }\n            }\n        }\n\n        int r = best_r;\n        int wc = (r == 0 ? w[i] : h[i]);\n        int hc = (r == 0 ? h[i] : w[i]);\n\n        if (best_option == 0) { // current shelf\n            int b = shelf_ref;\n            res.push_back({i, r, 'L', b});\n\n            long long x = shelf_x;\n            long long y = shelf_top;\n            shelf_x += wc;\n            shelf_max_h = max(shelf_max_h, (long long)hc);\n            overall_width = max(overall_width, shelf_x);\n            long long new_bottom = y + hc;\n            if (new_bottom > overall_height) {\n                overall_height = new_bottom;\n                max_bottom_rect = i;\n            }\n        } else { // new shelf\n            int b = (max_bottom_rect == -1) ? -1 : max_bottom_rect;\n            res.push_back({i, r, 'L', b});\n\n            long long x = 0;\n            long long y = overall_height;\n            shelf_ref = b;\n            shelf_top = y;\n            shelf_x = wc;\n            shelf_max_h = hc;\n            overall_width = max(overall_width, (long long)wc);\n            long long new_bottom = y + hc;\n            overall_height = new_bottom;\n            max_bottom_rect = i;\n            shelf_exists = true;\n        }\n    }\n    return res;\n}\n\n// Column-based packing (uses U direction)\nvector<Placement> generate_column_packing(const vector<int>& w, const vector<int>& h,\n                                          mt19937& rng, double alpha, double noise) {\n    int n = w.size();\n    vector<Placement> res;\n    bool col_exists = false;\n    int col_ref = -1;            // b for the current column\n    long long col_left = 0;      // x coordinate of the column\n    long long col_y = 0;         // next y in this column\n    long long col_max_w = 0;     // max width in this column\n    long long overall_width = 0;\n    long long overall_height = 0;\n    int max_right_rect = -1;     // rectangle with maximum right edge (x+w)\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        double best_cost = 1e100;\n        int best_r = 0, best_option = 0; // option 0: current column, 1: new column\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            // Option: place in current column\n            if (col_exists) {\n                long long new_col_y = col_y + hc;\n                long long new_col_max_w = max(col_max_w, (long long)wc);\n                long long new_width = max(overall_width, col_left + new_col_max_w);\n                long long new_height = max(overall_height, new_col_y);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = alpha * delta_w + delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 0;\n                }\n            }\n\n            // Option: start a new column\n            {\n                long long new_width = overall_width + wc;\n                long long new_height = max(overall_height, (long long)hc);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = alpha * delta_w + delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 1;\n                }\n            }\n        }\n\n        int r = best_r;\n        int wc = (r == 0 ? w[i] : h[i]);\n        int hc = (r == 0 ? h[i] : w[i]);\n\n        if (best_option == 0) { // current column\n            int b = col_ref;\n            res.push_back({i, r, 'U', b});\n\n            long long x = col_left;\n            long long y = col_y;\n            col_y += hc;\n            col_max_w = max(col_max_w, (long long)wc);\n            long long old_overall_width = overall_width;\n            overall_width = max(overall_width, col_left + col_max_w);\n            overall_height = max(overall_height, col_y);\n            if (overall_width > old_overall_width) {\n                max_right_rect = i;\n            }\n        } else { // new column\n            int b = (max_right_rect == -1) ? -1 : max_right_rect;\n            res.push_back({i, r, 'U', b});\n\n            long long x = overall_width;\n            long long y = 0;\n            col_ref = b;\n            col_left = x;\n            col_y = hc;\n            col_max_w = wc;\n            overall_width = x + wc;\n            overall_height = max(overall_height, (long long)hc);\n            max_right_rect = i;\n            col_exists = true;\n        }\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<long long> sum_w(N), sum_h(N);\n    vector<int> cnt(N, 1); // start with the given noisy measurements\n    for (int i = 0; i < N; ++i) {\n        int wp, hp;\n        cin >> wp >> hp;\n        sum_w[i] = wp;\n        sum_h[i] = hp;\n    }\n\n    // Estimate true sizes from the given data (already one sample)\n    vector<int> est_w(N), est_h(N);\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n    }\n\n    // Order rectangles by estimated area to prioritize measurement\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return (long long)est_w[a] * est_h[a] > (long long)est_w[b] * est_h[b];\n    });\n\n    const int PACK_TURNS = 20; // desired number of packing attempts\n    int M = max(0, T - PACK_TURNS); // number of measurement turns\n\n    // ---------- Measurement phase ----------\n    for (int t = 0; t < M; ++t) {\n        int idx = order[t % N]; // cycle through rectangles, most important first\n        cout << \"1\\n\";\n        cout << idx << \" 0 U -1\\n\";\n        cout << flush;\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Update measurements\n        sum_w[idx] += Wp;\n        sum_h[idx] += Hp;\n        cnt[idx]++;\n        // Update estimates on the fly (optional, but we will recompute later)\n        est_w[idx] = (sum_w[idx] + cnt[idx]/2) / cnt[idx];\n        est_h[idx] = (sum_h[idx] + cnt[idx]/2) / cnt[idx];\n    }\n\n    // Recompute all estimates after measurement phase\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n        if (est_w[i] < 1) est_w[i] = 1;\n        if (est_h[i] < 1) est_h[i] = 1;\n    }\n\n    // ---------- Packing phase ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<double> alphas = {0.5, 0.8, 1.0, 1.2, 1.5, 2.0};\n    uniform_int_distribution<int> alpha_dist(0, alphas.size()-1);\n    uniform_int_distribution<int> type_dist(0, 1); // 0: row, 1: column\n    const double noise = 0.1;\n\n    for (int t = M; t < T; ++t) {\n        int type = type_dist(rng);\n        double alpha = alphas[alpha_dist(rng)];\n\n        vector<Placement> placements;\n        if (type == 0) {\n            placements = generate_row_packing(est_w, est_h, rng, alpha, noise);\n        } else {\n            placements = generate_column_packing(est_w, est_h, rng, alpha, noise);\n        }\n\n        // Output the placement\n        cout << N << \"\\n\";\n        for (const auto& pl : placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << \"\\n\";\n        }\n        cout << flush;\n\n        // Read the measurement (ignored for further decisions)\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <tuple>\nusing namespace std;\n\n// Parameters for simulated annealing\nconst int MAX_ITER = 300000;\nconst double START_TEMP = 50.0;\nconst double COOLING = 0.99998;\nconst double START_PENALTY = 1.0;\nconst double END_PENALTY = 10000.0;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\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    // ---------- Greedy initial solution ----------\n    vector<int> depth(N, -1);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });\n\n    for (int v : order) {\n        if (depth[v] != -1) continue;\n        depth[v] = 0;\n        queue<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [u, d] = q.front(); q.pop();\n            if (d == H) continue;\n            for (int w : adj[u]) {\n                if (depth[w] == -1) {\n                    depth[w] = d + 1;\n                    q.emplace(w, d + 1);\n                }\n            }\n        }\n    }\n\n    // Compute initial support and unsatisfied count\n    vector<int> support(N, 0);\n    int unsatisfied_cnt = 0;\n    long long current_score = 0;\n    for (int v = 0; v < N; ++v) {\n        current_score += (long long)depth[v] * A[v];\n        if (depth[v] > 0) {\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v] - 1) {\n                    support[v]++;\n                }\n            }\n            if (support[v] == 0) unsatisfied_cnt++;\n        }\n    }\n\n    // Best feasible solution\n    long long best_score = current_score;\n    vector<int> best_depths = depth;\n\n    // ---------- Simulated Annealing ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_vertex(0, N - 1);\n    uniform_int_distribution<int> rand_depth(0, H);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    double temp = START_TEMP;\n    double penalty_weight = START_PENALTY;\n    const double penalty_inc = (END_PENALTY - START_PENALTY) / MAX_ITER;\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        int v = rand_vertex(rng);\n        int old_d = depth[v];\n        int new_d;\n\n        // Choose move type\n        double r = rand_real(rng);\n        if (r < 0.5) {\n            new_d = rand_depth(rng);\n        } else if (r < 0.8) { // try to increase\n            if (old_d < H) new_d = old_d + 1;\n            else new_d = rand_depth(rng);\n        } else { // try to decrease\n            if (old_d > 0) new_d = old_d - 1;\n            else new_d = rand_depth(rng);\n        }\n\n        if (old_d == new_d) {\n            temp *= COOLING;\n            penalty_weight += penalty_inc;\n            continue;\n        }\n\n        // Evaluate move\n        long long delta_score = (long long)(new_d - old_d) * A[v];\n        double delta_penalty = 0.0;\n        int delta_unsatisfied = 0;\n        vector<pair<int, int>> updates; // (vertex, new_support)\n\n        // Affected vertices: v and its neighbours\n        vector<int> affected = {v};\n        for (int u : adj[v]) affected.push_back(u);\n\n        for (int w : affected) {\n            int depth_w_old = depth[w];\n            int depth_w_new = (w == v) ? new_d : depth[w];\n            bool old_sat = (depth_w_old == 0) || (support[w] > 0);\n\n            // Compute new support for w\n            int new_support_w = 0;\n            for (int x : adj[w]) {\n                int depth_x = (x == v) ? new_d : depth[x];\n                if (depth_x == depth_w_new - 1) {\n                    new_support_w++;\n                }\n            }\n            bool new_sat = (depth_w_new == 0) || (new_support_w > 0);\n\n            delta_penalty += penalty_weight * ((new_sat ? 0 : A[w]) - (old_sat ? 0 : A[w]));\n            delta_unsatisfied += (new_sat ? 0 : 1) - (old_sat ? 0 : 1);\n            updates.emplace_back(w, new_support_w);\n        }\n\n        double delta_total = delta_score - delta_penalty;\n\n        if (delta_total > 0.0 || rand_real(rng) < exp(delta_total / temp)) {\n            // Accept move\n            depth[v] = new_d;\n            for (auto& [w, ns] : updates) {\n                support[w] = ns;\n            }\n            current_score += delta_score;\n            unsatisfied_cnt += delta_unsatisfied;\n\n            if (unsatisfied_cnt == 0 && current_score > best_score) {\n                best_score = current_score;\n                best_depths = depth;\n            }\n        }\n\n        temp *= COOLING;\n        penalty_weight += penalty_inc;\n    }\n\n    // ---------- Output ----------\n    // Use the best feasible solution found\n    depth = best_depths;\n\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (depth[v] == 0) continue;\n        for (int u : adj[v]) {\n            if (depth[u] == depth[v] - 1) {\n                parent[v] = u;\n                break;\n            }\n        }\n        // In a feasible solution such a neighbour must exist\n    }\n\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    bool fuku[20][20] = {};\n    bool oni[20][20] = {};\n    bool oni_rem[20][20] = {};\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] == 'o') fuku[i][j] = true;\n            else if (grid[i][j] == 'x') {\n                oni[i][j] = true;\n                oni_rem[i][j] = true;\n            }\n        }\n    }\n\n    // column data\n    int col_top[20], col_bottom[20];\n    for (int j = 0; j < N; ++j) {\n        col_top[j] = N;\n        col_bottom[j] = -1;\n        for (int i = 0; i < N; ++i) {\n            if (fuku[i][j]) {\n                col_top[j] = min(col_top[j], i);\n                col_bottom[j] = max(col_bottom[j], i);\n            }\n        }\n    }\n\n    vector<string> ops;\n\n    // Phase 1: clear columns\n    for (int j = 0; j < N; ++j) {\n        // top zone (no fuku above)\n        if (col_top[j] > 0) {\n            bool has = false;\n            for (int i = 0; i < col_top[j]; ++i)\n                if (oni_rem[i][j]) { has = true; break; }\n            if (has) {\n                int t = col_top[j];\n                for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int i = 0; i < t; ++i)\n                    if (oni[i][j]) oni_rem[i][j] = false;\n            }\n        }\n        // bottom zone (no fuku below)\n        if (col_bottom[j] < N - 1) {\n            bool has = false;\n            for (int i = col_bottom[j] + 1; i < N; ++i)\n                if (oni_rem[i][j]) { has = true; break; }\n            if (has) {\n                int b = N - 1 - col_bottom[j];\n                for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int i = col_bottom[j] + 1; i < N; ++i)\n                    if (oni[i][j]) oni_rem[i][j] = false;\n            }\n        }\n    }\n\n    // row data\n    int row_left[20], row_right[20];\n    for (int i = 0; i < N; ++i) {\n        row_left[i] = N;\n        row_right[i] = -1;\n        for (int j = 0; j < N; ++j) {\n            if (fuku[i][j]) {\n                row_left[i] = min(row_left[i], j);\n                row_right[i] = max(row_right[i], j);\n            }\n        }\n    }\n\n    // Phase 2: clear rows\n    for (int i = 0; i < N; ++i) {\n        // left zone (no fuku left)\n        if (row_left[i] > 0) {\n            bool has = false;\n            for (int j = 0; j < row_left[i]; ++j)\n                if (oni_rem[i][j]) { has = true; break; }\n            if (has) {\n                int l = row_left[i];\n                for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int j = 0; j < l; ++j)\n                    if (oni[i][j]) oni_rem[i][j] = false;\n            }\n        }\n        // right zone (no fuku right)\n        if (row_right[i] < N - 1) {\n            bool has = false;\n            for (int j = row_right[i] + 1; j < N; ++j)\n                if (oni_rem[i][j]) { has = true; break; }\n            if (has) {\n                int r = N - 1 - row_right[i];\n                for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int j = row_right[i] + 1; j < N; ++j)\n                    if (oni[i][j]) oni_rem[i][j] = false;\n            }\n        }\n    }\n\n    // output\n    for (const string& op : ops) cout << op << '\\n';\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint best_a[N], best_b[N];\nint best_error;\n\nint simulate(const int a[], const int b[]) {\n    int count[N] = {0};\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int t = count[current];\n        int next;\n        if (t % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nvoid greedy_init() {\n    int count[N] = {0};\n    fill(a, a + N, -1);\n    fill(b, b + N, -1);\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int parity = count[current] % 2;\n        int next;\n        if (parity == 1) {\n            if (a[current] == -1) {\n                int best_j = 0;\n                int best_val = T[0] - count[0];\n                for (int j = 1; j < N; j++) {\n                    int val = T[j] - count[j];\n                    if (val > best_val) {\n                        best_val = val;\n                        best_j = j;\n                    }\n                }\n                a[current] = best_j;\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                int best_j = 0;\n                int best_val = T[0] - count[0];\n                for (int j = 1; j < N; j++) {\n                    int val = T[j] - count[j];\n                    if (val > best_val) {\n                        best_val = val;\n                        best_j = j;\n                    }\n                }\n                b[current] = best_j;\n            }\n            next = b[current];\n        }\n        current = next;\n    }\n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, l;\n    cin >> n >> l;\n    for (int i = 0; i < n; i++) {\n        cin >> T[i];\n    }\n\n    greedy_init();\n    int current_error = simulate(a, b);\n    best_error = current_error;\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis_emp(0, N - 1);\n    uniform_int_distribution<> dis_which(0, 1);\n\n    for (int iter = 0; iter < 100; iter++) {\n        int new_a[N], new_b[N];\n        memcpy(new_a, a, sizeof(a));\n        memcpy(new_b, b, sizeof(b));\n\n        int i = dis_emp(gen);\n        int which = dis_which(gen);\n        int new_val = dis_emp(gen);\n        if (which == 0) {\n            new_a[i] = new_val;\n        } else {\n            new_b[i] = new_val;\n        }\n\n        int new_error = simulate(new_a, new_b);\n        if (new_error < current_error) {\n            memcpy(a, new_a, sizeof(a));\n            memcpy(b, new_b, sizeof(b));\n            current_error = new_error;\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, new_a, sizeof(new_a));\n                memcpy(best_b, new_b, sizeof(new_b));\n            }\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n#include <functional>\n\nusing namespace std;\n\n// Query function\nvector<pair<int, int>> query(const vector<int>& cities) {\n    int l = cities.size();\n    cout << \"? \" << l;\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(min(a, b), max(a, b));\n    }\n    return edges;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Sort cities by center coordinates\n    vector<int> cities(N);\n    for (int i = 0; i < N; i++) cities[i] = i;\n    \n    sort(cities.begin(), cities.end(), [&](int i, int j) {\n        int ci = lx[i] + rx[i];\n        int cj = lx[j] + rx[j];\n        if (ci != cj) return ci < cj;\n        int di = ly[i] + ry[i];\n        int dj = ly[j] + ry[j];\n        if (di != dj) return di < dj;\n        return i < j;\n    });\n    \n    // Partition into groups\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(cities[idx++]);\n        }\n    }\n    \n    // Store edges for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    \n    // Process each group\n    for (int i = 0; i < M; i++) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        \n        // If group size is small enough, query entire group\n        if (sz <= L) {\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n        } else {\n            // Overlapping windows\n            int start = 0;\n            while (start < sz - 1) {\n                int end = min(start + L, sz);\n                vector<int> window(groups[i].begin() + start, groups[i].begin() + end);\n                if (window.size() >= 2) {\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                }\n                start = end - 1; // Overlap by one city\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        // Output cities in group\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        \n        // Output edges\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 <string>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    vector<string> actions;\n    int cx = targets[0].first, cy = targets[0].second;\n    const int MAX_ACTIONS = 800;\n\n    for (int k = 1; k < M; ++k) {\n        int tx = targets[k].first, ty = targets[k].second;\n        while ((cx != tx || cy != ty) && actions.size() < MAX_ACTIONS) {\n            if (cx == tx) {\n                if (ty == 0 && cy > 0) {\n                    actions.push_back(\"S L\");\n                    cy = 0;\n                } else if (ty == N - 1 && cy < N - 1) {\n                    actions.push_back(\"S R\");\n                    cy = N - 1;\n                } else {\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            } else if (cy == ty) {\n                if (tx == 0 && cx > 0) {\n                    actions.push_back(\"S U\");\n                    cx = 0;\n                } else if (tx == N - 1 && cx < N - 1) {\n                    actions.push_back(\"S D\");\n                    cx = N - 1;\n                } else {\n                    if (cx < tx) {\n                        actions.push_back(\"M D\");\n                        cx++;\n                    } else {\n                        actions.push_back(\"M U\");\n                        cx--;\n                    }\n                }\n            } else {\n                // Move vertically first\n                if (cx < tx) {\n                    actions.push_back(\"M D\");\n                    cx++;\n                } else if (cx > tx) {\n                    actions.push_back(\"M U\");\n                    cx--;\n                } else {\n                    // Should not happen, but fallback\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            }\n        }\n        if (actions.size() >= MAX_ACTIONS) {\n            break;\n        }\n    }\n\n    // Output actions\n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n\n    return 0;\n}"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <tuple>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nvector<Company> comps;\nvector<tuple<int, int, int, int>> ans;\n\nvoid rec(vector<int>& idx, int x_min, int x_max, int y_min, int y_max) {\n    if (idx.empty()) return;\n    if (idx.size() == 1) {\n        int i = idx[0];\n        int W = x_max - x_min;\n        int H = y_max - y_min;\n        int r = comps[i].r;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - r);\n        for (int w = 1; w <= W; ++w) {\n            int h1 = max(1, min(H, (int)(r / w)));\n            int h2 = max(1, min(H, (int)ceil((double)r / w)));\n            int area1 = w * h1;\n            int diff1 = abs(area1 - r);\n            if (diff1 < best_diff) {\n                best_diff = diff1;\n                best_w = w;\n                best_h = h1;\n            }\n            int area2 = w * h2;\n            int diff2 = abs(area2 - r);\n            if (diff2 < best_diff) {\n                best_diff = diff2;\n                best_w = w;\n                best_h = h2;\n            }\n        }\n        int a = max(x_min, comps[i].x - (best_w - 1));\n        a = min(a, x_max - best_w);\n        int b = max(y_min, comps[i].y - (best_h - 1));\n        b = min(b, y_max - best_h);\n        int c = a + best_w;\n        int d = b + best_h;\n        ans[i] = {a, b, c, d};\n        return;\n    }\n\n    long long total_r = 0;\n    for (int i : idx) total_r += comps[i].r;\n\n    double best_diff = 1e18;\n    int best_dir = -1; // 0 vertical, 1 horizontal\n    int best_c = -1;\n\n    // Try vertical split\n    vector<int> sorted_x = idx;\n    sort(sorted_x.begin(), sorted_x.end(), [&](int i, int j) { return comps[i].x < comps[j].x; });\n    if (comps[sorted_x.front()].x != comps[sorted_x.back()].x) {\n        vector<long long> prefix_x(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_x.size(); ++j) {\n            prefix_x[j + 1] = prefix_x[j] + comps[sorted_x[j]].r;\n        }\n        for (int p = 1; p < sorted_x.size(); ++p) {\n            long long left_sum = prefix_x[p];\n            double desired_width = (left_sum / (double)total_r) * (x_max - x_min);\n            double ideal_c = x_min + desired_width;\n            int c_min = comps[sorted_x[p - 1]].x + 1;\n            int c_max = comps[sorted_x[p]].x;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_width = c - x_min;\n            double diff = fabs(actual_width - desired_width);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 0;\n                best_c = c;\n            }\n        }\n    }\n\n    // Try horizontal split\n    vector<int> sorted_y = idx;\n    sort(sorted_y.begin(), sorted_y.end(), [&](int i, int j) { return comps[i].y < comps[j].y; });\n    if (comps[sorted_y.front()].y != comps[sorted_y.back()].y) {\n        vector<long long> prefix_y(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_y.size(); ++j) {\n            prefix_y[j + 1] = prefix_y[j] + comps[sorted_y[j]].r;\n        }\n        for (int p = 1; p < sorted_y.size(); ++p) {\n            long long left_sum = prefix_y[p];\n            double desired_height = (left_sum / (double)total_r) * (y_max - y_min);\n            double ideal_c = y_min + desired_height;\n            int c_min = comps[sorted_y[p - 1]].y + 1;\n            int c_max = comps[sorted_y[p]].y;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_height = c - y_min;\n            double diff = fabs(actual_height - desired_height);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 1;\n                best_c = c;\n            }\n        }\n    }\n\n    if (best_dir == 0) {\n        vector<int> left_idx, right_idx;\n        for (int i : idx) {\n            if (comps[i].x < best_c) left_idx.push_back(i);\n            else right_idx.push_back(i);\n        }\n        rec(left_idx, x_min, best_c, y_min, y_max);\n        rec(right_idx, best_c, x_max, y_min, y_max);\n    } else {\n        vector<int> bottom_idx, top_idx;\n        for (int i : idx) {\n            if (comps[i].y < best_c) bottom_idx.push_back(i);\n            else top_idx.push_back(i);\n        }\n        rec(bottom_idx, x_min, x_max, y_min, best_c);\n        rec(top_idx, x_min, x_max, best_c, y_max);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    cin >> n;\n    comps.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> comps[i].x >> comps[i].y >> comps[i].r;\n    }\n\n    ans.resize(n);\n    vector<int> all_idx(n);\n    for (int i = 0; i < n; ++i) all_idx[i] = i;\n    rec(all_idx, 0, 10000, 0, 10000);\n\n    for (int i = 0; i < n; ++i) {\n        auto [a, b, c, d] = ans[i];\n        cout << a << \" \" << b << \" \" << c << \" \" << d << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <algorithm>\n#include <string>\n#include <utility>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nstruct State {\n    int i, j;\n    int score;\n    vector<pair<int, int>> neighbors;\n    int next_idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> t(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    vector<vector<int>> p(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    int M = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            M = max(M, t[i][j] + 1);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 1.9; // seconds\n\n    int best_score = p[si][sj];\n    vector<char> best_path;\n\n    vector<char> visited(M, 0);\n    visited[t[si][sj]] = 1;\n\n    // Helper to count unvisited neighbors of (i,j)\n    auto count_unvisited = [&](int i, int j) {\n        int cnt = 0;\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 && !visited[t[ni][nj]])\n                ++cnt;\n        }\n        return cnt;\n    };\n\n    vector<State> stack;\n    vector<char> current_path;\n\n    // Initialize start state\n    vector<pair<int, int>> start_neighbors;\n    for (int d = 0; d < 4; ++d) {\n        int ni = si + di[d], nj = sj + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[t[ni][nj]])\n            start_neighbors.emplace_back(ni, nj);\n    }\n    // Sort start_neighbors by heuristic\n    vector<tuple<int, int, int, int>> temp;\n    for (auto [ni, nj] : start_neighbors) {\n        int weight = p[ni][nj] + 5 * count_unvisited(ni, nj);\n        int rand_val = uniform_int_distribution<int>(0, 1000000)(rng);\n        temp.emplace_back(ni, nj, weight, rand_val);\n    }\n    sort(temp.begin(), temp.end(), [](const auto& a, const auto& b) {\n        if (get<2>(a) != get<2>(b)) return get<2>(a) > get<2>(b);\n        return get<3>(a) > get<3>(b);\n    });\n    start_neighbors.clear();\n    for (auto [ni, nj, w, r] : temp)\n        start_neighbors.emplace_back(ni, nj);\n\n    stack.push_back({si, sj, p[si][sj], start_neighbors, 0});\n\n    while (!stack.empty() &&\n           chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < time_limit) {\n        State& top = stack.back();\n        if (top.next_idx >= (int)top.neighbors.size()) {\n            // Backtrack\n            if (t[top.i][top.j] != t[si][sj]) // do not unmark start tile\n                visited[t[top.i][top.j]] = 0;\n            stack.pop_back();\n            if (!current_path.empty())\n                current_path.pop_back();\n            continue;\n        }\n\n        // Try next neighbor\n        auto [ni, nj] = top.neighbors[top.next_idx++];\n        int tile = t[ni][nj];\n        visited[tile] = 1;\n        int new_score = top.score + p[ni][nj];\n\n        // Compute move character\n        char move;\n        if (ni == top.i - 1 && nj == top.j) move = 'U';\n        else if (ni == top.i + 1 && nj == top.j) move = 'D';\n        else if (ni == top.i && nj == top.j - 1) move = 'L';\n        else if (ni == top.i && nj == top.j + 1) move = 'R';\n        else assert(false);\n\n        current_path.push_back(move);\n        if (new_score > best_score) {\n            best_score = new_score;\n            best_path = current_path;\n        }\n\n        // Generate neighbors for the new state\n        vector<pair<int, int>> new_neighbors;\n        for (int d = 0; d < 4; ++d) {\n            int nni = ni + di[d], nnj = nj + dj[d];\n            if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && !visited[t[nni][nnj]])\n                new_neighbors.emplace_back(nni, nnj);\n        }\n\n        // Sort new_neighbors by heuristic with random tie-breaking\n        vector<tuple<int, int, int, int>> temp_new;\n        for (auto [nni, nnj] : new_neighbors) {\n            int weight = p[nni][nnj] + 5 * count_unvisited(nni, nnj);\n            int rand_val = uniform_int_distribution<int>(0, 1000000)(rng);\n            temp_new.emplace_back(nni, nnj, weight, rand_val);\n        }\n        sort(temp_new.begin(), temp_new.end(), [](const auto& a, const auto& b) {\n            if (get<2>(a) != get<2>(b)) return get<2>(a) > get<2>(b);\n            return get<3>(a) > get<3>(b);\n        });\n        new_neighbors.clear();\n        for (auto [nni, nnj, w, r] : temp_new)\n            new_neighbors.emplace_back(nni, nnj);\n\n        stack.push_back({ni, nj, new_score, new_neighbors, 0});\n    }\n\n    // Output the best path\n    for (char c : best_path)\n        cout << c;\n    cout << endl;\n\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int ROWS = 30;\nconst int COLS = 30;\n\n// Direction vectors: U, D, L, R\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nvector<vector<double>> h_est(ROWS, vector<double>(COLS-1, 5000.0));\nvector<vector<double>> v_est(ROWS-1, vector<double>(COLS, 5000.0));\nvector<vector<int>> h_count(ROWS, vector<int>(COLS-1, 0));\nvector<vector<int>> v_count(ROWS-1, vector<int>(COLS, 0)); // Fixed type\n\npair<string, double> find_path(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(ROWS, vector<double>(COLS, 1e18));\n    vector<vector<pair<int,int>>> parent(ROWS, vector<pair<int,int>>(COLS, {-1,-1}));\n    vector<vector<int>> dir_used(ROWS, vector<int>(COLS, -1));\n    \n    dist[si][sj] = 0;\n    using Node = pair<double, pair<int,int>>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    pq.push({0.0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, node] = pq.top(); pq.pop();\n        auto [i, j] = node;\n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + dr[dir];\n            int nj = j + dc[dir];\n            if (ni < 0 || ni >= ROWS || nj < 0 || nj >= COLS) continue;\n            \n            double w;\n            if (dir == 0) w = v_est[ni][nj]; // U\n            else if (dir == 1) w = v_est[i][j]; // D\n            else if (dir == 2) w = h_est[i][nj]; // L\n            else w = h_est[i][j]; // R\n            \n            if (dist[ni][nj] > d + w + 1e-9) {\n                dist[ni][nj] = d + w;\n                parent[ni][nj] = {i, j};\n                dir_used[ni][nj] = dir;\n                pq.push({dist[ni][nj], {ni, nj}});\n            }\n        }\n    }\n    \n    string path;\n    double est_len = 0;\n    int ci = ti, cj = tj;\n    \n    while (ci != si || cj != sj) {\n        int dir = dir_used[ci][cj];\n        path += dir_char[dir];\n        \n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        \n        if (dir == 0) { // U\n            est_len += v_est[ci][cj];\n        } else if (dir == 1) { // D\n            est_len += v_est[pi][pj];\n        } else if (dir == 2) { // L\n            est_len += h_est[ci][cj];\n        } else { // R\n            est_len += h_est[pi][pj];\n        }\n        \n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, est_len};\n}\n\nvoid update_weights(const string& path, int si, int sj, double observed) {\n    int i = si, j = sj;\n    double est_len = 0;\n    vector<tuple<int,int,bool>> edges;\n    \n    for (char c : path) {\n        int dir;\n        if (c == 'U') dir = 0;\n        else if (c == 'D') dir = 1;\n        else if (c == 'L') dir = 2;\n        else dir = 3;\n        \n        int ni = i + dr[dir];\n        int nj = j + dc[dir];\n        \n        if (dir == 0) {\n            edges.emplace_back(ni, nj, false);\n            est_len += v_est[ni][nj];\n        } else if (dir == 1) {\n            edges.emplace_back(i, j, false);\n            est_len += v_est[i][j];\n        } else if (dir == 2) {\n            edges.emplace_back(i, nj, true);\n            est_len += h_est[i][nj];\n        } else {\n            edges.emplace_back(i, j, true);\n            est_len += h_est[i][j];\n        }\n        \n        i = ni;\n        j = nj;\n    }\n    \n    double error = observed - est_len;\n    int edge_count = edges.size();\n    if (edge_count == 0) return;\n    \n    for (auto [r, c, is_horiz] : edges) {\n        double lr = 1.0 / (1.0 + (is_horiz ? h_count[r][c] : v_count[r][c]));\n        double delta = lr * error / edge_count;\n        \n        if (is_horiz) {\n            h_est[r][c] += delta;\n            h_est[r][c] = max(1000.0, min(9000.0, h_est[r][c]));\n            h_count[r][c]++;\n        } else {\n            v_est[r][c] += delta;\n            v_est[r][c] = max(1000.0, min(9000.0, v_est[r][c]));\n            v_count[r][c]++;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [path, est_len] = find_path(si, sj, ti, tj);\n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_weights(path, si, sj, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int ALPHABET = 8;\nconst int TOTAL_SYMBOLS = 9;  // A-H and '.'\nconst int K = 10000;          // weight for c in objective\n\n// Placement structure\nstruct Placement {\n    int str_id;\n    int mismatch_count;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    cin >> N >> M;\n    vector<string> strs(M);\n    vector<int> len(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n        len[i] = strs[i].size();\n    }\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Initialize grid with random letters\n    char grid[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + rng() % ALPHABET;\n        }\n    }\n\n    // Precompute placements and mapping from cells to placements\n    vector<Placement> placements;\n    vector<vector<pair<int, char>>> cell_to_placements(N * N);\n    vector<int> valid_placement_count(M, 0);\n\n    for (int sid = 0; sid < M; ++sid) {\n        int L = len[sid];\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int dir = 0; dir < 2; ++dir) {  // 0: horizontal, 1: vertical\n                    int pid = placements.size();\n                    placements.push_back({sid, 0});\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {  // horizontal\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {  // vertical\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        char required = strs[sid][p];\n                        cell_to_placements[ni * N + nj].emplace_back(pid, required);\n                        if (grid[ni][nj] != required) {\n                            placements[pid].mismatch_count++;\n                        }\n                    }\n                    if (placements[pid].mismatch_count == 0) {\n                        valid_placement_count[sid]++;\n                    }\n                }\n            }\n        }\n    }\n\n    // Compute initial coverage and number of empty cells\n    int c = 0;\n    for (int i = 0; i < M; ++i) {\n        if (valid_placement_count[i] > 0) c++;\n    }\n    int d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] == '.') d++;\n        }\n    }\n    int current_obj = c * K + (c == M ? (N * N - d) : 0);\n\n    // Simulated annealing parameters\n    double temp = 100.0;\n    const double cooling_rate = 0.99999;\n    const int max_iter = 2000000;\n    auto start_time = chrono::steady_clock::now();\n\n    // SA main loop\n    for (int iter = 0; iter < max_iter; ++iter) {\n        // Check time limit\n        if (iter % 1000 == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 2.9) break;\n        }\n\n        // Pick a random cell and a new symbol\n        int pos = rng() % (N * N);\n        int i = pos / N, j = pos % N;\n        char old_char = grid[i][j];\n        int sym = rng() % TOTAL_SYMBOLS;\n        char new_char = (sym == ALPHABET) ? '.' : ('A' + sym);\n        if (old_char == new_char) continue;\n\n        // Compute change in empty cells\n        int new_d = d;\n        if (old_char == '.' && new_char != '.') new_d--;\n        if (old_char != '.' && new_char == '.') new_d++;\n\n        // Compute changes in valid placement counts for affected strings\n        unordered_map<int, int> delta_count;\n        for (const auto& inc : cell_to_placements[pos]) {\n            int pid = inc.first;\n            char required = inc.second;\n            Placement& pl = placements[pid];\n            bool old_match = (old_char == required);\n            bool new_match = (new_char == required);\n            if (old_match && !new_match) {\n                if (pl.mismatch_count == 0) {\n                    delta_count[pl.str_id]--;\n                }\n            } else if (!old_match && new_match) {\n                if (pl.mismatch_count == 1) {\n                    delta_count[pl.str_id]++;\n                }\n            }\n        }\n\n        // Compute new coverage\n        int new_c = c;\n        for (const auto& p : delta_count) {\n            int str_id = p.first;\n            int delta = p.second;\n            bool old_covered = (valid_placement_count[str_id] > 0);\n            bool new_covered = (valid_placement_count[str_id] + delta > 0);\n            if (old_covered && !new_covered) new_c--;\n            if (!old_covered && new_covered) new_c++;\n        }\n\n        // Compute new objective\n        int new_obj = new_c * K + (new_c == M ? (N * N - new_d) : 0);\n        int delta_obj = new_obj - current_obj;\n\n        // Acceptance probability\n        if (delta_obj > 0 || (temp > 0 && (double)rng() / rng.max() < exp(delta_obj / temp))) {\n            // Apply the move\n            grid[i][j] = new_char;\n            for (const auto& inc : cell_to_placements[pos]) {\n                int pid = inc.first;\n                char required = inc.second;\n                Placement& pl = placements[pid];\n                bool old_match = (old_char == required);\n                bool new_match = (new_char == required);\n                if (old_match && !new_match) pl.mismatch_count++;\n                else if (!old_match && new_match) pl.mismatch_count--;\n            }\n            for (const auto& p : delta_count) {\n                valid_placement_count[p.first] += p.second;\n            }\n            c = new_c;\n            d = new_d;\n            current_obj = new_obj;\n        }\n\n        // Cool down\n        temp *= cooling_rate;\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        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<int>> cost;               // -1 for obstacle, else digit 5-9\nvector<vector<int>> row_seg, col_seg;   // segment ids for each cell\nint R_cnt, C_cnt;                       // number of row/column segments\nvector<vector<pair<int, int>>> row_cells, col_cells; // cells in each segment\nvector<unordered_map<int, pair<int, int>>> cell_of;  // (r,c) -> (i,j)\n\n// Directions: up, down, left, right\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// Linear index for a cell\ninline int to_id(int i, int j) { return i * N + j; }\ninline pair<int, int> from_id(int id) { return {id / N, id % N}; }\n\n// ----------------------------------------------------------------------\n// Dijkstra from a source, returns distances and predecessors\nstruct DijkstraResult {\n    vector<vector<int>> dist;\n    vector<vector<int>> prev;   // previous cell as linear id\n    DijkstraResult() : dist(N, vector<int>(N, INF)), prev(N, vector<int>(N, -1)) {}\n};\n\nDijkstraResult run_dijkstra(int si, int sj) {\n    DijkstraResult res;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    res.dist[si][sj] = 0;\n    pq.push({0, to_id(si, sj)});\n    while (!pq.empty()) {\n        auto [d, id] = pq.top(); pq.pop();\n        auto [i, j] = from_id(id);\n        if (d != res.dist[i][j]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (cost[ni][nj] == -1) continue;   // obstacle\n            int nd = d + cost[ni][nj];\n            if (nd < res.dist[ni][nj]) {\n                res.dist[ni][nj] = nd;\n                res.prev[ni][nj] = id;\n                pq.push({nd, to_id(ni, nj)});\n            }\n        }\n    }\n    return res;\n}\n\n// ----------------------------------------------------------------------\n// Hopcroft\u2013Karp for bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> matchL, matchR, dist;\n    HopcroftKarp(int nL, int nR) : nL(nL), nR(nR), adj(nL), matchL(nL, -1), matchR(nR, -1), dist(nL) {}\n    void addEdge(int u, int v) { adj[u].push_back(v); }\n    bool bfs() {\n        queue<int> q;\n        for (int u = 0; u < nL; ++u) {\n            if (matchL[u] == -1) {\n                dist[u] = 0;\n                q.push(u);\n            } else dist[u] = INF;\n        }\n        bool found = false;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (matchR[v] == -1) found = true;\n                else if (dist[matchR[v]] == INF) {\n                    dist[matchR[v]] = dist[u] + 1;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n        return found;\n    }\n    bool dfs(int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 || (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = INF;\n        return false;\n    }\n    int maxMatching() {\n        int matching = 0;\n        while (bfs()) {\n            for (int u = 0; u < nL; ++u)\n                if (matchL[u] == -1 && dfs(u))\n                    ++matching;\n        }\n        return matching;\n    }\n};\n\n// ----------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input --------------------------------------------------------\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    cost.assign(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                cost[i][j] = grid[i][j] - '0';\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n\n    // ----- Row segments -------------------------------------------------\n    row_seg.assign(N, vector<int>(N, -1));\n    R_cnt = 0;\n    row_cells.clear();\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (cost[i][j] != -1) {\n                int start_j = j;\n                while (j < N && cost[i][j] != -1) {\n                    row_seg[i][j] = R_cnt;\n                    ++j;\n                }\n                row_cells.emplace_back();\n                for (int k = start_j; k < j; ++k)\n                    row_cells.back().emplace_back(i, k);\n                ++R_cnt;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ----- Column segments ----------------------------------------------\n    col_seg.assign(N, vector<int>(N, -1));\n    C_cnt = 0;\n    col_cells.clear();\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (cost[i][j] != -1) {\n                int start_i = i;\n                while (i < N && cost[i][j] != -1) {\n                    col_seg[i][j] = C_cnt;\n                    ++i;\n                }\n                col_cells.emplace_back();\n                for (int k = start_i; k < i; ++k)\n                    col_cells.back().emplace_back(k, j);\n                ++C_cnt;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ----- Build full bipartite graph (row segments vs column segments) -\n    HopcroftKarp hk_full(R_cnt, C_cnt);\n    cell_of.resize(R_cnt);\n    for (auto [i, j] : road_cells) {\n        int r = row_seg[i][j];\n        int c = col_seg[i][j];\n        hk_full.addEdge(r, c);\n        cell_of[r][c] = {i, j};\n    }\n\n    // ----- Maximum matching and minimum vertex cover --------------------\n    hk_full.maxMatching();\n\n    vector<bool> visL(R_cnt, false), visR(C_cnt, false);\n    function<void(int)> dfs_cover = [&](int u) {\n        visL[u] = true;\n        for (int v : hk_full.adj[u]) {\n            if (!visR[v] && hk_full.matchL[u] != v) {\n                visR[v] = true;\n                if (hk_full.matchR[v] != -1 && !visL[hk_full.matchR[v]])\n                    dfs_cover(hk_full.matchR[v]);\n            }\n        }\n    };\n    for (int u = 0; u < R_cnt; ++u)\n        if (hk_full.matchL[u] == -1)\n            dfs_cover(u);\n\n    vector<bool> inX(R_cnt, false), inY(C_cnt, false);\n    for (int u = 0; u < R_cnt; ++u) if (!visL[u]) inX[u] = true;\n    for (int v = 0; v < C_cnt; ++v) if (visR[v]) inY[v] = true;\n\n    // ----- Remove start's own segments ----------------------------------\n    int r_start = row_seg[si][sj];\n    int c_start = col_seg[si][sj];\n    if (r_start != -1) inX[r_start] = false;\n    if (c_start != -1) inY[c_start] = false;\n\n    // ----- Collect vertices that still need covering --------------------\n    vector<int> X_list, Y_list;\n    for (int u = 0; u < R_cnt; ++u) if (inX[u]) X_list.push_back(u);\n    for (int v = 0; v < C_cnt; ++v) if (inY[v]) Y_list.push_back(v);\n    int nX = X_list.size(), nY = Y_list.size();\n\n    // If nothing left to cover, we only need to start and return.\n    if (nX == 0 && nY == 0) {\n        // Trivial tour: go to an adjacent road cell and back.\n        for (int d = 0; d < 4; ++d) {\n            int ni = si + di[d], nj = sj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && cost[ni][nj] != -1) {\n                cout << dir_char[d];\n                // Opposite direction\n                if (d == 0) cout << 'D';\n                else if (d == 1) cout << 'U';\n                else if (d == 2) cout << 'R';\n                else cout << 'L';\n                cout << endl;\n                return 0;\n            }\n        }\n        // Should not happen (graph is connected), but fallback:\n        cout << endl;\n        return 0;\n    }\n\n    // ----- Build subgraph between X_list and Y_list --------------------\n    vector<int> X_index(R_cnt, -1), Y_index(C_cnt, -1);\n    for (int i = 0; i < nX; ++i) X_index[X_list[i]] = i;\n    for (int i = 0; i < nY; ++i) Y_index[Y_list[i]] = i;\n\n    HopcroftKarp hk_sub(nX, nY);\n    vector<unordered_map<int, pair<int, int>>> sub_cell_of(nX);\n    for (int r : X_list) {\n        int i = X_index[r];\n        for (auto &[c, coord] : cell_of[r]) {\n            if (inY[c]) {\n                int j = Y_index[c];\n                hk_sub.addEdge(i, j);\n                sub_cell_of[i][j] = {r, c};\n            }\n        }\n    }\n\n    // ----- Maximum matching in subgraph ---------------------------------\n    hk_sub.maxMatching();\n\n    // ----- Precompute distances from start (for picking close cells) ----\n    auto dist_start_res = run_dijkstra(si, sj);\n    auto &dist_start = dist_start_res.dist;\n\n    // ----- Construct set S of cells to visit ----------------------------\n    set<pair<int, int>> S_set;\n\n    // Cells from the matching\n    for (int i = 0; i < nX; ++i) {\n        int j = hk_sub.matchL[i];\n        if (j != -1) {\n            auto [r, c] = sub_cell_of[i][j];\n            S_set.insert(cell_of[r][c]);\n        }\n    }\n\n    // Unmatched row segments: pick closest cell to start\n    for (int i = 0; i < nX; ++i) {\n        if (hk_sub.matchL[i] == -1) {\n            int r = X_list[i];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : row_cells[r]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    // Unmatched column segments: pick closest cell to start\n    for (int j = 0; j < nY; ++j) {\n        if (hk_sub.matchR[j] == -1) {\n            int c = Y_list[j];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : col_cells[c]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    vector<pair<int, int>> points(S_set.begin(), S_set.end());\n    int K = points.size();\n\n    // ----- All-pairs shortest paths among points and start -------------\n    int total_nodes = K + 1;          // indices 0..K-1 : points, K : start\n    vector<vector<int>> dist_mat(total_nodes, vector<int>(total_nodes, INF));\n    vector<DijkstraResult> dijkstra_res(total_nodes);\n\n    for (int idx = 0; idx < total_nodes; ++idx) {\n        int i, j;\n        if (idx < K) {\n            i = points[idx].first, j = points[idx].second;\n        } else {\n            i = si, j = sj;\n        }\n        dijkstra_res[idx] = run_dijkstra(i, j);\n        auto &res = dijkstra_res[idx];\n        for (int other = 0; other < total_nodes; ++other) {\n            int oi, oj;\n            if (other < K) {\n                oi = points[other].first, oj = points[other].second;\n            } else {\n                oi = si, oj = sj;\n            }\n            dist_mat[idx][other] = res.dist[oi][oj];\n        }\n    }\n\n    // ----- Initial tour using nearest neighbor --------------------------\n    vector<int> order;                 // order of visiting points (indices 0..K-1)\n    vector<bool> visited(K, false);\n    int cur = K;                       // start index\n    while ((int)order.size() < K) {\n        int nxt = -1;\n        int best = INF;\n        for (int j = 0; j < K; ++j) {\n            if (!visited[j] && dist_mat[cur][j] < best) {\n                best = dist_mat[cur][j];\n                nxt = j;\n            }\n        }\n        if (nxt == -1) break;          // should not happen (graph connected)\n        visited[nxt] = true;\n        order.push_back(nxt);\n        cur = nxt;\n    }\n\n    // ----- 2-opt improvement for directed TSP --------------------------\n    auto compute_order_cost = [&](const vector<int>& ord) {\n        int total = 0;\n        int cur = K;\n        for (int idx : ord) {\n            total += dist_mat[cur][idx];\n            cur = idx;\n        }\n        total += dist_mat[cur][K];\n        return total;\n    };\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < K-1; ++i) {\n            for (int j = i+1; j < K; ++j) {\n                // Nodes before and after the segment\n                int a = (i == 0) ? K : order[i-1];\n                int b = order[i];\n                int c = order[j];\n                int d = (j == K-1) ? K : order[j+1];\n\n                // Old edges\n                int old_edges = dist_mat[a][b] + dist_mat[c][d];\n                // New edges after reversal\n                int new_edges = dist_mat[a][c] + dist_mat[b][d];\n\n                // Old internal cost of segment i..j\n                int old_internal = 0;\n                for (int k = i; k < j; ++k) {\n                    old_internal += dist_mat[order[k]][order[k+1]];\n                }\n                // New internal cost after reversal\n                int new_internal = 0;\n                for (int k = j; k > i; --k) {\n                    new_internal += dist_mat[order[k]][order[k-1]];\n                }\n\n                int delta = (new_edges + new_internal) - (old_edges + old_internal);\n                if (delta < 0) {\n                    // Apply reversal\n                    reverse(order.begin() + i, order.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // ----- Build final tour (start -> order -> start) -------------------\n    vector<int> tour;\n    tour.push_back(K);                 // start\n    for (int x : order) tour.push_back(x);\n    tour.push_back(K);                 // return to start\n\n    // ----- Reconstruct the move string ---------------------------------\n    string moves;\n    for (size_t t = 0; t + 1 < tour.size(); ++t) {\n        int from_idx = tour[t], to_idx = tour[t + 1];\n        auto [fi, fj] = (from_idx < K) ? points[from_idx] : make_pair(si, sj);\n        auto [ti, tj] = (to_idx < K) ? points[to_idx] : make_pair(si, sj);\n        auto &res = dijkstra_res[from_idx];\n\n        // Backtrack from (ti,tj) to (fi,fj)\n        vector<pair<int, int>> path;\n        int ci = ti, cj = tj;\n        while (!(ci == fi && cj == fj)) {\n            path.emplace_back(ci, cj);\n            int pid = res.prev[ci][cj];\n            if (pid == -1) break;      // should not happen\n            auto [pi, pj] = from_id(pid);\n            ci = pi; cj = pj;\n        }\n        path.emplace_back(fi, fj);\n        reverse(path.begin(), path.end());\n\n        // Convert path to moves\n        for (size_t i = 0; i + 1 < path.size(); ++i) {\n            auto [cur_i, cur_j] = path[i];\n            auto [nxt_i, nxt_j] = path[i + 1];\n            for (int d = 0; d < 4; ++d) {\n                if (cur_i + di[d] == nxt_i && cur_j + dj[d] == nxt_j) {\n                    moves += dir_char[d];\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << moves << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N+1, vector<int>(K));\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n        }\n    }\n    \n    // Build dependency graph\n    vector<vector<int>> children(N+1), parents(N+1);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        children[u].push_back(v);\n        parents[v].push_back(u);\n    }\n    \n    // Compute critical path length (priority)\n    vector<int> priority(N+1, 1);\n    for (int i = N; i >= 1; i--) {\n        for (int child : children[i]) {\n            priority[i] = max(priority[i], priority[child] + 1);\n        }\n    }\n    \n    // State tracking\n    vector<int> task_status(N+1, -1); // -1: not started, 0: in progress, 1: completed\n    vector<int> worker_task(M+1, -1); // -1: idle, else: task being worked on\n    vector<vector<int>> worker_skills(M+1, vector<int>(K, 0)); // Lower bounds\n    \n    // For randomness\n    auto seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    int day = 0;\n    while (true) {\n        day++;\n        \n        // Find available workers\n        vector<int> available_workers;\n        for (int w = 1; w <= M; w++) {\n            if (worker_task[w] == -1) {\n                available_workers.push_back(w);\n            }\n        }\n        \n        // Find ready tasks (all dependencies completed)\n        vector<int> ready_tasks;\n        for (int t = 1; t <= N; t++) {\n            if (task_status[t] != -1) continue;\n            \n            bool all_deps_completed = true;\n            for (int parent : parents[t]) {\n                if (task_status[parent] != 1) {\n                    all_deps_completed = false;\n                    break;\n                }\n            }\n            \n            if (all_deps_completed) {\n                ready_tasks.push_back(t);\n            }\n        }\n        \n        // Sort ready tasks by priority (higher first)\n        sort(ready_tasks.begin(), ready_tasks.end(), \n             [&](int a, int b) { return priority[a] > priority[b]; });\n        \n        // Prepare assignments\n        vector<pair<int, int>> assignments;\n        vector<bool> worker_used(M+1, false);\n        \n        // Greedy assignment with exploration\n        uniform_real_distribution<double> explore_dist(0.0, 1.0);\n        const double EXPLORE_PROB = 0.1;\n        \n        for (int task : ready_tasks) {\n            if (available_workers.empty()) break;\n            \n            int best_worker = -1;\n            double best_score = -1e18;\n            \n            // With some probability, do random assignment for exploration\n            if (explore_dist(rng) < EXPLORE_PROB && available_workers.size() > 1) {\n                uniform_int_distribution<int> worker_dist(0, available_workers.size()-1);\n                int idx = worker_dist(rng);\n                best_worker = available_workers[idx];\n            } else {\n                // Find worker that minimizes expected completion time\n                for (int w : available_workers) {\n                    if (worker_used[w]) continue;\n                    \n                    // Estimate completion time based on current skill bounds\n                    int expected_time = 1;\n                    int deficiency = 0;\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > worker_skills[w][k]) {\n                            deficiency += d[task][k] - worker_skills[w][k];\n                        }\n                    }\n                    if (deficiency > 0) {\n                        expected_time = max(1, deficiency); // Conservative estimate\n                    }\n                    \n                    // Score: prefer higher priority tasks with lower expected time\n                    double score = priority[task] * 1000.0 - expected_time;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_worker = w;\n                    }\n                }\n            }\n            \n            if (best_worker != -1) {\n                assignments.emplace_back(best_worker, task);\n                worker_task[best_worker] = task;\n                task_status[task] = 0;\n                \n                // Remove worker from available list\n                available_workers.erase(\n                    remove(available_workers.begin(), available_workers.end(), best_worker),\n                    available_workers.end()\n                );\n                worker_used[best_worker] = true;\n            }\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [w, t] : assignments) {\n            cout << \" \" << w << \" \" << t;\n        }\n        cout << endl;\n        cout.flush();\n        \n        // Read completion information\n        int completion_count;\n        cin >> completion_count;\n        \n        if (completion_count == -1) {\n            break; // End of simulation\n        }\n        \n        // Update based on completions\n        for (int i = 0; i < completion_count; i++) {\n            int worker;\n            cin >> worker;\n            \n            int task = worker_task[worker];\n            if (task != -1) {\n                task_status[task] = 1;\n                worker_task[worker] = -1;\n                \n                // Update skill estimates if completed in 1 day\n                // (implies skills meet/exceed requirements)\n                for (int k = 0; k < K; k++) {\n                    worker_skills[worker][k] = max(worker_skills[worker][k], d[task][k]);\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nPoint center = {400, 400};\n\ninline int manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Delta cost for inserting pickup X at position p and dropoff Y at position q (p <= q)\n// into the current sequence seq.\nint delta_insert(const vector<int>& seq, int p, int q, int X, int Y,\n                 const vector<vector<int>>& dist) {\n    int n = seq.size();\n    if (n == 0) {\n        // only possible: p = q = 0\n        return dist[100][X] + dist[X][Y] + dist[Y][100];\n    }\n    int A, B;\n    if (p == 0) A = 100; else A = seq[p-1];\n    if (p == n) B = 100; else B = seq[p];\n    if (q == p) {\n        // dropoff immediately after pickup\n        return dist[A][X] + dist[X][Y] + dist[Y][B] - dist[A][B];\n    } else {\n        // q > p\n        int delta = dist[A][X] + dist[X][B] - dist[A][B];\n        // Determine left and right neighbors for Y after X has been inserted\n        int left, right;\n        if (q == n) {\n            left = seq[q-1];\n            right = 100;\n        } else {\n            left = seq[q-1];\n            right = seq[q];\n        }\n        delta += dist[left][Y] + dist[Y][right] - dist[left][right];\n        return delta;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input -----\n    vector<Point> pickup(1000), dropoff(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> pickup[i].x >> pickup[i].y >> dropoff[i].x >> dropoff[i].y;\n    }\n\n    // ----- Order selection -----\n    // Use sum of distances from center to pickup and dropoff as score.\n    vector<int> order_idx(1000);\n    iota(order_idx.begin(), order_idx.end(), 0);\n    vector<int> score(1000);\n    for (int i = 0; i < 1000; ++i) {\n        score[i] = manhattan(center, pickup[i]) + manhattan(center, dropoff[i]);\n    }\n    sort(order_idx.begin(), order_idx.end(),\n         [&](int a, int b) { return score[a] < score[b]; });\n    vector<int> selected(order_idx.begin(), order_idx.begin() + 50);  // original 0\u2011based indices\n\n    // ----- Build nodes for selected orders -----\n    // nodes 0..49 : pickups, nodes 50..99 : dropoffs\n    vector<Point> nodes(100);\n    for (int i = 0; i < 50; ++i) {\n        int ord = selected[i];\n        nodes[i] = pickup[ord];\n        nodes[i + 50] = dropoff[ord];\n    }\n\n    // ----- Precompute distances (including center as node 100) -----\n    vector<Point> pts(101);\n    for (int i = 0; i < 100; ++i) pts[i] = nodes[i];\n    pts[100] = center;\n    vector<vector<int>> dist(101, vector<int>(101));\n    for (int i = 0; i < 101; ++i)\n        for (int j = 0; j < 101; ++j)\n            dist[i][j] = manhattan(pts[i], pts[j]);\n\n    // ----- Initial route construction (insertion heuristic) -----\n    vector<int> seq;                     // current sequence of node indices (0..99)\n    vector<bool> used(50, false);        // which orders are already in the route\n    int current_cost = 0;                // total travel time of current route\n\n    for (int step = 0; step < 50; ++step) {\n        int best_order = -1, best_p, best_q, best_delta = 1e9;\n        // Try every not yet used order\n        for (int i = 0; i < 50; ++i) {\n            if (used[i]) continue;\n            int X = i;          // pickup node\n            int Y = i + 50;     // dropoff node\n            int n = seq.size();\n            // Try all insertion positions p (for pickup) and q (for dropoff) with p <= q\n            for (int p = 0; p <= n; ++p) {\n                for (int q = p; q <= n; ++q) {\n                    int delta = delta_insert(seq, p, q, X, Y, dist);\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_order = i;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        // Insert the best order\n        int X = best_order;\n        int Y = best_order + 50;\n        seq.insert(seq.begin() + best_p, X);\n        seq.insert(seq.begin() + best_q + 1, Y);   // after first insertion, index shifts\n        used[best_order] = true;\n        current_cost += best_delta;\n    }\n\n    // ----- Simulated Annealing (swap moves only) -----\n    int best_cost = current_cost;\n    vector<int> best_seq = seq;\n\n    // Position of each node in the current sequence\n    vector<int> pos(100);\n    for (int i = 0; i < 100; ++i) pos[seq[i]] = i;\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> rand_pos(0, 99);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    const int MAX_ITER = 1000000;\n    double temp = 100.0;\n    const double cooling = 0.999999;   // slow cooling for many iterations\n\n    // Helper: can we swap positions a and b? (a < b)\n    auto can_swap = [&](int a, int b) -> bool {\n        int nodeA = seq[a], nodeB = seq[b];\n        // For nodeA\n        bool pickupA = (nodeA < 50);\n        int new_pos_pickupA, new_pos_dropoffA;\n        if (pickupA) {\n            new_pos_pickupA = b;\n            int dropoffA = nodeA + 50;\n            new_pos_dropoffA = (dropoffA == nodeB) ? a : pos[dropoffA];\n        } else {\n            new_pos_dropoffA = b;\n            int pickupA = nodeA - 50;\n            new_pos_pickupA = (pickupA == nodeB) ? a : pos[pickupA];\n        }\n        if (new_pos_pickupA >= new_pos_dropoffA) return false;\n\n        // For nodeB\n        bool pickupB = (nodeB < 50);\n        int new_pos_pickupB, new_pos_dropoffB;\n        if (pickupB) {\n            new_pos_pickupB = a;\n            int dropoffB = nodeB + 50;\n            new_pos_dropoffB = (dropoffB == nodeA) ? b : pos[dropoffB];\n        } else {\n            new_pos_dropoffB = a;\n            int pickupB = nodeB - 50;\n            new_pos_pickupB = (pickupB == nodeA) ? b : pos[pickupB];\n        }\n        if (new_pos_pickupB >= new_pos_dropoffB) return false;\n\n        return true;\n    };\n\n    // Helper: delta cost for swapping positions a and b (a < b)\n    auto delta_swap = [&](int a, int b) -> int {\n        int n1 = seq[a], n2 = seq[b];\n        int old_cost = 0, new_cost = 0;\n\n        auto get_node = [&](int p) -> int {\n            if (p < 0 || p >= 100) return 100;\n            return seq[p];\n        };\n\n        int lefts[4] = {a-1, a, b-1, b};\n        bool used[4] = {false};\n        for (int i = 0; i < 4; ++i) {\n            if (used[i]) continue;\n            int lp = lefts[i];\n            if (lp < -1 || lp >= 100) continue;\n            for (int j = i+1; j < 4; ++j)\n                if (lefts[j] == lp) used[j] = true;\n\n            int u = get_node(lp);\n            int v = get_node(lp+1);\n            old_cost += dist[u][v];\n\n            int u_new = (lp == a) ? n2 : (lp == b) ? n1 : u;\n            int v_new = (lp+1 == a) ? n2 : (lp+1 == b) ? n1 : v;\n            new_cost += dist[u_new][v_new];\n        }\n        return new_cost - old_cost;\n    };\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        temp *= cooling;\n        int a = rand_pos(gen);\n        int b = rand_pos(gen);\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        if (!can_swap(a, b)) continue;\n\n        int delta = delta_swap(a, b);\n        if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n            int nodeA = seq[a], nodeB = seq[b];\n            seq[a] = nodeB;\n            seq[b] = nodeA;\n            pos[nodeA] = b;\n            pos[nodeB] = a;\n            current_cost += delta;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_seq = seq;\n            }\n        }\n    }\n\n    // ----- Output -----\n    // Selected orders (convert to 1\u2011based)\n    cout << \"50\";\n    for (int idx : selected) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n\n    // Full route: center -> best_seq -> center\n    vector<Point> route;\n    route.push_back(center);\n    for (int id : best_seq) route.push_back(nodes[id]);\n    route.push_back(center);\n\n    cout << route.size();\n    for (Point p : route) cout << \" \" << p.x << \" \" << p.y;\n    cout << endl;\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, d;\n};\n\nclass DSU {\n    vector<int> parent, rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\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]) parent[x] = y;\n        else if (rank[x] > rank[y]) parent[y] = x;\n        else {\n            parent[y] = x;\n            rank[x]++;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    int M;\n    cin >> M;\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        double dx = x[u] - x[v];\n        double dy = y[u] - y[v];\n        double dist = sqrt(dx * dx + dy * dy);\n        int d = round(dist);\n        edges[i] = {u, v, d};\n    }\n    \n    DSU dsu(N);\n    const int K = 400;  // fallback threshold\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        int u = edges[i].u, v = edges[i].v;\n        \n        // If already connected, skip\n        if (dsu.find(u) == dsu.find(v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // In the last K edges, accept any connecting edge to ensure connectivity\n        if (i >= M - K) {\n            dsu.unite(u, v);\n            cout << 1 << endl;\n            continue;\n        }\n        \n        // Find minimum d between the two components\n        int comp_u = dsu.find(u);\n        int comp_v = dsu.find(v);\n        int min_d = INT_MAX;\n        \n        for (int j = 0; j < M; j++) {\n            int a = dsu.find(edges[j].u);\n            int b = dsu.find(edges[j].v);\n            if ((a == comp_u && b == comp_v) || (a == comp_v && b == comp_u)) {\n                min_d = min(min_d, edges[j].d);\n            }\n        }\n        \n        // Accept if length is reasonable compared to best possible\n        if (l <= 2 * min_d) {\n            dsu.unite(u, v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID = 30;\n\n// Pet movement directions\nconst int dx[4] = {1, -1, 0, 0};\nconst int dy[4] = {0, 0, 1, -1};\n\nstruct Task {\n    int target_x, target_y;   // where to stand to build\n    char build_action;        // 'U','D','L','R' to build adjacent wall\n    int wall_x, wall_y;       // the wall square to build\n};\n\nint N, M;\nvector<int> pet_x, pet_y, pet_type;\nvector<int> human_x, human_y;\nbool wall[GRID+1][GRID+1] = {false};  // true if wall\n\n// Helper functions\nbool inside(int x, int y) {\n    return 1 <= x && x <= GRID && 1 <= y && y <= GRID;\n}\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; ++i)\n        if (pet_x[i] == x && pet_y[i] == y)\n            return true;\n    return false;\n}\n\nbool has_adjacent_pet(int x, int y) {\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + dx[d], ny = y + dy[d];\n        if (inside(nx, ny) && has_pet_at(nx, ny))\n            return true;\n    }\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; ++i)\n        if (human_x[i] == x && human_y[i] == y)\n            return true;\n    return false;\n}\n\nchar move_towards(int cx, int cy, int tx, int ty) {\n    if (cx == tx && cy == ty) return '.';\n    int dx = tx - cx, dy = ty - cy;\n    if (abs(dx) >= abs(dy))\n        return (dx > 0) ? 'D' : 'U';\n    else\n        return (dy > 0) ? 'R' : 'L';\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    cin >> N;\n    pet_x.resize(N); pet_y.resize(N); pet_type.resize(N);\n    for (int i = 0; i < N; ++i)\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n    cin >> M;\n    human_x.resize(M); human_y.resize(M);\n    for (int i = 0; i < M; ++i)\n        cin >> human_x[i] >> human_y[i];\n\n    // Initial pet grid for plan selection\n    bool pet_init[GRID+1][GRID+1] = {false};\n    for (int i = 0; i < N; ++i)\n        pet_init[pet_x[i]][pet_y[i]] = true;\n\n    // Plan selection: maximize interior size\n    int best_size = -1;\n    int plan_type = -1;   // 0: horizontal only, 1: vertical only, 2: both\n    int plan_H = -1, plan_V = -1;\n    bool plan_interior_above = true;   // for horizontal\n    bool plan_interior_left = true;    // for vertical\n    int plan_corner = -1;              // for both (0:TL,1:TR,2:BL,3:BR)\n\n    // ---------- One\u2011wall horizontal ----------\n    for (int H = 2; H <= GRID; ++H) {\n        // Wall squares (H, 1..30)\n        bool wall_ok = true;\n        for (int y = 1; y <= GRID; ++y)\n            if (pet_init[H][y]) { wall_ok = false; break; }\n        if (!wall_ok) continue;\n\n        // Interior above\n        bool interior_ok = true;\n        for (int x = 1; x < H; ++x)\n            for (int y = 1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = (H - 1) * GRID;\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 0;\n                plan_H = H;\n                plan_interior_above = true;\n            }\n        }\n\n        // Interior below\n        interior_ok = true;\n        for (int x = H+1; x <= GRID; ++x)\n            for (int y = 1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = (GRID - H) * GRID;\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 0;\n                plan_H = H;\n                plan_interior_above = false;\n            }\n        }\n    }\n\n    // ---------- One\u2011wall vertical ----------\n    for (int V = 2; V <= GRID; ++V) {\n        // Wall squares (1..30, V)\n        bool wall_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            if (pet_init[x][V]) { wall_ok = false; break; }\n        if (!wall_ok) continue;\n\n        // Interior left\n        bool interior_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            for (int y = 1; y < V; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = GRID * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 1;\n                plan_V = V;\n                plan_interior_left = true;\n            }\n        }\n\n        // Interior right\n        interior_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            for (int y = V+1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = GRID * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 1;\n                plan_V = V;\n                plan_interior_left = false;\n            }\n        }\n    }\n\n    // ---------- Two\u2011wall corners ----------\n    // Corner 0: top\u2011left\n    for (int H = 2; H <= GRID; ++H) {\n        for (int V = 2; V <= GRID; ++V) {\n            // Wall: (H, 1..V) and (1..H, V)\n            bool wall_ok = true;\n            for (int y = 1; y <= V; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = 1; x <= H; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: 1..H-1 , 1..V-1\n            bool interior_ok = true;\n            for (int x = 1; x < H; ++x)\n                for (int y = 1; y < V; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (H - 1) * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 0;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 1: top\u2011right\n    for (int H = 2; H <= GRID; ++H) {\n        for (int V = 1; V <= GRID-1; ++V) {\n            // Wall: (H, V..30) and (1..H, V)\n            bool wall_ok = true;\n            for (int y = V; y <= GRID; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = 1; x <= H; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: 1..H-1 , V+1..30\n            bool interior_ok = true;\n            for (int x = 1; x < H; ++x)\n                for (int y = V+1; y <= GRID; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (H - 1) * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 1;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 2: bottom\u2011left\n    for (int H = 1; H <= GRID-1; ++H) {\n        for (int V = 2; V <= GRID; ++V) {\n            // Wall: (H, 1..V) and (H..30, V)\n            bool wall_ok = true;\n            for (int y = 1; y <= V; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = H; x <= GRID; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: H+1..30 , 1..V-1\n            bool interior_ok = true;\n            for (int x = H+1; x <= GRID; ++x)\n                for (int y = 1; y < V; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (GRID - H) * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 2;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 3: bottom\u2011right\n    for (int H = 1; H <= GRID-1; ++H) {\n        for (int V = 1; V <= GRID-1; ++V) {\n            // Wall: (H, V..30) and (H..30, V)\n            bool wall_ok = true;\n            for (int y = V; y <= GRID; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = H; x <= GRID; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: H+1..30 , V+1..30\n            bool interior_ok = true;\n            for (int x = H+1; x <= GRID; ++x)\n                for (int y = V+1; y <= GRID; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (GRID - H) * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 3;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // ---------- Prepare tasks and roles ----------\n    vector<Task> hor_tasks, ver_tasks;\n    int gather_x = 1, gather_y = 1;   // default, will be overwritten\n    vector<int> role(M, 0);           // 0: normal, 1: horizontal builder, 2: vertical builder\n\n    if (plan_type == 0) { // horizontal only\n        if (plan_interior_above) {\n            gather_x = 1; gather_y = 1;\n            for (int y = 1; y <= GRID; ++y)\n                hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n        } else {\n            gather_x = GRID; gather_y = 1;\n            for (int y = 1; y <= GRID; ++y)\n                hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n        }\n        if (M > 0) role[0] = 1;\n    }\n    else if (plan_type == 1) { // vertical only\n        if (plan_interior_left) {\n            gather_x = 1; gather_y = 1;\n            for (int x = 1; x <= GRID; ++x)\n                ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n        } else {\n            gather_x = 1; gather_y = GRID;\n            for (int x = 1; x <= GRID; ++x)\n                ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n        }\n        if (M > 0) role[0] = 2;\n    }\n    else if (plan_type == 2) { // both walls\n        switch (plan_corner) {\n            case 0: // top\u2011left\n                gather_x = 1; gather_y = 1;\n                for (int y = 1; y <= plan_V; ++y)\n                    hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n                for (int x = 1; x < plan_H; ++x)\n                    ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n                break;\n            case 1: // top\u2011right\n                gather_x = 1; gather_y = GRID;\n                for (int y = plan_V; y <= GRID; ++y)\n                    hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n                for (int x = 1; x < plan_H; ++x)\n                    ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n                break;\n            case 2: // bottom\u2011left\n                gather_x = GRID; gather_y = 1;\n                for (int y = 1; y <= plan_V; ++y)\n                    hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n                for (int x = plan_H; x <= GRID; ++x)\n                    ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n                break;\n            case 3: // bottom\u2011right\n                gather_x = GRID; gather_y = GRID;\n                for (int y = plan_V; y <= GRID; ++y)\n                    hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n                for (int x = plan_H; x <= GRID; ++x)\n                    ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n                break;\n        }\n        if (M > 0) role[0] = 1;\n        if (M > 1) role[1] = 2;\n    }\n\n    // Builder indices\n    int hor_idx = 0, ver_idx = 0;\n\n    // ---------- Simulation ----------\n    for (int turn = 0; turn < 300; ++turn) {\n        vector<char> actions(M, '.');\n\n        for (int i = 0; i < M; ++i) {\n            if (role[i] == 0) { // normal\n                actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n            }\n            else if (role[i] == 1) { // horizontal builder\n                if (hor_idx >= (int)hor_tasks.size()) {\n                    // done \u2013 go to gathering point\n                    actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n                } else {\n                    Task &t = hor_tasks[hor_idx];\n                    if (human_x[i] == t.target_x && human_y[i] == t.target_y) {\n                        // try to build\n                        if (!wall[t.wall_x][t.wall_y] &&\n                            !has_pet_at(t.wall_x, t.wall_y) &&\n                            !has_human_at(t.wall_x, t.wall_y) &&\n                            !has_adjacent_pet(t.wall_x, t.wall_y)) {\n                            actions[i] = t.build_action;\n                            wall[t.wall_x][t.wall_y] = true;\n                            ++hor_idx;\n                        } else {\n                            actions[i] = '.';\n                        }\n                    } else {\n                        actions[i] = move_towards(human_x[i], human_y[i], t.target_x, t.target_y);\n                    }\n                }\n            }\n            else if (role[i] == 2) { // vertical builder\n                if (ver_idx >= (int)ver_tasks.size()) {\n                    actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n                } else {\n                    Task &t = ver_tasks[ver_idx];\n                    if (human_x[i] == t.target_x && human_y[i] == t.target_y) {\n                        if (!wall[t.wall_x][t.wall_y] &&\n                            !has_pet_at(t.wall_x, t.wall_y) &&\n                            !has_human_at(t.wall_x, t.wall_y) &&\n                            !has_adjacent_pet(t.wall_x, t.wall_y)) {\n                            actions[i] = t.build_action;\n                            wall[t.wall_x][t.wall_y] = true;\n                            ++ver_idx;\n                        } else {\n                            actions[i] = '.';\n                        }\n                    } else {\n                        actions[i] = move_towards(human_x[i], human_y[i], t.target_x, t.target_y);\n                    }\n                }\n            }\n        }\n\n        // Output actions\n        for (char c : actions) cout << c;\n        cout << endl;\n        cout.flush();\n\n        // Update human positions according to actions\n        for (int i = 0; i < M; ++i) {\n            if (actions[i] == 'U') human_x[i]--;\n            else if (actions[i] == 'D') human_x[i]++;\n            else if (actions[i] == 'L') human_y[i]--;\n            else if (actions[i] == 'R') human_y[i]++;\n            // build or '.' \u2192 no movement\n        }\n\n        // Read pet movements\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20, W = 20;\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint si, sj, ti, tj;\ndouble p;\nint h[H][W - 1]; // horizontal walls: between (i,j) and (i,j+1)\nint v[H - 1][W]; // vertical walls: between (i,j) and (i+1,j)\n\nstruct MoveData {\n    double stay;       // probability to stay in the same cell\n    double move;       // probability to move to neighbour (0 if blocked)\n    int ni, nj;        // neighbour coordinates (valid only if move>0)\n    bool is_target;    // does moving lead directly to the office?\n};\nMoveData move_info[H][W][4];\nint dir_to_idx[256];\n\n// Precompute transition data for every cell and direction.\nvoid precompute_move_info() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                auto& data = move_info[i][j][d];\n                data.ni = i + di[d];\n                data.nj = j + dj[d];\n                bool blocked = false;\n                if (d == 0) { // U\n                    if (i == 0) blocked = true;\n                    else if (v[i - 1][j] == 1) blocked = true;\n                } else if (d == 1) { // D\n                    if (i == H - 1) blocked = true;\n                    else if (v[i][j] == 1) blocked = true;\n                } else if (d == 2) { // L\n                    if (j == 0) blocked = true;\n                    else if (h[i][j - 1] == 1) blocked = true;\n                } else { // R\n                    if (j == W - 1) blocked = true;\n                    else if (h[i][j] == 1) blocked = true;\n                }\n                data.stay = p + (1 - p) * blocked;\n                data.move = blocked ? 0.0 : (1 - p);\n                data.is_target = (!blocked && data.ni == ti && data.nj == tj);\n            }\n        }\n    }\n    dir_to_idx['U'] = 0;\n    dir_to_idx['D'] = 1;\n    dir_to_idx['L'] = 2;\n    dir_to_idx['R'] = 3;\n}\n\n// Compute expected score for a given command string.\ndouble compute_score(const string& s) {\n    double a[20][20], b[20][20];\n    double (*cur)[20] = a;\n    double (*nxt)[20] = b;\n    memset(a, 0, sizeof(a));\n    cur[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int step = 0; step < L; ++step) {\n        int d = dir_to_idx[s[step]];\n        memset(nxt, 0, sizeof(a));\n        for (int i = 0; i < H; ++i) {\n            for (int j = 0; j < W; ++j) {\n                double prob = cur[i][j];\n                if (prob == 0.0) continue;\n                const MoveData& data = move_info[i][j][d];\n                nxt[i][j] += prob * data.stay;\n                if (data.move > 0) {\n                    if (data.is_target) {\n                        score += (401 - (step + 1)) * prob * data.move;\n                    } else {\n                        nxt[data.ni][data.nj] += prob * data.move;\n                    }\n                }\n            }\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\n// BFS to find a shortest valid path (ignoring forgetting).\nstring bfs_path() {\n    queue<pair<int, int>> q;\n    vector<vector<bool>> visited(H, vector<bool>(W, false));\n    vector<vector<int>> parent_i(H, vector<int>(W, -1));\n    vector<vector<int>> parent_j(H, vector<int>(W, -1));\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            const MoveData& data = move_info[i][j][d];\n            if (data.move > 0) { // move allowed\n                int ni = data.ni, nj = data.nj;\n                if (!visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent_i[ni][nj] = i;\n                    parent_j[ni][nj] = j;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n    // Reconstruct path from target to start.\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int pi = parent_i[ci][cj];\n        int pj = parent_j[ci][cj];\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj >> ti >> tj >> p;\n    for (int i = 0; i < 20; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 19; ++j) h[i][j] = line[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 20; ++j) v[i][j] = line[j] - '0';\n    }\n\n    precompute_move_info();\n\n    string bfs_str = bfs_path();\n    double bfs_score = compute_score(bfs_str);\n    string current = bfs_str;\n    double current_score = bfs_score;\n\n    // If the BFS path is not too long, try doubling it for robustness.\n    if (bfs_str.size() * 2 <= 200) {\n        string doubled = bfs_str + bfs_str;\n        double doubled_score = compute_score(doubled);\n        if (doubled_score > current_score) {\n            current = doubled;\n            current_score = doubled_score;\n        }\n    }\n\n    string best = current;\n    double best_score = current_score;\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    auto rand_index = [&](int n) -> int {\n        return uniform_int_distribution<int>(0, n - 1)(rng);\n    };\n\n    const double time_limit = 1.95; // seconds\n    auto start_time = chrono::steady_clock::now();\n\n    double start_temp = 1.0;\n    double end_temp = 1e-4;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        double progress = elapsed / time_limit;\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        // Generate neighbour solution\n        string neighbour = current;\n        int L = neighbour.size();\n\n        // Adjust operation probabilities based on current score.\n        double insert_prob, delete_prob, replace_prob;\n        if (current_score < 1000) {\n            // Low score: favour insertions to add moves.\n            insert_prob = 0.6;\n            delete_prob = 0.1;\n            replace_prob = 0.3;\n        } else {\n            insert_prob = 0.3;\n            delete_prob = 0.3;\n            replace_prob = 0.4;\n        }\n\n        double op = uniform(rng);\n        if (op < replace_prob) { // replace one character\n            int pos = rand_index(L);\n            char old = neighbour[pos];\n            char newc;\n            do { newc = dir_chars[rand_dir(rng)]; } while (newc == old);\n            neighbour[pos] = newc;\n        } else if (op < replace_prob + insert_prob && L < 200) { // insert a character\n            int pos = rand_index(L + 1); // 0 .. L\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour.insert(neighbour.begin() + pos, newc);\n        } else { // delete or fallback to replace\n            if (L > 1) {\n                int pos = rand_index(L);\n                neighbour.erase(neighbour.begin() + pos);\n            } else {\n                // cannot delete, do replace instead\n                int pos = 0;\n                char old = neighbour[pos];\n                char newc;\n                do { newc = dir_chars[rand_dir(rng)]; } while (newc == old);\n                neighbour[pos] = newc;\n            }\n        }\n\n        double new_score = compute_score(neighbour);\n        double delta = new_score - current_score;\n        if (delta > 0 || uniform(rng) < exp(delta / T)) {\n            current = move(neighbour);\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best = current;\n            }\n        }\n    }\n\n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cstring>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Predefined connection table from problem statement\nconst int 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 grid[N][N];\nint conn[N][N][4]; // Internal connections for each tile\n\n// Compute internal connections based on rotations\nvoid compute_conn(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            int r = rotations[i][j];\n            for (int d = 0; d < 4; d++) {\n                int d0 = (d - r + 4) % 4;\n                if (to[type][d0] == -1) {\n                    conn[i][j][d] = -1;\n                } else {\n                    conn[i][j][d] = (to[type][d0] + r) % 4;\n                }\n            }\n        }\n    }\n}\n\n// Efficient cycle detection using half-edge walking\nint compute_score(int rotations[][N]) {\n    compute_conn(rotations);\n    vector<bool> visited(N*N*4, false);\n    int L1 = 0, L2 = 0; // Largest and second largest cycles\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                int id = (i*N + j)*4 + d;\n                if (conn[i][j][d] != -1 && !visited[id]) {\n                    int start_id = id;\n                    int current_id = id;\n                    int prev_id = -1;\n                    int count = 0;\n                    bool is_cycle = false;\n\n                    // Walk along the component\n                    while (true) {\n                        visited[current_id] = true;\n                        count++;\n                        \n                        // Get current tile and direction\n                        int tile_id = current_id / 4;\n                        int ci = tile_id / N;\n                        int cj = tile_id % N;\n                        int cd = current_id % 4;\n\n                        // Find neighbors: internal and external\n                        int d2 = conn[ci][cj][cd];\n                        int internal_id = (ci*N + cj)*4 + d2;\n                        int external_id = -1;\n                        int ni = ci + di[cd];\n                        int nj = cj + dj[cd];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n                            conn[ni][nj][(cd+2)%4] != -1) {\n                            external_id = (ni*N + nj)*4 + (cd+2)%4;\n                        }\n\n                        // Choose next step (avoid going back)\n                        int next_id = -1;\n                        if (internal_id != prev_id) {\n                            next_id = internal_id;\n                        } else if (external_id != -1 && external_id != prev_id) {\n                            next_id = external_id;\n                        } else {\n                            break; // Dead end\n                        }\n\n                        // Check if we completed a cycle\n                        if (next_id == start_id) {\n                            is_cycle = true;\n                            break;\n                        }\n\n                        prev_id = current_id;\n                        current_id = next_id;\n                    }\n\n                    // Update cycle lengths if we found a cycle\n                    if (is_cycle) {\n                        int length = count / 2; // Each move uses 2 half-edges\n                        if (length > L1) {\n                            L2 = L1;\n                            L1 = length;\n                        } else if (length > L2) {\n                            L2 = length;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    return L1 * L2;\n}\n\nint main() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[j] - '0';\n        }\n    }\n\n    // Initialize random number generators\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> tile_dist(0, N*N-1);\n    uniform_int_distribution<> rot_dist(0, 3);\n    uniform_real_distribution<> prob_dist(0.0, 1.0);\n\n    // Start with random solution\n    int current_rotations[N][N];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            current_rotations[i][j] = rot_dist(gen);\n        }\n    }\n    int current_score = compute_score(current_rotations);\n    \n    // Keep track of best solution\n    int best_rotations[N][N];\n    memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n    int best_score = current_score;\n\n    // Simulated annealing parameters\n    double temperature = 100.0;\n    double cooling_rate = 0.9995;\n    int sa_steps = 10000;\n\n    // Simulated annealing\n    for (int step = 0; step < sa_steps; step++) {\n        // Pick a random tile and a new rotation\n        int tile_idx = tile_dist(gen);\n        int i = tile_idx / N;\n        int j = tile_idx % N;\n        int old_rot = current_rotations[i][j];\n        int new_rot = rot_dist(gen);\n        \n        // Skip if same rotation\n        if (new_rot == old_rot) {\n            continue;\n        }\n\n        // Apply change\n        current_rotations[i][j] = new_rot;\n        int new_score = compute_score(current_rotations);\n\n        // Decide whether to accept the new solution\n        int score_diff = new_score - current_score;\n        if (score_diff > 0 || \n            prob_dist(gen) < exp(score_diff / temperature)) {\n            // Accept\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n            }\n        } else {\n            // Reject - revert change\n            current_rotations[i][j] = old_rot;\n        }\n\n        // Cool down\n        temperature *= cooling_rate;\n    }\n\n    // Final greedy local improvement\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    current_score = best_score;\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int original = current_rotations[i][j];\n                for (int r = 1; r <= 3; r++) {\n                    current_rotations[i][j] = (original + r) % 4;\n                    int new_score = compute_score(current_rotations);\n                    if (new_score > current_score) {\n                        current_score = new_score;\n                        original = current_rotations[i][j];\n                        improved = true;\n                        if (new_score > best_score) {\n                            best_score = new_score;\n                            memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n                        }\n                    } else {\n                        current_rotations[i][j] = original;\n                    }\n                }\n            }\n        }\n    }\n\n    // Output best solution found\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[4] = {0, 0, -1, 1};  // L, R, U, D\nconst int dy[4] = {-1, 1, 0, 0};\nconst char dir_char[4] = {'L', 'R', 'U', 'D'};\nconst int dir_bit[4] = {1, 4, 2, 8};  // L=1, R=4, U=2, D=8\nconst int opposite[4] = {1, 0, 3, 2};  // opposite directions\n\nint N, T;\nvector<vector<int>> board;\nint empty_r, empty_r;\n\n// Check if moving in direction d is valid\nbool can_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    return nr >= 0 && nr < N && nc >= 0 && nc < N;\n}\n\n// Execute move in direction d\nvoid make_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    empty_r = nr;\n    empty_c = nc;\n}\n\n// Calculate size of largest tree in current configuration\nint largest_tree_size() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_size = 0;\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]) {\n                // BFS to find component\n                vector<pair<int,int>> component;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [r, c] = q.front();\n                    q.pop();\n                    component.push_back({r, c});\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dy[d];\n                        int nc = c + dx[d];\n                        if (nr >= 0 && nr < N && nc >= 0 && nc < N && \n                            board[nr][nc] != 0 && !visited[nr][nc]) {\n                            // Check if connection exists\n                            int curr_bit = dir_bit[d];\n                            int next_bit = dir_bit[opposite[d]];\n                            if ((board[r][c] & curr_bit) && (board[nr][nc] & next_bit)) {\n                                visited[nr][nc] = true;\n                                q.push({nr, nc});\n                            }\n                        }\n                    }\n                }\n                \n                // Count edges in component\n                int V = component.size();\n                int E = 0;\n                vector<vector<bool>> in_comp(N, vector<bool>(N, false));\n                for (auto [r, c] : component) {\n                    in_comp[r][c] = true;\n                }\n                \n                for (auto [r, c] : component) {\n                    // Check right neighbor\n                    if (c + 1 < N && in_comp[r][c+1]) {\n                        if ((board[r][c] & 4) && (board[r][c+1] & 1)) {\n                            E++;\n                        }\n                    }\n                    // Check down neighbor\n                    if (r + 1 < N && in_comp[r+1][c]) {\n                        if ((board[r][c] & 8) && (board[r+1][c] & 2)) {\n                            E++;\n                        }\n                    }\n                }\n                \n                if (E == V - 1) {  // Tree condition\n                    max_size = max(max_size, V);\n                }\n            }\n        }\n    }\n    return max_size;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.resize(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] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_r = i;\n                empty_c = j;\n            }\n        }\n    }\n    \n    string moves;\n    int current_max = largest_tree_size();\n    \n    for (int step = 0; step < T; step++) {\n        if (current_max == N * N - 1) {\n            break;  // Already achieved full tree\n        }\n        \n        int best_d = -1;\n        int best_size = current_max;\n        \n        // Try all possible moves\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(d)) continue;\n            \n            // Simulate move\n            int nr = empty_r + dy[d];\n            int nc = empty_c + dx[d];\n            swap(board[empty_r][empty_c], board[nr][nc]);\n            int saved_er = empty_r, saved_ec = empty_c;\n            empty_r = nr;\n            empty_c = nc;\n            \n            int new_size = largest_tree_size();\n            \n            // Restore board\n            empty_r = saved_er;\n            empty_c = saved_ec;\n            swap(board[empty_r][empty_c], board[nr][nc]);\n            \n            if (new_size > best_size) {\n                best_size = new_size;\n                best_d = d;\n            }\n        }\n        \n        // If no improvement, choose any valid move to keep exploring\n        if (best_d == -1) {\n            for (int d = 0; d < 4; d++) {\n                if (can_move(d)) {\n                    best_d = d;\n                    break;\n                }\n            }\n            if (best_d == -1) break;  // No moves possible\n        }\n        \n        // Execute best move\n        make_move(best_d);\n        moves += dir_char[best_d];\n        current_max = best_size;\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\n\nstruct Pt { ll x, y; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    int a[11];\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    vector<Pt> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n\n    // Direction vectors for testing separation\n    const int ND = 32;\n    vector<pair<double,double>> dirs(ND);\n    for (int i = 0; i < ND; i++) {\n        double ang = 2.0 * M_PI * i / ND;\n        dirs[i] = {cos(ang), sin(ang)};\n    }\n\n    auto compute_score = [&](const vector<array<ll,4>>& lines) -> int {\n        vector<int> pc(N, 0);\n        for (int i = 0; i < N; i++)\n            for (auto& ln : lines) {\n                ll d = (ln[2]-ln[0])*(pts[i].y-ln[1]) - (ln[3]-ln[1])*(pts[i].x-ln[0]);\n                if (d < 0) pc[i] |= 1;\n                else if (d > 0) pc[i] |= 2;\n            }\n        unordered_map<int,int> cnt;\n        for (int p : pc) if (p) cnt[p]++;\n        int score = 0, tot = 0;\n        for (int i = 1; i <= 10; i++) {\n            score += min(a[i], cnt[i]);\n            tot += a[i];\n        }\n        return tot > 0 ? (int)round(1e6 * (double)score / tot) : 0;\n    };\n\n    vector<array<ll,4>> best;\n    int best_score = -1;\n\n    // Sort by angle\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int i, int j) {\n        return atan2(pts[i].y, pts[i].x) < atan2(pts[j].y, pts[j].x);\n    });\n\n    // Try different rotations of boundary positions\n    for (int rot = 0; rot < 10; rot++) {\n        // Greedy grouping by angle order\n        vector<int> gr(N, -1);\n        int idx = 0;\n        for (int d = 1; d <= 10; d++)\n            for (int j = 0; j < a[d] && idx < N; j++, idx++)\n                gr[ord[idx]] = d;\n\n        int G = 0;\n        for (int i = 1; i <= 10; i++) G += a[i];\n\n        // Compute boundary angles between groups\n        vector<double> angs(N);\n        for (int i = 0; i < N; i++) angs[i] = atan2(pts[ord[i]].y, pts[ord[i]].x);\n\n        vector<array<ll,4>> sol;\n        int cg = 0;\n        for (int g = 0; g < G; g++) {\n            int g0 = cg, g1 = cg + 1;\n            int i0 = (g0 + rot) % N, i1 = (g1 + rot) % N;\n            double a0 = angs[i0], a1 = angs[i1];\n            double bd;\n            if (g < G - 1) bd = (a0 + a1) / 2;\n            else {\n                double d = a1 - a0;\n                while (d < 0) d += 2*M_PI;\n                while (d > 2*M_PI) d -= 2*M_PI;\n                bd = a0 + d / 2;\n                if (bd > M_PI) bd -= 2*M_PI;\n            }\n            cg = g1;\n            double na = -sin(bd), nb = cos(bd);\n            sol.push_back({(ll)round(1e4*na), (ll)round(1e4*nb),\n                           (ll)round(-1e4*na), (ll)round(-1e4*nb)});\n        }\n\n        // Refine multi-point groups\n        unordered_map<int, vector<int>> gm;\n        for (int i = 0; i < N; i++) if (gr[i] > 0) gm[gr[i]].push_back(i);\n\n        for (auto& [gval, gi] : gm) {\n            if ((int)gi.size() <= 1) continue;\n            bool done = false;\n            for (int di = 0; di < ND && !done; di++) {\n                auto [dx, dy] = dirs[di];\n                vector<pair<double,int>> pp(N);\n                for (int i = 0; i < N; i++)\n                    pp[i] = {pts[i].x*dx + pts[i].y*dy, i};\n                sort(pp.begin(), pp.end());\n\n                vector<int> gpi, ngi;\n                for (auto& [v, i] : pp)\n                    (gr[i] == gval ? gpi : ngi).push_back(i);\n                if (gpi.empty() || ngi.empty()) continue;\n\n                double mxg = -1e30, mng = 1e30;\n                for (int i : gpi) mxg = max(mxg, pp[0].first + i * 0.0); // wrong\n                // Recompute properly\n                mxg = -1e30; mng = 1e30;\n                unordered_set<int> gs(gi.begin(), gi.end());\n                for (auto& [v, i] : pp) {\n                    if (gs.count(i)) mxg = max(mxg, v);\n                    else mng = min(mng, v);\n                }\n                if (mxg >= mng || mng - mxg < 0.5) continue;\n\n                double thr = (mxg + mng) / 2;\n                double na = dx, nb = dy;\n                ll c = llround(na * gpi[0] + nb * gpi[0]); // wrong, need actual coords\n                // Fix: use a group point\n                c = llround(pts[gpi[0]].x * na + pts[gpi[0]].y * nb);\n\n                double pnx = -nb, pny = na;\n                ll dxx = llround(pnx * 1e4), dyy = llround(pny * 1e4);\n                ll g = __gcd(abs(dxx), abs(dyy));\n                if (g > 1) { dxx /= g; dyy /= g; }\n                if (dxx == 0 && dyy == 0) { dxx = llround(-nb); dyy = llround(na); }\n                if (dxx == 0 && dyy == 0) continue;\n                dxx *= 10000; dyy *= 10000;\n                ll bx = llround(thr * na), by = llround(thr * nb);\n\n                sol.push_back({bx+dxx, by+dyy, bx-dxx, by-dyy});\n                done = true;\n            }\n        }\n\n        int sc = compute_score(sol);\n        if (sc > best_score) { best_score = sc; best = sol; }\n    }\n\n    cout << best.size() << \"\\n\";\n    for (auto& l : best)\n        cout << l[0] << \" \" << l[1] << \" \" << l[2] << \" \" << l[3] << \"\\n\";\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Cand {\n    double score;\n    int nx, ny, p1x, p1y, p2x, p2y, p3x, p3y;\n    bool operator<(const Cand& o) const { return score > o.score; }\n};\n\nint main(){\n    int N, M;\n    scanf(\"%d%d\",&N,&M);\n    const int MX=62;\n    bool g[MX][MX]={};\n    vector<pair<int,int>> dots;\n    for(int i=0;i<M;i++){\n        int x,y; scanf(\"%d%d\",&x,&y);\n        g[x][y]=true; dots.push_back({x,y});\n    }\n    double c=(N-1)/2.0;\n    double w[MX][MX];\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)\n        w[x][y]=(x-c)*(x-c)+(y-c)*(y-c)+1;\n    bitset<60> hz[MX][MX],vt[MX][MX],ne[MX][MX],nw[MX][MX];\n    auto ckH=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y>=N)return false;\n        return !hz[x][y].test(0);};\n    auto ckV=[&](int x,int y)->bool{\n        if(x<0||x<N||y<0||y>=N-1)return false;\n        return !vt[x][y].test(0);};\n    auto ckNE=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y>=N)return false;\n        return !ne[x][y].test(0);};\n    auto ckNW=[&](int x,int y)->bool{\n        if(x<1||x<N||y<0||y>=N)return false;\n        return !nw[x][y].test(0);};\n    auto sH=[&](int x,int y){hz[x][y].set(0);};\n    auto sV=[&](int x,int y){vt[x][y].set(0);};\n    auto sNE=[&](int x,int y){ne[x][y].set(0);};\n    auto sNW=[&](int x,int y){nw[x][y].set(0);};\n    vector<array<int,8>> ops;\n    auto getTime=[&]()->double{\n        auto now=chrono::steady_clock::now();\n        return chrono::duration<double>(now.time_since_epoch()).count();};\n    double startTime=getTime();\n    while(getTime()-startTime<4.5){\n        vector<Cand> cands;\n        for(auto&[px,py]:dots){\n            for(int d=0;d<4;d++){\n                static const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};\n                int qx=px+dx[d]*2,qy=py+dy[d]*2;\n                if(qx<0||qx>=N||qy<0||qy>=N||g[qx][qy])continue;\n                int c1x=px+dx[d],c1y=py+dy[d],c2x=qx-dx[d],c2y=qy-dy[d];\n                if(c2x<0||c2x>=N||c2y<0||c2y>=N||!g[c2x][c2y])continue;\n                double sc=w[qx][qy];\n                if(d==0||d==2){\n                    if(!ckV(qx,min(qy,c1y))||!ckV(c2x,min(c2y,py))||\n                       !ckH(min(qx,c2x),qy)||!ckH(min(px,c1x),c1y))continue;\n                }else{\n                    if(!ckH(min(qx,c1x),qy)||!ckH(min(c2x,px),c2y)||\n                       !ckV(qx,min(qy,c2y))||!ckV(c1x,min(c1y,py)))continue;\n                }\n                cands.push_back({sc,qx,qy,px,py,c1x,c1y,c2x,c2y});\n            }\n            for(int d=0;d<2;d++){\n                int nx=px+1,ny=py+(d==0?1:-1);\n                if(nx<0||nx>=N||ny<0||ny>=N||g[nx][ny])continue;\n                int x1=px,y1=py,x2=nx,y2=ny;\n                if((x1+y1)%2!=(x2+y2)%2)continue;\n                int a1x=(x1+y1+x2-y2)/2,a1y=(x1+y1-x2+y2)/2;\n                int b1x=(x2+y2+x1-y1)/2,b1y=(x2+y2-x1+y1)/2;\n                int ok1=(a1x>=0&&a1x<N&&a1y>=0&&a1y<N&&b1x>=0&&b1x<N&&b1y>=0&&b1y<N);\n                if(ok1){\n                    bool f1=g[a1x][a1y],f2=g[b1x][b1y];\n                    if(f1&&!f2){\n                        double sc=w[b1x][b1y];\n                        if(ckNE(min(b1x,a1x),min(b1y,a1y))&&\n                           ckNW(min(a1x,x1),min(a1y,y1))&&\n                           ckNE(min(x1,b1x),min(y1,b1y))&&\n                           ckNW(min(b1x,x2),min(b1y,y2)))\n                            cands.push_back({sc,b1x,b1y,x1,y1,a1x,a1y,x2,y2});\n                    }else if(!f1&&f2){\n                        double sc=w[a1x][a1y];\n                        if(ckNE(min(a1x,b1x),min(a1y,b1y))&&\n                           ckNW(min(b1x,x1),min(b1y,y1))&&\n                           ckNE(min(x1,a1x),min(y1,a1y))&&\n                           ckNW(min(a1x,x2),min(a1y,y2)))\n                            cands.push_back({sc,a1x,a1y,x1,y1,b1x,b1y,x2,y2});\n                    }\n                }\n                int c1x=(x1+y1+x2+y2)/2,c1y=(x1-y1+x2+y2)/2;\n                int c2x=(x1+y1-x2-y2)/2,c2y=(x1-y1-x2-y2)/2;\n                int ok2=(c1x>=0&&c1x<N&&c1y>=0&&c1y<N&&c2x>=0&&c2x<N&&c2y>=0&&c2y<N);\n                if(ok2){\n                    bool f1=g[c1x][c1y],f2=g[c2x][c2y];\n                    if(f1&&!f2){\n                        double sc=w[c2x][c2y];\n                        if(ckNE(min(c2x,x2),min(c2y,y2))&&\n                           ckNW(min(x2,c1x),min(y2,c1y))&&\n                           ckNE(min(c1x,x1),min(c1y,y1))&&\n                           ckNW(min(x1,c2x),min(y1,c2y)))\n                            cands.push_back({sc,c2x,c2y,x1,y1,x2,y2,c1x,c1y});\n                    }else if(!f1&&f2){\n                        double sc=w[c1x][c1y];\n                        if(ckNE(min(c1x,x2),min(c1y,y2))&&\n                           ckNW(min(x2,c2x),min(y2,c2y))&&\n                           ckNE(min(c2x,x1),min(c2y,y1))&&\n                           ckNW(min(x1,c1x),min(y1,c1y)))\n                            cands.push_back({sc,c1x,c1y,x1,y1,x2,y2,c2x,c2y});\n                    }\n                }\n            }\n        }\n        sort(cands.begin(),cands.end());\n        bool found=false;\n        for(auto& cd:cands){\n            int nx=cd.nx,ny=cd.ny,p1x=cd.p1x,p1y=cd.p1y;\n            int p2x=cd.p2x,p2y=cd.p2y,p3x=cd.p3x,p3y=cd.p3y;\n            if(!ckH(min(nx,p1x),min(ny,p1y)))continue;\n            if(!ckV(min(p1x,p2x),min(p1y,p2y)))continue;\n            if(!ckH(min(p2x,p3x),min(p2y,p3y)))continue;\n            if(!ckV(min(p3x,nx),min(p3y,ny)))continue;\n            if(!ckNE(min(nx,p2x),min(ny,p2y)))continue;\n            if(!ckNW(min(p2x,p1x),min(p2y,p1y)))continue;\n            if(!ckNE(min(p1x,p3x),min(p1y,p3y)))continue;\n            if(!ckNW(min(p3x,nx),min(p3y,ny)))continue;\n            sH(min(nx,p1x),min(ny,p1y));sV(min(p1x,p2x),min(p1y,p2y));\n            sH(min(p2x,p3x),min(p2y,p3y));sV(min(p3x,nx),min(p3y,ny));\n            sNE(min(nx,p2x),min(ny,p2y));sNW(min(p2x,p1x),min(p2y,p1y));\n            sNE(min(p1x,p3x),min(p1y,p3y));sNW(min(p3x,nx),min(p3y,ny));\n            g[nx][ny]=true;\n            dots.push_back({nx,ny});\n            array<int,8> op={nx,ny,p1x,p1y,p2x,p2y,p3x,p3y};\n            ops.push_back(op);\n            found=true;break;\n        }\n        if(!found)break;\n    }\n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&o:ops)\n        printf(\"%d %d %d %d %d %d %d %d\\n\",o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7]);\n    double ws=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(g[x][y])ws+=w[x][y];\n    double S=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)S+=w[x][y];\n    printf(\"Score: %lld\\n\",(long long)round(1e6*N*N/M*ws/S));\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[100];\n\nvoid tilt(char dir, int g[N][N]) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; ++j) {\n            int write = 0;\n            for (int i = 0; i < N; ++i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int i = write; i < N; ++i) g[i][j] = 0;\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; ++j) {\n            int write = N - 1;\n            for (int i = N - 1; i >= 0; --i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    --write;\n                }\n            }\n            for (int i = write; i >= 0; --i) g[i][j] = 0;\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; ++i) {\n            int write = 0;\n            for (int j = 0; j < N; ++j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int j = write; j < N; ++j) g[i][j] = 0;\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < N; ++i) {\n            int write = N - 1;\n            for (int j = N - 1; j >= 0; --j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    --write;\n                }\n            }\n            for (int j = write; j >= 0; --j) g[i][j] = 0;\n        }\n    }\n}\n\nint compute_score(int g[N][N]) {\n    bool visited[N][N] = {};\n    int total = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (g[i][j] != 0 && !visited[i][j]) {\n                int flavor = g[i][j];\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int size = 0;\n                while (!q.empty()) {\n                    auto [r, c] = q.front(); q.pop();\n                    ++size;\n                    if (r > 0 && g[r-1][c] == flavor && !visited[r-1][c]) {\n                        visited[r-1][c] = true;\n                        q.push({r-1, c});\n                    }\n                    if (r < N-1 && g[r+1][c] == flavor && !visited[r+1][c]) {\n                        visited[r+1][c] = true;\n                        q.push({r+1, c});\n                    }\n                    if (c > 0 && g[r][c-1] == flavor && !visited[r][c-1]) {\n                        visited[r][c-1] = true;\n                        q.push({r, c-1});\n                    }\n                    if (c < N-1 && g[r][c+1] == flavor && !visited[r][c+1]) {\n                        visited[r][c+1] = true;\n                        q.push({r, c+1});\n                    }\n                }\n                total += size * size;\n            }\n        }\n    }\n    return total;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n\n    memset(grid, 0, sizeof(grid));\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell in front-to-back, left-to-right order.\n        vector<pair<int, int>> empties;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) {\n                    empties.push_back({i, j});\n                }\n            }\n        }\n        auto [r, c] = empties[p - 1];\n        grid[r][c] = flavors[t];\n\n        // Try each direction and pick the one with maximum score.\n        int best_score = -1;\n        char best_dir = 'F';\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            int temp[N][N];\n            memcpy(temp, grid, sizeof(temp));\n            tilt(dir, temp);\n            int score = compute_score(temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        cout.flush();\n\n        // Apply the chosen tilt to the actual grid.\n        tilt(best_dir, grid);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int M;\n    double eps;\n    cin >> M >> eps;\n    const int N = 100;\n    const int T = N * (N - 1) / 2;\n\n    // Precompute expectations and variances for each graph G_s\n    vector<double> mu_E(M), mu_T(M), var_T(M);\n    double var_E = T * eps * (1 - eps);\n\n    for (int s = 0; s < M; ++s) {\n        int k = s + 1;  // clique size\n        // Expected edge count after noise\n        mu_E[s] = (k * (k - 1) / 2) * (1 - 2 * eps) + T * eps;\n\n        // Build probability matrix p_{ij}\n        vector<vector<double>> p(N, vector<double>(N, eps));\n        for (int i = 0; i < k; ++i) {\n            for (int j = i + 1; j < k; ++j) {\n                p[i][j] = p[j][i] = 1 - eps;\n            }\n        }\n\n        double mu = 0.0, var = 0.0;\n        // Sum over all triples for expected triangles and first part of variance\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                for (int l = j + 1; l < N; ++l) {\n                    double q = p[i][j] * p[j][l] * p[l][i];\n                    mu += q;\n                    var += q - q * q;\n                }\n            }\n        }\n        mu_T[s] = mu;\n\n        // Sum over edges for the remaining variance contribution\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                double S = 0.0, T2 = 0.0;\n                for (int l = 0; l < N; ++l) {\n                    if (l == i || l == j) continue;\n                    double term = p[i][l] * p[j][l];\n                    S += term;\n                    T2 += term * term;\n                }\n                var += p[i][j] * (1 - p[i][j]) * (S * S - T2);\n            }\n        }\n        var_T[s] = var;\n    }\n\n    // Output the graphs\n    cout << N << endl;\n    for (int s = 0; s < M; ++s) {\n        int k = s + 1;\n        string graph(T, '0');\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (i < k && j < k) {\n                    graph[idx] = '1';\n                }\n                ++idx;\n            }\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n\n    // Process 100 queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n\n        // Parse H into an adjacency matrix\n        vector<vector<bool>> adj(N, vector<bool>(N, false));\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[idx] == '1') {\n                    adj[i][j] = adj[j][i] = true;\n                }\n                ++idx;\n            }\n        }\n\n        // Count edges in H\n        int E_obs = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (adj[i][j]) ++E_obs;\n            }\n        }\n\n        // Count triangles in H\n        int T_obs = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < N; ++k) {\n                    if (adj[j][k] && adj[k][i]) {\n                        ++T_obs;\n                    }\n                }\n            }\n        }\n\n        // Classify by minimum normalized distance\n        double best_score = 1e100;\n        int best_s = 0;\n        for (int s = 0; s < M; ++s) {\n            double score = 0.0;\n            // Edge count feature\n            if (var_E > 1e-12) {\n                score += pow(E_obs - mu_E[s], 2) / var_E;\n            } else {\n                if (fabs(E_obs - mu_E[s]) > 1e-6) score += 1e12;\n            }\n            // Triangle count feature\n            if (var_T[s] > 1e-12) {\n                score += pow(T_obs - mu_T[s], 2) / var_T[s];\n            } else {\n                if (fabs(T_obs - mu_T[s]) > 1e-6) score += 1e12;\n            }\n            if (score < best_score) {\n                best_score = score;\n                best_s = s;\n            }\n        }\n\n        cout << best_s << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <cassert>\n#include <tuple>\n#include <chrono>\n\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\n\nstruct Edge {\n    int u, v, w;\n};\n\nstruct EdgeAdj {\n    int to, idx;\n    ll w;\n};\n\nvector<ll> dijkstra(int s, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\nvector<ll> dijkstra_ignore_set(int s, const vector<bool>& ignore_edge, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (ignore_edge[e.idx]) continue;\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\ndouble compute_day_frustration(int day, const vector<int>& day_assignment, \n                              const vector<Edge>& edges, const vector<vector<ll>>& orig_dist,\n                              const vector<vector<EdgeAdj>>& adj, int N, \n                              const vector<int>& sample_sources) {\n    // Build ignore set for this day\n    vector<bool> ignore_edge(edges.size(), false);\n    for (int i = 0; i < edges.size(); ++i) {\n        if (day_assignment[i] == day) {\n            ignore_edge[i] = true;\n        }\n    }\n    \n    double total_increase = 0.0;\n    int pair_count = 0;\n    \n    for (int s : sample_sources) {\n        vector<ll> new_dist = dijkstra_ignore_set(s, ignore_edge, adj);\n        for (int t = 0; t < N; ++t) {\n            if (s == t) continue;\n            ll orig_d = orig_dist[s][t];\n            ll new_d = new_dist[t];\n            if (new_d >= INF/2) new_d = 1000000000; // As per problem statement\n            total_increase += (new_d - orig_d);\n            pair_count++;\n        }\n    }\n    \n    // Scale to full pairs\n    double avg_increase = total_increase / pair_count;\n    return avg_increase * (N * (N - 1)) / (sample_sources.size() * (N - 1));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    \n    vector<Edge> edges(M);\n    vector<vector<EdgeAdj>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w};\n        adj[u].push_back({v, i, w});\n        adj[v].push_back({u, i, w});\n    }\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Precompute original distances\n    vector<vector<ll>> orig_dist(N);\n    for (int s = 0; s < N; ++s) {\n        orig_dist[s] = dijkstra(s, adj);\n    }\n    \n    // Sample vertices for frustration estimation\n    int sample_size = min(50, N);\n    vector<int> sample_sources(sample_size);\n    iota(sample_sources.begin(), sample_sources.end(), 0);\n    if (N > sample_size) {\n        // Shuffle and take first sample_size\n        random_device rd;\n        mt19937 gen(rd());\n        shuffle(sample_sources.begin(), sample_sources.end(), gen);\n        sample_sources.resize(sample_size);\n    }\n    \n    // Initial assignment: distribute evenly with spatial dispersion\n    vector<int> assignment(M);\n    double cx = accumulate(x.begin(), x.end(), 0.0) / N;\n    double cy = accumulate(y.begin(), y.end(), 0.0) / N;\n    vector<pair<double, int>> angle_edges;\n    for (int i = 0; i < M; ++i) {\n        double mx = (x[edges[i].u] + x[edges[i].v]) * 0.5;\n        double my = (y[edges[i].u] + y[edges[i].v]) * 0.5;\n        double angle = atan2(my - cy, mx - cx);\n        angle_edges.emplace_back(angle, i);\n    }\n    sort(angle_edges.begin(), angle_edges.end());\n    for (int i = 0; i < M; ++i) {\n        assignment[angle_edges[i].second] = (i % D) + 1;\n    }\n    \n    // Compute initial frustration\n    vector<double> day_frustration(D + 1, 0.0);\n    double total_frustration = 0.0;\n    for (int day = 1; day <= D; ++day) {\n        day_frustration[day] = compute_day_frustration(day, assignment, edges, orig_dist, adj, N, sample_sources);\n        total_frustration += day_frustration[day];\n    }\n    \n    // Simulated annealing\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> dis(0.0, 1.0);\n    uniform_int_distribution<int> rand_edge(0, M - 1);\n    uniform_int_distribution<int> rand_day(1, D);\n    \n    double temp = 1000.0;\n    double cooling = 0.9997;\n    const int ITER = 200000;\n    \n    for (int iter = 0; iter < ITER; ++iter) {\n        // Check time limit\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 5.5) break; // Leave margin\n        \n        int e = rand_edge(gen);\n        int old_day = assignment[e];\n        int new_day = rand_day(gen);\n        while (new_day == old_day) new_day = rand_day(gen);\n        \n        // Check if new_day has capacity (count edges per day)\n        int cnt_new = count(assignment.begin(), assignment.end(), new_day);\n        if (cnt_new >= K) continue;\n        \n        // Try move\n        assignment[e] = new_day;\n        \n        // Recompute frustration for affected days only\n        double new_frustration_old_day = compute_day_frustration(old_day, assignment, edges, orig_dist, adj, N, sample_sources);\n        double new_frustration_new_day = compute_day_frustration(new_day, assignment, edges, orig_dist, adj, N, sample_sources);\n        \n        double new_total = total_frustration - day_frustration[old_day] - day_frustration[new_day] \n                          + new_frustration_old_day + new_frustration_new_day;\n        \n        double delta = new_total - total_frustration;\n        \n        if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n            // Accept\n            total_frustration = new_total;\n            day_frustration[old_day] = new_frustration_old_day;\n            day_frustration[new_day] = new_frustration_new_day;\n        } else {\n            // Reject - revert\n            assignment[e] = old_day;\n        }\n        \n        temp *= cooling;\n    }\n    \n    // Output\n    for (int i = 0; i < M; ++i) {\n        if (i > 0) cout << ' ';\n        cout << assignment[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f[2], r[2];\n    for (int i = 0; i < 2; ++i) {\n        f[i].resize(D);\n        for (int j = 0; j < D; ++j) cin >> f[i][j];\n        r[i].resize(D);\n        for (int j = 0; j < D; ++j) cin >> r[i][j];\n    }\n\n    // common cells (intersection of allowed sets)\n    vector<vector<vector<bool>>> common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (int x = 0; x < D; ++x) {\n        for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ++z) {\n                if (f[0][z][x] == '1' && r[0][z][y] == '1' &&\n                    f[1][z][x] == '1' && r[1][z][y] == '1') {\n                    common[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // which columns are already covered by common cells\n    bool covered_f[2][D][D] = {false};\n    bool covered_r[2][D][D] = {false};\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 (common[x][y][z]) {\n                    for (int i = 0; i < 2; ++i) {\n                        covered_f[i][z][x] = true;\n                        covered_r[i][z][y] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // connected components of common cells (shared blocks)\n    const int dx[6] = {1, -1, 0, 0, 0, 0};\n    const int dy[6] = {0, 0, 1, -1, 0, 0};\n    const int dz[6] = {0, 0, 0, 0, 1, -1};\n    vector<vector<vector<int>>> compId(D, vector<vector<int>>(D, vector<int>(D, -1)));\n    vector<vector<array<int, 3>>> components;\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 (common[x][y][z] && compId[x][y][z] == -1) {\n                    queue<array<int, 3>> q;\n                    q.push({x, y, z});\n                    compId[x][y][z] = components.size();\n                    vector<array<int, 3>> comp;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.push_back({cx, cy, cz});\n                        for (int d = 0; d < 6; ++d) {\n                            int nx = cx + dx[d], ny = cy + dy[d], nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                                common[nx][ny][nz] && compId[nx][ny][nz] == -1) {\n                                compId[nx][ny][nz] = components.size();\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n\n    // exclusive cells for each object (minimal covering of uncovered columns)\n    vector<array<int, 3>> excl[2];\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            vector<int> Xu, Yu;\n            for (int x = 0; x < D; ++x)\n                if (f[i][z][x] == '1' && !covered_f[i][z][x]) Xu.push_back(x);\n            for (int y = 0; y < D; ++y)\n                if (r[i][z][y] == '1' && !covered_r[i][z][y]) Yu.push_back(y);\n\n            int a = Xu.size(), b = Yu.size();\n            int m = min(a, b);\n\n            // matched pairs\n            for (int k = 0; k < m; ++k)\n                excl[i].push_back({Xu[k], Yu[k], z});\n\n            // extra front columns\n            if (a > b) {\n                int y0;\n                if (b > 0) y0 = Yu[0];\n                else {\n                    for (int y = 0; y < D; ++y)\n                        if (r[i][z][y] == '1') { y0 = y; break; }\n                }\n                for (int k = m; k < a; ++k)\n                    excl[i].push_back({Xu[k], y0, z});\n            }\n            // extra right columns\n            else if (b > a) {\n                int x0;\n                if (a > 0) x0 = Xu[0];\n                else {\n                    for (int x = 0; x < D; ++x)\n                        if (f[i][z][x] == '1') { x0 = x; break; }\n                }\n                for (int k = m; k < b; ++k)\n                    excl[i].push_back({x0, Yu[k], z});\n            }\n        }\n    }\n\n    // assign block IDs\n    int n = components.size() + excl[0].size() + excl[1].size();\n    vector<int> compIds(components.size());\n    int curId = 1;\n    for (size_t i = 0; i < components.size(); ++i) compIds[i] = curId++;\n    vector<int> exclIds[2];\n    for (int i = 0; i < 2; ++i) {\n        exclIds[i].resize(excl[i].size());\n        for (size_t j = 0; j < excl[i].size(); ++j) exclIds[i][j] = curId++;\n    }\n\n    // build output arrays\n    vector<vector<vector<int>>> b[2];\n    for (int i = 0; i < 2; ++i)\n        b[i].assign(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    // place shared blocks (same in both objects)\n    for (size_t ci = 0; ci < components.size(); ++ci) {\n        int bid = compIds[ci];\n        for (auto [x, y, z] : components[ci]) {\n            b[0][x][y][z] = bid;\n            b[1][x][y][z] = bid;\n        }\n    }\n\n    // place exclusive blocks\n    for (int i = 0; i < 2; ++i) {\n        for (size_t j = 0; j < excl[i].size(); ++j) {\n            auto [x, y, z] = excl[i][j];\n            b[i][x][y][z] = exclIds[i][j];\n        }\n    }\n\n    // output\n    cout << n << '\\n';\n    for (int obj = 0; obj < 2; ++obj) {\n        bool first = true;\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 (first) first = false;\n                    else cout << ' ';\n                    cout << b[obj][x][y][z];\n                }\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\nconst ll RADIUS_SQ = 25000000LL; // 5000^2\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // graph and edge index mapping\n    vector<vector<ll>> distV(N, vector<ll>(N, INF));\n    vector<vector<int>> nextV(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        distV[i][i] = 0;\n        nextV[i][i] = i;\n    }\n    vector<tuple<int, int, int>> edges(M); // u, v, w\n    vector<vector<int>> edgeIdx(N, vector<int>(N, -1));\n    for (int j = 0; j < M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u, --v;\n        edges[j] = {u, v, w};\n        distV[u][v] = distV[v][u] = w;\n        nextV[u][v] = v;\n        nextV[v][u] = u;\n        edgeIdx[u][v] = edgeIdx[v][u] = j;\n    }\n\n    // residents\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute distances between vertices and residents\n    vector<vector<ll>> sqDist(N, vector<ll>(K));\n    vector<vector<double>> eucDist(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = x[i] - a[k];\n            ll dy = y[i] - b[k];\n            sqDist[i][k] = dx*dx + dy*dy;\n            eucDist[i][k] = sqrt((double)sqDist[i][k]);\n        }\n    }\n\n    // Floyd-Warshall for shortest paths between vertices\n    for (int kk = 0; kk < N; ++kk) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][kk] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[kk][j] == INF) continue;\n                if (distV[i][j] > distV[i][kk] + distV[kk][j]) {\n                    distV[i][j] = distV[i][kk] + distV[kk][j];\n                    nextV[i][j] = nextV[i][kk];\n                }\n            }\n        }\n    }\n\n    // Initialize with all vertices connected to vertex 0\n    vector<int> S(N);\n    iota(S.begin(), S.end(), 0);\n    \n    // Greedy assignment to minimize sum of squares\n    vector<double> maxDist(N, 0.0);\n    vector<int> assign(K);\n    \n    // Initial assignment: each resident to nearest vertex\n    for (int k = 0; k < K; ++k) {\n        double minDist = 1e18;\n        int bestV = -1;\n        for (int v : S) {\n            double d = eucDist[v][k];\n            if (d < minDist) {\n                minDist = d;\n                bestV = v;\n            }\n        }\n        assign[k] = bestV;\n        if (minDist > maxDist[bestV]) {\n            maxDist[bestV] = minDist;\n        }\n    }\n\n    // Local search: try to remove vertices\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < (int)S.size(); ++i) {\n            int v = S[i];\n            if (v == 0) continue; // Keep vertex 0\n\n            // Try removing vertex v\n            vector<int> newS = S;\n            newS.erase(newS.begin() + i);\n            \n            // Check if all residents can be reassigned within 5000\n            bool canRemove = true;\n            vector<int> newAssign = assign;\n            vector<double> newMaxDist(N, 0.0);\n            \n            for (int k = 0; k < K; ++k) {\n                if (assign[k] == v) {\n                    // Find nearest vertex in newS within 5000\n                    double bestDist = 1e18;\n                    int bestVertex = -1;\n                    for (int u : newS) {\n                        double d = eucDist[u][k];\n                        if (d <= 5000.0 && d < bestDist) {\n                            bestDist = d;\n                            bestVertex = u;\n                        }\n                    }\n                    if (bestVertex == -1) {\n                        canRemove = false;\n                        break;\n                    }\n                    newAssign[k] = bestVertex;\n                    if (bestDist > newMaxDist[bestVertex]) {\n                        newMaxDist[bestVertex] = bestDist;\n                    }\n                } else {\n                    int u = assign[k];\n                    if (eucDist[u][k] > newMaxDist[u]) {\n                        newMaxDist[u] = eucDist[u][k];\n                    }\n                }\n            }\n            \n            if (!canRemove) continue;\n            \n            // Compute new costs\n            ll newSumSq = 0;\n            for (int u : newS) {\n                if (newMaxDist[u] > 0) {\n                    int p = (int)ceil(newMaxDist[u] - 1e-9);\n                    newSumSq += (ll)p * p;\n                }\n            }\n            \n            // Compute MST cost for newS\n            vector<tuple<ll, int, int>> mstEdges;\n            for (size_t a = 0; a < newS.size(); ++a) {\n                for (size_t b = a+1; b < newS.size(); ++b) {\n                    int u = newS[a], v2 = newS[b];\n                    mstEdges.emplace_back(distV[u][v2], u, v2);\n                }\n            }\n            sort(mstEdges.begin(), mstEdges.end());\n            vector<int> parent(N);\n            iota(parent.begin(), parent.end(), 0);\n            function<int(int)> find = [&](int x) {\n                return parent[x] == x ? x : parent[x] = find(parent[x]);\n            };\n            auto unite = [&](int x, int y) {\n                parent[find(x)] = find(y);\n            };\n            ll newMSTCost = 0;\n            for (auto [w, u, v2] : mstEdges) {\n                if (find(u) != find(v2)) {\n                    unite(u, v2);\n                    newMSTCost += w;\n                }\n            }\n            \n            // Current costs\n            ll currentSumSq = 0;\n            for (int u : S) {\n                if (maxDist[u] > 0) {\n                    int p = (int)ceil(maxDist[u] - 1e-9);\n                    currentSumSq += (ll)p * p;\n                }\n            }\n            \n            // Current MST cost\n            vector<tuple<ll, int, int>> currentMSTEdges;\n            for (size_t a = 0; a < S.size(); ++a) {\n                for (size_t b = a+1; b < S.size(); ++b) {\n                    int u = S[a], v2 = S[b];\n                    currentMSTEdges.emplace_back(distV[u][v2], u, v2);\n                }\n            }\n            sort(currentMSTEdges.begin(), currentMSTEdges.end());\n            vector<int> currentParent(N);\n            iota(currentParent.begin(), currentParent.end(), 0);\n            function<int(int)> currentFind = [&](int x) {\n                return currentParent[x] == x ? x : currentParent[x] = currentFind(currentParent[x]);\n            };\n            auto currentUnite = [&](int x, int y) {\n                currentParent[currentFind(x)] = currentFind(y);\n            };\n            ll currentMSTCost = 0;\n            for (auto [w, u, v2] : currentMSTEdges) {\n                if (currentFind(u) != currentFind(v2)) {\n                    currentUnite(u, v2);\n                    currentMSTCost += w;\n                }\n            }\n            \n            if (newSumSq + newMSTCost < currentSumSq + currentMSTCost) {\n                // Accept removal\n                S = newS;\n                assign = newAssign;\n                maxDist = newMaxDist;\n                improved = true;\n                break;\n            }\n        }\n    }\n\n    // Compute final P values\n    vector<int> P(N, 0);\n    for (int u : S) {\n        if (maxDist[u] > 0) {\n            int p = (int)ceil(maxDist[u] - 1e-9);\n            P[u] = p;\n        }\n    }\n\n    // Build final MST\n    vector<tuple<ll, int, int>> finalMSTEdges;\n    for (size_t i = 0; i < S.size(); ++i) {\n        for (size_t j = i+1; j < S.size(); ++j) {\n            int u = S[i], v = S[j];\n            finalMSTEdges.emplace_back(distV[u][v], u, v);\n        }\n    }\n    sort(finalMSTEdges.begin(), finalMSTEdges.end());\n    vector<int> finalParent(N);\n    iota(finalParent.begin(), finalParent.end(), 0);\n    function<int(int)> finalFind = [&](int x) {\n        return finalParent[x] == x ? x : finalParent[x] = finalFind(finalParent[x]);\n    };\n    auto finalUnite = [&](int x, int y) {\n        finalParent[finalFind(x)] = finalFind(y);\n    };\n    vector<pair<int, int>> finalMSTPairs;\n    for (auto [w, u, v] : finalMSTEdges) {\n        if (finalFind(u) != finalFind(v)) {\n            finalUnite(u, v);\n            finalMSTPairs.emplace_back(u, v);\n        }\n    }\n\n    // Turn on edges along shortest paths\n    vector<bool> edgeOn(M, false);\n    for (auto [u, v] : finalMSTPairs) {\n        int cur = u;\n        while (cur != v) {\n            int nxt = nextV[cur][v];\n            int idx = edgeIdx[cur][nxt];\n            if (idx != -1) {\n                edgeOn[idx] = true;\n            }\n            cur = nxt;\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N-1 ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; ++j) {\n        cout << edgeOn[j] << (j == M-1 ? '\\n' : ' ');\n    }\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    int grid[N][N];\n    map<int,pair<int,int>> pos;\n    vector<array<int,4>> ops;\n    \n    auto do_swap = [&](int x1,int y1,int x2,int y2){\n        int v1=grid[x1][y1], v2=grid[x2][y2];\n        grid[x1][y1]=v2; grid[x2][y2]=v1;\n        pos[v1]={x2,y2}; pos[v2]={x1,y1};\n        ops.push_back({x1,y1,x2,y2});\n    };\n    \n    auto find_path = [&](int sx,int sy,int ex,int ey){\n        queue<pair<int,int>> q;\n        vector<int> par(N*N,-1);\n        auto sk=[&](int a,int b){return a*N+b;};\n        q.push({sx,sy});\n        int ss=sk(sx,sy);\n        par[ss]=ss;\n        while(!q.empty()){\n            auto[x,y]=q.front();q.pop();\n            int s=sk(x,y);\n            if(x==ex&&y==ey){\n                vector<pair<int,int>> p;\n                int c=s;\n                while(c!=par[c]){\n                    p.push_back({c/N,c%N});\n                    c=par[c];\n                }\n                p.push_back({c/N,c%N});\n                reverse(p.begin(),p.end());\n                return p;\n            }\n            for(auto[dx,dy]:{pair{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}}){\n                int nx=x+dx,ny=y+dy;\n                if(nx>=0&&nx<N&&ny>=0&&ny<=nx){\n                    int ns=sk(nx,ny);\n                    if(par[ns]==-1){par[ns]=s;q.push({nx,ny});}\n                }\n            }\n        }\n        return vector<pair<int,int>>{{sx,sy}};\n    };\n    \n    auto exec_path = [&](int val,int tx,int ty){\n        auto[sx,sy]=pos[val];\n        if(sx==tx&&sy==ty)return;\n        auto path=find_path(sx,sy,tx,ty);\n        for(int i=0;i+1<(int)path.size();i++)\n            do_swap(path[i].first,path[i].second,path[i+1].first,path[i+1].second);\n    };\n    \n    for(int i=0;i<N;i++)\n        for(int j=0;j<=i;j++){\n            cin>>grid[i][j];\n            pos[grid[i][j]]={i,j};\n        }\n    \n    // Floyd's heapify with full sifting and backtrack\n    for(int x=N-2;x>=0;x--){\n        for(int y=x;y>=0;y--){\n            int cx=x, cy=y;\n            while(cx<N-1){\n                int v=grid[cx][cy];\n                int lx=cx+1, ly=cy, rx=cx+1, ry=cy+1;\n                int mx=cx, my=cy, mv=v;\n                if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mx=lx;my=ly;mv=grid[lx][ly];}\n                if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mx=rx;my=ry;mv=grid[rx][ry];}\n                if(mx==cx&&my==cy) break;\n                exec_path(v,mx,my);\n                cx=mx; cy=my;\n            }\n            // Backtrack: if a smaller value bubbled up, re-sift from parent\n            if(cx>x){\n                int px=cx-1, py=(cy>0&&cy>cx-1)?cy-1:cy;\n                if(px>=0&&py>=0&&py<=px&&grid[px][py]>grid[cx][cy]){\n                    int bx=px, by=py;\n                    while(bx<N-1){\n                        int v=grid[bx][by];\n                        int lx=bx+1, ly=by, rx=bx+1, ry=by+1;\n                        int mx=bx, my=by, mv=v;\n                        if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mx=lx;my=ly;mv=grid[lx][ly];}\n                        if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mx=rx;my=ry;mv=grid[rx][ry];}\n                        if(mx==bx&&my==by) break;\n                        exec_path(v,mx,my);\n                        bx=mx; by=my;\n                    }\n                }\n            }\n        }\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto& o:ops) cout<<o[0]<<\" \"<<o[1]<<\" \"<<o[2]<<\" \"<<o[3]<<\"\\n\";\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n#include <cmath>\nusing namespace std;\n\nconst int entrance_i = 0, entrance_j = 4;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nbool obstacle[9][9] = {false};\nbool occupied[9][9] = {false};\nint idx[9][9];  // index in retrieval order, -1 if not a container square\nvector<pair<int, int>> retrieval_order;\n\n// Check if coordinates are within bounds\ninline bool in_bounds(int i, int j) {\n    return i >= 0 && i < 9 && j >= 0 && j < 9;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D, N;\n    cin >> D >> N;  // D is 9, but we still read it\n\n    // Mark obstacles\n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n\n    // List all container squares (excluding entrance and obstacles)\n    vector<pair<int, int>> container_squares;\n    for (int i = 0; i < 9; ++i) {\n        for (int j = 0; j < 9; ++j) {\n            if (i == entrance_i && j == entrance_j) continue;\n            if (obstacle[i][j]) continue;\n            container_squares.emplace_back(i, j);\n        }\n    }\n    int M = container_squares.size();  // number of containers\n\n    // Compute distances from entrance to each container square via BFS\n    int dist[9][9];\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    dist[entrance_i][entrance_j] = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || dist[nx][ny] != -1) continue;\n            dist[nx][ny] = dist[x][y] + 1;\n            q.emplace(nx, ny);\n        }\n    }\n\n    // Sort container squares by distance, then row, then column to get retrieval order\n    sort(container_squares.begin(), container_squares.end(),\n         [&](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             if (a.first != b.first) return a.first < b.first;\n             return a.second < b.second;\n         });\n    retrieval_order = container_squares;\n\n    // Create mapping from square to index in retrieval order\n    memset(idx, -1, sizeof(idx));\n    for (int k = 0; k < M; ++k) {\n        auto [i, j] = retrieval_order[k];\n        idx[i][j] = k;\n    }\n\n    int placed = 0;  // number of containers placed so far\n\n    // Process each container arrival\n    for (int step = 0; step < M; ++step) {\n        int t;\n        cin >> t;\n\n        // BFS to find reachable empty container squares\n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n                // For container squares, only if not occupied\n                if (nx == entrance_i && ny == entrance_j) {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                } else if (!occupied[nx][ny]) {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n\n        // Collect reachable empty container squares\n        vector<pair<int, int>> reachable;\n        for (auto [i, j] : container_squares) {\n            if (vis[i][j] && !occupied[i][j]) {\n                reachable.emplace_back(i, j);\n            }\n        }\n\n        int E = M - placed;  // number of empty container squares before placement\n\n        // Evaluate each reachable square for safety (preserving connectivity)\n        vector<int> safe_indices;\n        vector<int> candidate_indices;\n        for (auto [i, j] : reachable) {\n            candidate_indices.push_back(idx[i][j]);\n\n            // Temporarily occupy this square\n            occupied[i][j] = true;\n\n            // BFS to check if all empty squares are still connected to entrance\n            bool vis2[9][9] = {false};\n            queue<pair<int, int>> q2;\n            q2.emplace(entrance_i, entrance_j);\n            vis2[entrance_i][entrance_j] = true;\n            int count = 1;\n            while (!q2.empty()) {\n                auto [x, y] = q2.front(); q2.pop();\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis2[nx][ny]) continue;\n                    if (nx == entrance_i && ny == entrance_j) {\n                        vis2[nx][ny] = true;\n                        q2.emplace(nx, ny);\n                        count++;\n                    } else if (!occupied[nx][ny]) {\n                        vis2[nx][ny] = true;\n                        q2.emplace(nx, ny);\n                        count++;\n                    }\n                }\n            }\n\n            // Restore\n            occupied[i][j] = false;\n\n            if (count == E) {\n                safe_indices.push_back(idx[i][j]);\n            }\n        }\n\n        // Choose the square with index closest to t, preferring safe squares\n        int chosen_index;\n        if (!safe_indices.empty()) {\n            chosen_index = safe_indices[0];\n            for (int k : safe_indices) {\n                if (abs(k - t) < abs(chosen_index - t)) {\n                    chosen_index = k;\n                }\n            }\n        } else {\n            chosen_index = candidate_indices[0];\n            for (int k : candidate_indices) {\n                if (abs(k - t) < abs(chosen_index - t)) {\n                    chosen_index = k;\n                }\n            }\n        }\n\n        // Output the chosen square\n        auto [pi, pj] = retrieval_order[chosen_index];\n        cout << pi << \" \" << pj << endl;\n\n        // Mark as occupied\n        occupied[pi][pj] = true;\n        placed++;\n    }\n\n    // Output the retrieval order\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int n = 50, m = 100;\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    // size of each color\n    vector<int> sz(m + 1, 0);\n    // whether color is originally adjacent to outside (0)\n    vector<bool> adj0(m + 1, false);\n    // adjacency between colors (excluding 0)\n    vector<vector<bool>> adj(m + 1, vector<bool>(m + 1, false));\n    // edge counts: edge[x][y] = number of unordered adjacent pairs between colors x and y\n    // (including y=0 for outside)\n    vector<vector<int>> edge(m + 1, vector<int>(m + 1, 0));\n\n    // first pass: sizes, adjacency, edge counts\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = grid[i][j];\n            sz[c]++;\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n                adj0[c] = true;\n            }\n            // right neighbor\n            if (j + 1 < n) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    adj[c][d] = adj[d][c] = true;\n                }\n            }\n            // down neighbor\n            if (i + 1 < n) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    adj[c][d] = adj[d][c] = true;\n                }\n            }\n        }\n    }\n\n    // second pass: initial edge counts (each internal edge counted once)\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = grid[i][j];\n            // right\n            if (j + 1 < n) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // down\n            if (i + 1 < n) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // boundary to outside\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n                edge[c][0]++;\n                edge[0][c]++;\n            }\n        }\n    }\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n\n    // visited array for BFS (token method)\n    int vis[50][50] = {};\n    int token = 0;\n\n    // lambda to check if removing (i,j) would disconnect its color\n    auto is_connected_without = [&](int i, int j, int c) -> bool {\n        token++;\n        queue<pair<int, int>> q;\n        // start from a neighbour of the same color\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == c) {\n                vis[ni][nj] = token;\n                q.emplace(ni, nj);\n                break;\n            }\n        }\n        if (q.empty()) return false;   // should not happen in a connected component\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            cnt++;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == c && vis[nx][ny] != token && !(nx == i && ny == j)) {\n                    vis[nx][ny] = token;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n        return cnt == sz[c] - 1;\n    };\n\n    // lambda to test whether cell (i,j) can be turned to 0\n    auto is_removable = [&](int i, int j) -> bool {\n        int c = grid[i][j];\n        if (sz[c] <= 1) return false;\n\n        bool on_boundary = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n        // interior cells must touch an existing 0 cell\n        if (!on_boundary) {\n            bool touches_zero = false;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == 0) {\n                    touches_zero = true;\n                    break;\n                }\n            }\n            if (!touches_zero) return false;\n        }\n\n        // count neighbours\n        vector<int> cnt(m + 1, 0);\n        int n0 = 0;   // neighbours that are already 0\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol > 0) {\n                    if (!adj0[dcol]) return false;   // would create illegal 0-adjacency\n                    cnt[dcol]++;\n                } else if (dcol == 0) {\n                    n0++;\n                }\n            }\n        }\n        int nc = cnt[c];          // neighbours of the same colour\n        int b = on_boundary ? 1 : 0;\n\n        // check that after removal every required edge (c,d) still exists\n        for (int d = 1; d <= m; ++d) {\n            if (d == c) continue;\n            if (adj[c][d]) {\n                if (edge[c][d] - cnt[d] < 1) return false;\n            }\n        }\n\n        // check that colour c remains adjacent to 0 if required\n        if (adj0[c]) {\n            int new_edge_c0 = edge[c][0] - b - n0 + nc;\n            if (new_edge_c0 < 1) return false;\n        }\n\n        // connectivity of colour c\n        if (nc >= 2) {\n            if (!is_connected_without(i, j, c)) return false;\n        }\n        // if nc == 1, the cell is a leaf \u2192 removal cannot disconnect\n        return true;\n    };\n\n    // lambda to actually perform the removal\n    auto remove_cell = [&](int i, int j) {\n        int c = grid[i][j];\n        sz[c]--;\n\n        bool on_boundary = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n\n        // delete old edges\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol != c) {\n                    edge[c][dcol]--;\n                    edge[dcol][c]--;\n                }\n            }\n        }\n        if (on_boundary) {\n            edge[c][0]--;\n            edge[0][c]--;\n        }\n\n        // change to 0\n        grid[i][j] = 0;\n\n        // add new edges (now 0 with its neighbours)\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol != 0) {\n                    edge[0][dcol]++;\n                    edge[dcol][0]++;\n                }\n            }\n        }\n    };\n\n    // queue of candidate cells (initially all boundary cells)\n    queue<pair<int, int>> cand;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if ((i == 0 || i == n - 1 || j == 0 || j == n - 1) && grid[i][j] > 0) {\n                cand.emplace(i, j);\n            }\n        }\n    }\n\n    // main erosion loop\n    while (!cand.empty()) {\n        auto [i, j] = cand.front();\n        cand.pop();\n        if (grid[i][j] == 0) continue;   // already removed\n        if (is_removable(i, j)) {\n            remove_cell(i, j);\n            // neighbours may become removable\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] > 0) {\n                    cand.emplace(ni, nj);\n                }\n            }\n        }\n    }\n\n    // output\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j];\n            if (j + 1 < n) cout << ' ';\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <numeric>\n\nusing namespace std;\n\nint used = 0;\nint N, D, Q;\n\nstring do_query(int l, int r) {\n    cout << \"1 1 \" << l << \" \" << r << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nstring compare_groups(const vector<int>& a, const vector<int>& b) {\n    cout << a.size() << \" \" << b.size();\n    for (int x : a) cout << \" \" << x;\n    for (int x : b) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    // Initialize random generator for shuffling\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    // Create initial order and shuffle\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    \n    vector<int> sorted;\n    sorted.reserve(N);\n    \n    // Decide whether to use greedy assignment based on available queries\n    bool use_greedy = (Q >= 2000);\n    int max_sort_comparisons = use_greedy ? min(Q - (N - D) * (D - 1), Q) : Q;\n    \n    // Binary insertion sort with limited comparisons\n    for (int x : order) {\n        if (used >= max_sort_comparisons) {\n            sorted.push_back(x);\n            continue;\n        }\n        \n        int low = 0, high = sorted.size();\n        while (low < high && used < max_sort_comparisons) {\n            int mid = (low + high) / 2;\n            string res = do_query(x, sorted[mid]);\n            \n            bool mid_is_heavier;\n            if (res == \">\") {\n                mid_is_heavier = true;\n            } else if (res == \"<\") {\n                mid_is_heavier = false;\n            } else {\n                // Tie-break by index\n                mid_is_heavier = (sorted[mid] < x);\n            }\n            \n            if (mid_is_heavier) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        sorted.insert(sorted.begin() + low, x);\n    }\n    \n    vector<int> group(N);\n    \n    if (use_greedy) {\n        // Greedy assignment: assign to smallest group using comparisons\n        vector<vector<int>> groups(D);\n        \n        // First assign the heaviest D items to different groups\n        for (int i = 0; i < D && i < sorted.size(); i++) {\n            groups[i].push_back(sorted[i]);\n        }\n        \n        // Then assign remaining items to smallest group\n        for (int i = D; i < sorted.size(); i++) {\n            int item = sorted[i];\n            \n            // Find smallest group\n            int min_group = 0;\n            for (int g = 1; g < D; g++) {\n                if (groups[min_group].empty()) {\n                    min_group = g;\n                    continue;\n                }\n                if (groups[g].empty()) {\n                    min_group = g;\n                    continue;\n                }\n                \n                string res = compare_groups(groups[min_group], groups[g]);\n                if (res == \">\") {\n                    min_group = g;\n                } else if (res == \"=\") {\n                    // Keep current min_group if equal\n                    continue;\n                }\n            }\n            \n            groups[min_group].push_back(item);\n        }\n        \n        // Convert groups to assignment array\n        for (int g = 0; g < D; g++) {\n            for (int item : groups[g]) {\n                group[item] = g;\n            }\n        }\n        \n        // Use any remaining queries as dummy queries\n        while (used < Q) {\n            do_query(0, 1);\n        }\n    } else {\n        // Original snake order assignment\n        // First assign using snake order on sorted list\n        int cur_group = 0;\n        int step = 1;\n        for (int idx : sorted) {\n            group[idx] = cur_group;\n            cur_group += step;\n            if (cur_group == D) {\n                cur_group = D - 1;\n                step = -1;\n            } else if (cur_group == -1) {\n                cur_group = 0;\n                step = 1;\n            }\n        }\n        \n        // Dummy queries if needed\n        while (used < Q) {\n            do_query(0, 1);\n        }\n    }\n    \n    // Output the division\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << group[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        int cnt = n / m;\n        stacks[i].resize(cnt);\n        for (int j = 0; j < cnt; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    vector<pair<int, int>> ops;\n    int next_box = 1;\n\n    while (next_box <= n) {\n        // locate the current smallest box\n        int s = -1, idx = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == next_box) {\n                    s = i;\n                    idx = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (idx == (int)stacks[s].size() - 1) {\n            // already on top -> carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        } else {\n            // need to move the segment above it\n            int w = stacks[s][idx + 1]; // the box directly above\n\n            // choose destination stack\n            int d = -1;\n            // prefer an empty stack\n            for (int i = 0; i < m; ++i) {\n                if (i != s && stacks[i].empty()) {\n                    d = i;\n                    break;\n                }\n            }\n            if (d == -1) {\n                // choose the stack with the largest top\n                int max_top = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i != s && !stacks[i].empty()) {\n                        int top_val = stacks[i].back();\n                        if (top_val > max_top) {\n                            max_top = top_val;\n                            d = i;\n                        }\n                    }\n                }\n            }\n            // fallback (should never happen because m >= 2)\n            if (d == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i != s) {\n                        d = i;\n                        break;\n                    }\n                }\n            }\n\n            // operation 1: move w and everything above it to stack d\n            ops.emplace_back(w, d + 1); // output 1\u2011based index\n\n            // perform the move\n            vector<int> segment(stacks[s].begin() + idx + 1, stacks[s].end());\n            stacks[s].resize(idx + 1);          // keep only boxes up to and including next_box\n            stacks[d].insert(stacks[d].end(), segment.begin(), segment.end());\n\n            // now next_box is on top of stack s -> carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        }\n    }\n\n    // output the sequence\n    for (auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_NODES = MAX_N * MAX_N;\nconst int DIRS = 4;\nconst int di[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dj[DIRS] = {0, 0, -1, 1};\nconst char dir_char[DIRS] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<array<int, 4>> neighbors; // neighbors[node][dir] = neighbor index or -1\nvector<vector<int>> dist;         // dist[s][t]\nvector<vector<int>> next_move;    // next_move[s][t] = direction from s to t\n\n// Build graph from walls\nvoid build_graph() {\n    int total = N * N;\n    neighbors.assign(total, {-1, -1, -1, -1});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node = i * N + j;\n            // down\n            if (i < N-1 && h[i][j] == '0') {\n                int ni = i+1, nj = j;\n                int nnode = ni * N + nj;\n                neighbors[node][1] = nnode; // D\n                neighbors[nnode][0] = node; // U\n            }\n            // right\n            if (j < N-1 && v[i][j] == '0') {\n                int ni = i, nj = j+1;\n                int nnode = ni * N + nj;\n                neighbors[node][3] = nnode; // R\n                neighbors[nnode][2] = node; // L\n            }\n        }\n    }\n}\n\n// Precompute all-pairs shortest paths and next moves\nvoid precompute_paths() {\n    int total = N * N;\n    dist.assign(total, vector<int>(total, -1));\n    next_move.assign(total, vector<int>(total, -1));\n    for (int s = 0; s < total; ++s) {\n        queue<int> q;\n        q.push(s);\n        dist[s][s] = 0;\n        next_move[s][s] = -1;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int v = neighbors[u][dir];\n                if (v == -1) continue;\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    if (u == s) {\n                        next_move[s][v] = dir;\n                    } else {\n                        next_move[s][v] = next_move[s][u];\n                    }\n                    q.push(v);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(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    build_graph();\n    precompute_paths();\n\n    int total_nodes = N * N;\n    int home = 0; // (0,0)\n\n    // Phase 1: visit all squares at least once\n    string moves;\n    vector<int> m(total_nodes, 0); // visit counts\n    vector<bool> visited(total_nodes, false);\n    int visited_count = 0;\n    int current = home;\n\n    // First move: go to neighbor with highest d\n    int best_dir = -1;\n    int best_d = -1;\n    for (int dir = 0; dir < DIRS; ++dir) {\n        int nb = neighbors[current][dir];\n        if (nb == -1) continue;\n        int i = nb / N, j = nb % N;\n        if (d[i][j] > best_d) {\n            best_d = d[i][j];\n            best_dir = dir;\n        }\n    }\n    // If no neighbor (should not happen), take any\n    if (best_dir == -1) {\n        for (int dir = 0; dir < DIRS; ++dir) {\n            if (neighbors[current][dir] != -1) {\n                best_dir = dir;\n                break;\n            }\n        }\n    }\n    moves += dir_char[best_dir];\n    current = neighbors[current][best_dir];\n    m[current]++;\n    visited[current] = true;\n    visited_count++;\n\n    // Visit remaining squares using nearest unvisited heuristic\n    while (visited_count < total_nodes) {\n        int best_u = -1;\n        int best_dist = 1e9;\n        for (int u = 0; u < total_nodes; ++u) {\n            if (!visited[u]) {\n                int d = dist[current][u];\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_u = u;\n                }\n            }\n        }\n        while (current != best_u) {\n            int dir = next_move[current][best_u];\n            moves += dir_char[dir];\n            current = neighbors[current][dir];\n            m[current]++;\n            if (!visited[current]) {\n                visited[current] = true;\n                visited_count++;\n            }\n        }\n    }\n\n    // Return home\n    while (current != home) {\n        int dir = next_move[current][home];\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        if (!visited[current]) {\n            visited[current] = true;\n            visited_count++;\n        }\n    }\n\n    // Phase 2: greedy walk biased towards high d\n    const int L_max = 100000;\n    int current_length = moves.size();\n    while (current_length < L_max) {\n        int remaining = L_max - current_length;\n        int dist_home = dist[current][home];\n        if (remaining == dist_home) break;\n\n        double best_score = -1.0;\n        int best_dir = -1;\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb == -1) continue;\n            int new_dist_home = dist[nb][home];\n            if (remaining - 1 >= new_dist_home) {\n                int i = nb / N, j = nb % N;\n                double score = d[i][j] / (m[nb] + 1.0);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n        }\n        if (best_dir == -1) break; // no safe move, go home\n\n        moves += dir_char[best_dir];\n        current = neighbors[current][best_dir];\n        m[current]++;\n        current_length++;\n    }\n\n    // Final return home\n    while (current != home) {\n        int dir = next_move[current][home];\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        current_length++;\n    }\n\n    // Output\n    cout << moves << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int M_MAX = 200;\nusing Bits = bitset<M_MAX>;\n\n// rolling hash parameters\nconst uint64_t BASE = 91138233;   // any odd number works\nconst int MAX_LEN = 2000;         // more than enough\nvector<uint64_t> POW(MAX_LEN + 1);\n\nstruct MyString {\n    string s;\n    Bits cov;\n    vector<uint64_t> pref;\n    int len;\n\n    MyString(string s_, Bits cov_) : s(move(s_)), cov(cov_), len(s.size()) {\n        pref.resize(len + 1);\n        pref[0] = 0;\n        for (int i = 0; i < len; ++i) {\n            pref[i + 1] = pref[i] * BASE + (s[i] - 'A' + 1);\n        }\n    }\n\n    // hash of substring [l, r] (inclusive)\n    uint64_t get_hash(int l, int r) const {\n        return pref[r + 1] - pref[l] * POW[r - l + 1];\n    }\n};\n\n// ----------------------------------------------------------------------\n// main solving routine\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // precompute powers\n    POW[0] = 1;\n    for (int i = 1; i <= MAX_LEN; ++i) {\n        POW[i] = POW[i - 1] * BASE;\n    }\n\n    // ----- read input ---------------------------------------------------\n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<string> patterns(M);\n    unordered_map<string, int> pat_to_idx;\n    for (int k = 0; k < M; ++k) {\n        cin >> patterns[k];\n        pat_to_idx[patterns[k]] = k;\n    }\n\n    // ----- keyboard data ------------------------------------------------\n    vector<vector<int>> pos_for_char(26);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            pos_for_char[c - 'A'].push_back(i * N + j);\n        }\n    }\n\n    const int CELLS = N * N;\n    vector<vector<int>> dist(CELLS, vector<int>(CELLS));\n    for (int id1 = 0; id1 < CELLS; ++id1) {\n        int x1 = id1 / N, y1 = id1 % N;\n        for (int id2 = 0; id2 < CELLS; ++id2) {\n            int x2 = id2 / N, y2 = id2 % N;\n            dist[id1][id2] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // ----- build initial strings (each pattern) -------------------------\n    vector<MyString> cur;\n    for (int k = 0; k < M; ++k) {\n        Bits b;\n        b.set(k);\n        cur.emplace_back(patterns[k], b);\n    }\n\n    // helper: compute which patterns appear in a string\n    auto compute_cov = [&](const string& s) -> Bits {\n        Bits bs;\n        int L = s.size();\n        for (int i = 0; i <= L - 5; ++i) {\n            string sub = s.substr(i, 5);\n            auto it = pat_to_idx.find(sub);\n            if (it != pat_to_idx.end()) {\n                bs.set(it->second);\n            }\n        }\n        return bs;\n    };\n\n    // helper: maximum suffix\u2011prefix overlap\n    auto overlap = [&](const MyString& a, const MyString& b) -> int {\n        int lo = 0, hi = min(a.len, b.len);\n        while (lo < hi) {\n            int mid = (lo + hi + 1) / 2;\n            uint64_t ha = a.get_hash(a.len - mid, a.len - 1);\n            uint64_t hb = b.get_hash(0, mid - 1);\n            if (ha == hb)\n                lo = mid;\n            else\n                hi = mid - 1;\n        }\n        return lo;\n    };\n\n    // ----- greedy merging -----------------------------------------------\n    while (cur.size() > 1) {\n        // 1) discard a string whose patterns are already covered by another\n        bool removed = false;\n        for (size_t i = 0; i < cur.size() && !removed; ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                if ((cur[i].cov & cur[j].cov) == cur[j].cov) {\n                    cur.erase(cur.begin() + j);\n                    removed = true;\n                    break;\n                }\n                if ((cur[i].cov & cur[j].cov) == cur[i].cov) {\n                    cur.erase(cur.begin() + i);\n                    removed = true;\n                    break;\n                }\n            }\n        }\n        if (removed) continue;\n\n        // 2) find the pair with maximum overlap\n        int best_ov = -1;\n        size_t best_i = 0, best_j = 0;\n        bool best_rev = false;   // false: i then j, true: j then i\n        for (size_t i = 0; i < cur.size(); ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                int ov;\n\n                ov = overlap(cur[i], cur[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                    best_rev = false;\n                }\n\n                ov = overlap(cur[j], cur[i]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    best_i = i;\n                    best_j = j;\n                    best_rev = true;\n                }\n            }\n        }\n\n        // 3) merge the chosen pair\n        string new_s;\n        if (!best_rev)\n            new_s = cur[best_i].s + cur[best_j].s.substr(best_ov);\n        else\n            new_s = cur[best_j].s + cur[best_i].s.substr(best_ov);\n\n        Bits new_cov = compute_cov(new_s);\n\n        // erase the two original strings (larger index first)\n        size_t idx1 = best_i, idx2 = best_j;\n        if (idx1 > idx2) swap(idx1, idx2);\n        cur.erase(cur.begin() + idx2);\n        cur.erase(cur.begin() + idx1);\n        cur.emplace_back(move(new_s), new_cov);\n\n        // (optional early exit: if new_cov.all() we could keep only this one)\n    }\n\n    string final_s = cur[0].s;   // the superstring containing all patterns\n\n    // ----- DP: optimal key sequence for final_s ------------------------\n    int L = final_s.size();\n\n    struct State {\n        int id;        // cell index\n        int cost;      // minimal cost to reach this state\n        int prev_idx;  // index in previous states vector\n    };\n    vector<vector<State>> states(L);\n\n    // first character\n    int start_id = si * N + sj;\n    for (int id : pos_for_char[final_s[0] - 'A']) {\n        states[0].push_back({id, dist[start_id][id] + 1, -1});\n    }\n\n    // subsequent characters\n    for (int i = 1; i < L; ++i) {\n        char c = final_s[i];\n        vector<int> cur_ids = pos_for_char[c - 'A'];\n        vector<State> cur_states;\n        for (int id : cur_ids) {\n            int best_cost = INT_MAX;\n            int best_prev = -1;\n            for (size_t idx = 0; idx < states[i - 1].size(); ++idx) {\n                const State& prev = states[i - 1][idx];\n                int cand = prev.cost + dist[prev.id][id] + 1;\n                if (cand < best_cost) {\n                    best_cost = cand;\n                    best_prev = idx;\n                }\n            }\n            cur_states.push_back({id, best_cost, best_prev});\n        }\n        states[i] = move(cur_states);\n    }\n\n    // best final state\n    int best_idx = 0;\n    int best_cost = states[L - 1][0].cost;\n    for (size_t i = 1; i < states[L - 1].size(); ++i) {\n        if (states[L - 1][i].cost < best_cost) {\n            best_cost = states[L - 1][i].cost;\n            best_idx = i;\n        }\n    }\n\n    // backtrack\n    vector<int> path_ids(L);\n    int idx = best_idx;\n    for (int i = L - 1; i >= 0; --i) {\n        path_ids[i] = states[i][idx].id;\n        idx = states[i][idx].prev_idx;\n    }\n\n    // ----- output -------------------------------------------------------\n    for (int id : path_ids) {\n        int x = id / N, y = id % N;\n        cout << x << ' ' << y << '\\n';\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <cassert>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    int D = 0;\n    vector<vector<pair<int, int>>> shapes(M);\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        D += d;\n        shapes[k].resize(d);\n        for (int s = 0; s < d; ++s) {\n            int i, j;\n            cin >> i >> j;\n            shapes[k][s] = {i, j};\n        }\n    }\n\n    auto output_query = [&](const vector<pair<int, int>>& squares) {\n        cout << \"q \" << squares.size();\n        for (auto [i, j] : squares) {\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << endl;\n        cout.flush();\n    };\n\n    auto read_response = [&]() -> int {\n        int x;\n        cin >> x;\n        return x;\n    };\n\n    int total_cells = N * N;\n    vector<tuple<int, int, int>> edges; // u, v, sum\n    vector<vector<pair<int, int>>> adj(total_cells); // to (v, sum)\n\n    // Query horizontal adjacent pairs\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) {\n            int u = i * N + j;\n            int v = i * N + j + 1;\n            output_query({{i, j}, {i, j + 1}});\n            int s = read_response();\n            edges.emplace_back(u, v, s);\n            adj[u].emplace_back(v, s);\n            adj[v].emplace_back(u, s);\n        }\n    }\n\n    // Query vertical adjacent pairs for the first column\n    for (int i = 0; i < N - 1; ++i) {\n        int u = i * N + 0;\n        int v = (i + 1) * N + 0;\n        output_query({{i, 0}, {i + 1, 0}});\n        int s = read_response();\n        edges.emplace_back(u, v, s);\n        adj[u].emplace_back(v, s);\n        adj[v].emplace_back(u, s);\n    }\n\n    // BFS from (0,0) to assign a and b\n    vector<vector<int>> a(N, vector<int>(N, 0));\n    vector<vector<int>> b(N, vector<int>(N, 0));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<int> q;\n    a[0][0] = 1;\n    b[0][0] = 0;\n    visited[0][0] = true;\n    q.push(0);\n\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        int i = u / N, j = u % N;\n        for (auto [v, s] : adj[u]) {\n            int vi = v / N, vj = v % N;\n            if (!visited[vi][vj]) {\n                a[vi][vj] = -a[i][j];\n                b[vi][vj] = s - b[i][j];\n                visited[vi][vj] = true;\n                q.push(v);\n            }\n        }\n    }\n\n    // Compute A and B\n    int A = 0, B = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            A += a[i][j];\n            B += b[i][j];\n        }\n    }\n\n    // Check if (D - B) is divisible by A\n    bool error = false;\n    if ((D - B) % A != 0) {\n        error = true;\n    } else {\n        int x = (D - B) / A;\n        vector<vector<int>> v(N, vector<int>(N, 0));\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                v[i][j] = a[i][j] * x + b[i][j];\n                if (v[i][j] < 0 || v[i][j] > M) {\n                    error = true;\n                }\n            }\n        }\n\n        // Verify edge sums\n        if (!error) {\n            for (auto [u, vt, s] : edges) {\n                int ui = u / N, uj = u % N;\n                int vi = vt / N, vj = vt % N;\n                if (v[ui][uj] + vi[v][vj] != s) {\n                    error = true;\n                    break;\n                }\n            }\n        }\n\n        if (!error) {\n            // Prepare guess\n            vector<pair<int, int>> positive;\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    if (v[i][j] > 0) {\n                        positive.emplace_back(i, j);\n                    }\n                }\n            }\n            cout << \"a \" << positive.size();\n            for (auto [i, j] : positive) {\n                cout << \" \" << i << \" \" << j;\n            }\n            cout << endl;\n            cout.flush();\n            int resp = read_response();\n            if (resp == 1) {\n                return 0;\n            } else {\n                error = true;\n            }\n        }\n    }\n\n    // Fallback: drill all squares\n    if (error) {\n        vector<pair<int, int>> positive;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                output_query({{i, j}});\n                int val = read_response();\n                if (val > 0) {\n                    positive.emplace_back(i, j);\n                }\n            }\n        }\n        cout << \"a \" << positive.size();\n        for (auto [i, j] : positive) {\n            cout << \" \" << i << \" \" << j;\n        }\n        cout << endl;\n        cout.flush();\n        int resp = read_response();\n        // Should be 1, but we don't need to do anything else\n    }\n\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int area;\n};\n\n// tries to pack rectangles with desired areas B (sorted descending) using common row height H\n// returns true and fills rects if successful\nbool pack(int W, int H, const vector<int>& B, vector<Rect>& rects) {\n    int N = B.size();\n    vector<int> w(N);\n    for (int i = 0; i < N; ++i) {\n        w[i] = (B[i] + H - 1) / H;          // width needed for area at least B[i]\n        if (w[i] > W) return false;         // too wide to fit\n    }\n    // indices sorted by width descending (first-fit decreasing)\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    vector<int> row_used;                     // used width in each row\n    vector<vector<pair<int, int>>> row_items; // each row: (rectangle index, start_x)\n\n    for (int i : idx) {\n        int placed = -1;\n        for (int r = 0; r < (int)row_used.size(); ++r) {\n            if (row_used[r] + w[i] <= W) {\n                placed = r;\n                break;\n            }\n        }\n        if (placed == -1) {                   // start new row\n            row_used.push_back(w[i]);\n            row_items.push_back({{i, 0}});\n        } else {\n            int start_x = row_used[placed];\n            row_used[placed] += w[i];\n            row_items[placed].emplace_back(i, start_x);\n        }\n    }\n\n    int rows = row_used.size();\n    if (rows * H > W) return false;           // total height exceeds W\n\n    rects.assign(N, Rect());\n    for (int r = 0; r < rows; ++r) {\n        int y0 = r * H;\n        int y1 = y0 + H;\n        for (auto& p : row_items[r]) {\n            int id = p.first;\n            int x0 = p.second;\n            rects[id].x0 = x0;\n            rects[id].x1 = x0 + w[id];\n            rects[id].y0 = y0;\n            rects[id].y1 = y1;\n            rects[id].area = w[id] * H;\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    cin >> W >> D >> N;\n\n    vector<vector<int>> a_original(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a_original[d][k];\n\n    // ----- build descending demands per day -----\n    vector<vector<int>> a_desc(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        a_desc[d] = a_original[d];\n        sort(a_desc[d].begin(), a_desc[d].end(), greater<int>());\n    }\n\n    // ----- for each position i (i-th largest) collect values over days -----\n    vector<vector<int>> slot_vals(N, vector<int>(D));\n    for (int i = 0; i < N; ++i) {\n        for (int d = 0; d < D; ++d)\n            slot_vals[i][d] = a_desc[d][i];\n        sort(slot_vals[i].begin(), slot_vals[i].end(), greater<int>());\n    }\n\n    // ----- water filling to obtain optimal target areas b[i] -----\n    vector<int> b(N, 0);\n    vector<int> ptr(N, D);                // number of values > current b[i]\n    using P = pair<int, int>;\n    priority_queue<P> pq;                 // max-heap by f = ptr\n    for (int i = 0; i < N; ++i)\n        pq.emplace(ptr[i], i);\n\n    const int S = W * W;\n    int total_used = 0;\n    while (total_used < S && !pq.empty()) {\n        auto [f, i] = pq.top();\n        pq.pop();\n        if (f != ptr[i]) continue;        // outdated entry\n        if (f == 0) break;                // no further improvement possible\n        // add one unit to rectangle i\n        b[i]++;\n        total_used++;\n        // update ptr[i]\n        while (ptr[i] > 0 && slot_vals[i][ptr[i] - 1] <= b[i])\n            ptr[i]--;\n        pq.emplace(ptr[i], i);\n    }\n\n    // b now contains the desired areas; sort them descending\n    vector<int> B = b;\n    sort(B.begin(), B.end(), greater<int>());\n\n    // ----- pack rectangles into the W x W square -----\n    vector<Rect> rects;\n    int H_min = 0;\n    for (int bi : B)\n        H_min = max(H_min, (bi + W - 1) / W);   // smallest H such that width <= W\n\n    bool packed = false;\n    auto pack_lambda = [&](int H, const vector<int>& B, vector<Rect>& rects) -> bool {\n        return pack(W, H, B, rects);\n    };\n    for (int H = H_min; H <= W; ++H) {\n        if (pack_lambda(H, B, rects)) {\n            packed = true;\n            break;\n        }\n    }\n    if (!packed) {   // fallback: vertical strips of almost equal width\n        int Nrect = B.size();\n        vector<int> widths(Nrect, W / Nrect);\n        int rem = W % Nrect;\n        for (int i = 0; i < rem; ++i) widths[i]++;\n        rects.resize(Nrect);\n        int x = 0;\n        for (int i = 0; i < Nrect; ++i) {\n            rects[i].x0 = x;\n            rects[i].x1 = x + widths[i];\n            rects[i].y0 = 0;\n            rects[i].y1 = W;\n            rects[i].area = widths[i] * W;\n            x += widths[i];\n        }\n    }\n\n    // ----- order rectangles by area (largest first) -----\n    vector<int> rect_order(N);\n    iota(rect_order.begin(), rect_order.end(), 0);\n    sort(rect_order.begin(), rect_order.end(),\n         [&](int i, int j) { return rects[i].area > rects[j].area; });\n\n    // ----- assign rectangles to reservations each day -----\n    vector<vector<int>> assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int, int>> dem;   // (demand, original index)\n        for (int k = 0; k < N; ++k)\n            dem.emplace_back(a_original[d][k], k);\n        sort(dem.begin(), dem.end(), greater<pair<int, int>>());\n        for (int t = 0; t < N; ++t) {\n            int orig_k = dem[t].second;\n            int ridx = rect_order[t];\n            assign[d][orig_k] = ridx;\n        }\n    }\n\n    // ----- output -----\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int r = assign[d][k];\n            cout << rects[r].x0 << \" \" << rects[r].y0 << \" \"\n                 << rects[r].x1 << \" \" << rects[r].y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll MOD = 998244353;\n\nll mod(ll x) {\n    return ((x % MOD) + MOD) % MOD;\n}\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<vector<ll>> a(N, vector<ll>(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    vector<vector<vector<ll>>> s(M, vector<vector<ll>>(3, vector<ll>(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    // Greedy initial solution\n    vector<vector<ll>> board = a;\n    vector<tuple<int, int, int>> ops;\n    for (int step = 0; step < K; ++step) {\n        ll best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll gain = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int i = p + di, j = q + dj;\n                            ll old_val = board[i][j];\n                            ll add = s[m][di][dj];\n                            ll new_val = old_val + add;\n                            ll old_rem = mod(old_val);\n                            ll new_rem = mod(new_val);\n                            gain += new_rem - old_rem;\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int i = best_p + di, j = best_q + dj;\n                board[i][j] += s[best_m][di][dj];\n            }\n        }\n        ops.emplace_back(best_m, best_p, best_q);\n    }\n\n    // Local search improvements\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_op(0, M - 1);\n    uniform_int_distribution<int> rand_pos(0, N - 3);\n    const int LOCAL_ITER = 5000;\n    int L = ops.size();\n    for (int iter = 0; iter < LOCAL_ITER; ++iter) {\n        if (L == 0 && K == 0) break;\n        int move_type;\n        if (L == 0) move_type = 0; // only add\n        else if (L == K) move_type = uniform_int_distribution<int>(1, 2)(rng); // remove or replace\n        else move_type = uniform_int_distribution<int>(0, 2)(rng);\n\n        if (move_type == 0) { // add\n            if (L >= K) continue;\n            int m = rand_op(rng);\n            int p = rand_pos(rng);\n            int q = rand_pos(rng);\n            ll delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val + s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] += s[m][di][dj];\n                    }\n                }\n                ops.emplace_back(m, p, q);\n                L++;\n            }\n        } else if (move_type == 1) { // remove\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m, p, q] = ops[idx];\n            ll delta = 0;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val - s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] -= s[m][di][dj];\n                    }\n                }\n                ops.erase(ops.begin() + idx);\n                L--;\n            }\n        } else { // replace\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m_old, p_old, q_old] = ops[idx];\n            int m_new = rand_op(rng);\n            int p_new = rand_pos(rng);\n            int q_new = rand_pos(rng);\n            // Collect union of cells\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p_old + di, q_old + dj});\n                    cells.insert({p_new + di, q_new + dj});\n                }\n            }\n            ll delta = 0;\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                if (i >= p_old && i < p_old + 3 && j >= q_old && j < q_old + 3) {\n                    int di = i - p_old, dj = j - q_old;\n                    new_val -= s[m_old][di][dj];\n                }\n                if (i >= p_new && i < p_new + 3 && j >= q_new && j < q_new + 3) {\n                    int di = i - p_new, dj = j - q_new;\n                    new_val += s[m_new][di][dj];\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_old + di, j = q_old + dj;\n                        board[i][j] -= s[m_old][di][dj];\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_new + di, j = q_new + dj;\n                        board[i][j] += s[m_new][di][dj];\n                    }\n                }\n                ops[idx] = {m_new, p_new, q_new};\n            }\n        }\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto [m, p, q] : ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    const int N = 5;\n    int A[N][N];\n    int grid[N][N];\n    pair<int, int> pos_of[25];          // position of each container on the grid, (-1,-1) if not present\n    int next_idx[N] = {0};              // how many containers have been placed from each gate\n    bool dispatched[25] = {false};\n    int next_dispatch = 0;              // smallest container number not yet dispatched (not used in decisions)\n\n    // crane state\n    int crane_r = 0, crane_c = 0;\n    int crane_hold = -1;                // -1 means not holding\n\n    // read input\n    int dummy; cin >> dummy;            // N is always 5, but we read it\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // initialise grid and pos_of\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = -1;\n    for (int b = 0; b < 25; ++b)\n        pos_of[b] = {-1, -1};\n\n    vector<char> actions;               // actions of the large crane\n\n    // helper lambdas\n    auto move_towards = [&](int tr, int tc) -> char {\n        if (crane_r != tr)\n            return (tr < crane_r) ? 'U' : 'D';\n        else\n            return (tc < crane_c) ? 'L' : 'R';\n    };\n\n    auto decide = [&]() -> char {\n        if (crane_hold != -1) {\n            // holding a container -> go to its dispatch gate and release\n            int tr = crane_hold / N;\n            int tc = N - 1;\n            if (crane_r == tr && crane_c == tc)\n                return 'Q';\n            return move_towards(tr, tc);\n        } else {\n            // not holding -> pick up the nearest container from a receiving gate\n            int best_r = -1, best_c = -1, best_dist = 100;\n            for (int i = 0; i < N; ++i) {\n                if (grid[i][0] != -1) {\n                    int d = abs(i - crane_r) + abs(0 - crane_c);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_r = i;\n                        best_c = 0;\n                    }\n                }\n            }\n            if (best_r != -1) {\n                if (crane_r == best_r && crane_c == best_c)\n                    return 'P';\n                return move_towards(best_r, best_c);\n            } else {\n                // no container on any gate -> wait\n                return '.';\n            }\n        }\n    };\n\n    auto apply = [&](char act) {\n        if (act == 'P') {\n            // pick up\n            crane_hold = grid[crane_r][crane_c];\n            grid[crane_r][crane_c] = -1;\n            pos_of[crane_hold] = {-1, -1};\n        } else if (act == 'Q') {\n            // release\n            int cont = crane_hold;\n            grid[crane_r][crane_c] = cont;\n            pos_of[cont] = {crane_r, crane_c};\n            crane_hold = -1;\n        } else if (act == 'U') {\n            --crane_r;\n        } else if (act == 'D') {\n            ++crane_r;\n        } else if (act == 'L') {\n            --crane_c;\n        } else if (act == 'R') {\n            ++crane_c;\n        } // '.' does nothing\n    };\n\n    // simulation loop\n    const int MAX_TURN = 10000;\n    for (int turn = 1; turn <= MAX_TURN; ++turn) {\n        // ----- step 1 : receiving -----\n        for (int i = 0; i < N; ++i) {\n            if (next_idx[i] < N && grid[i][0] == -1) {\n                // condition: no crane holding a container at this square\n                if (crane_r == i && crane_c == 0 && crane_hold != -1)\n                    continue;   // blocked\n                int cont = A[i][next_idx[i]];\n                grid[i][0] = cont;\n                pos_of[cont] = {i, 0};\n                ++next_idx[i];\n            }\n        }\n\n        // ----- step 2 : actions -----\n        char act = decide();\n        actions.push_back(act);\n        apply(act);\n\n        // ----- step 3 : dispatch -----\n        for (int i = 0; i < N; ++i) {\n            int cont = grid[i][N-1];\n            if (cont != -1) {\n                dispatched[cont] = true;\n                grid[i][N-1] = -1;\n                pos_of[cont] = {-1, -1};\n            }\n        }\n\n        // update next_dispatch (not used in decisions but kept for completeness)\n        while (next_dispatch < N*N && dispatched[next_dispatch])\n            ++next_dispatch;\n\n        // check completion\n        bool all_done = true;\n        for (int b = 0; b < N*N; ++b)\n            if (!dispatched[b]) { all_done = false; break; }\n        if (all_done)\n            break;\n    }\n\n    int T = actions.size();\n    // output for large crane (initially at (0,0))\n    string S0(actions.begin(), actions.end());\n    cout << S0 << endl;\n    // output for the four small cranes: bomb at first turn, then idle\n    for (int i = 1; i < N; ++i) {\n        string Si = 'B' + string(T-1, '.');\n        cout << Si << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<array<int, 3>> supplies, demands;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0)\n                supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0)\n                demands.push_back({i, j, -h[i][j]});\n        }\n    }\n\n    vector<string> ops;\n    int cur_r = 0, cur_c = 0, load = 0;\n\n    auto move_to = [&](int tr, int tc) {\n        while (cur_r > tr) {\n            ops.push_back(\"U\");\n            --cur_r;\n        }\n        while (cur_r < tr) {\n            ops.push_back(\"D\");\n            ++cur_r;\n        }\n        while (cur_c > tc) {\n            ops.push_back(\"L\");\n            --cur_c;\n        }\n        while (cur_c < tc) {\n            ops.push_back(\"R\");\n            ++cur_c;\n        }\n    };\n\n    while (!supplies.empty() || !demands.empty()) {\n        if (load == 0) {\n            // Choose supply with smallest distance/amount\n            int best_idx = -1;\n            long long best_num = 0, best_den = 1;\n            for (int i = 0; i < (int)supplies.size(); ++i) {\n                auto& s = supplies[i];\n                int dist = abs(cur_r - s[0]) + abs(cur_c - s[1]);\n                int amt = s[2];\n                if (best_idx == -1 || dist * best_den < best_num * amt) {\n                    best_idx = i;\n                    best_num = dist;\n                    best_den = amt;\n                }\n            }\n            auto& s = supplies[best_idx];\n            move_to(s[0], s[1]);\n            ops.push_back(\"+\" + to_string(s[2]));\n            load += s[2];\n            supplies.erase(supplies.begin() + best_idx);\n        } else {\n            vector<int> feasible;\n            for (int i = 0; i < (int)demands.size(); ++i) {\n                if (demands[i][2] <= load)\n                    feasible.push_back(i);\n            }\n            if (!feasible.empty()) {\n                // Choose demand that minimizes distance/(amount + load) to prioritize larger amounts when load is high\n                int best_idx = -1;\n                long long best_num = 0, best_den = 1;\n                for (int idx : feasible) {\n                    auto& d = demands[idx];\n                    int dist = abs(cur_r - d[0]) + abs(cur_c - d[1]);\n                    int amt = d[2];\n                    // Compare dist1/(amt1+load) vs dist2/(amt2+load) by cross-multiplication\n                    if (best_idx == -1 || dist * (best_den + load) < best_num * (amt + load)) {\n                        best_idx = idx;\n                        best_num = dist;\n                        best_den = amt;\n                    }\n                }\n                auto& d = demands[best_idx];\n                move_to(d[0], d[1]);\n                ops.push_back(\"-\" + to_string(d[2]));\n                load -= d[2];\n                demands.erase(demands.begin() + best_idx);\n            } else {\n                // No feasible demand - choose supply with smallest distance/amount\n                int best_idx = -1;\n                long long best_num = 0, best_den = 1;\n                for (int i = 0; i < (int)supplies.size(); ++i) {\n                    auto& s = supplies[i];\n                    int dist = abs(cur_r - s[0]) + abs(cur_c - s[1]);\n                    int amt = s[2];\n                    if (best_idx == -1 || dist * best_den < best_num * amt) {\n                        best_idx = i;\n                        best_num = dist;\n                        best_den = amt;\n                    }\n                }\n                auto& s = supplies[best_idx];\n                move_to(s[0], s[1]);\n                ops.push_back(\"+\" + to_string(s[2]));\n                load += s[2];\n                supplies.erase(supplies.begin() + best_idx);\n            }\n        }\n    }\n\n    for (string& op : ops)\n        cout << op << endl;\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\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);  // 60\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    for (int t = 0; t < T; t++) {\n        // Compute sum for each seed\n        vector<int> sum(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            int s = 0;\n            for (int j = 0; j < M; j++) {\n                s += seeds[i][j];\n            }\n            sum[i] = s;\n        }\n\n        // Find seed with max value for each criterion\n        vector<int> max_val(M, -1);\n        vector<int> max_idx(M, -1);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                if (seeds[i][l] > max_val[l]) {\n                    max_val[l] = seeds[i][l];\n                    max_idx[l] = i;\n                }\n            }\n        }\n\n        // Set of important seeds (max per criterion)\n        set<int> important;\n        for (int l = 0; l < M; l++) {\n            important.insert(max_idx[l]);\n        }\n\n        // Sort all seeds by sum descending\n        vector<pair<int, int>> sum_idx;\n        for (int i = 0; i < seed_count; i++) {\n            sum_idx.emplace_back(sum[i], i);\n        }\n        sort(sum_idx.begin(), sum_idx.end(), greater<pair<int, int>>());\n\n        // Select seeds to plant\n        vector<int> to_plant;\n        for (int idx : important) {\n            to_plant.push_back(idx);\n        }\n        for (auto& p : sum_idx) {\n            if (to_plant.size() >= 36) break;\n            int idx = p.second;\n            if (important.find(idx) == important.end()) {\n                to_plant.push_back(idx);\n            }\n        }\n\n        // Sort to_plant by sum descending for grid assignment\n        sort(to_plant.begin(), to_plant.end(),\n             [&](int a, int b) { return sum[a] > sum[b]; });\n\n        // Output grid (6x6)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << to_plant[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read next generation if not last turn\n        if (t < T - 1) {\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\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n#include <cstdlib>\n#include <cassert>\n\nusing namespace std;\n\n// Directions: 0:right, 1:down, 2:left, 3:up\nconst int dr[4] = {0, 1, 0, -1};\nconst int dc[4] = {1, 0, -1, 0};\n\nint N, M, V;\nint V_prime;          // number of vertices used\nint K;                // number of leaves = V_prime-1\nvector<int> len;      // length of each leaf (1-indexed, len[i] for leaf i)\nint root_r, root_c;   // current root position\nvector<int> dir;      // direction of each leaf (1-indexed)\nvector<bool> holding; // whether leaf i holds a takoyaki\nbool src_rem[30][30]; // remaining source squares\nbool tgt_rem[30][30]; // remaining target squares\nint src_cnt, tgt_cnt; // counts\n\n// Helper functions\ninline bool in_grid(int r, int c) {\n    return 0 <= r && r < N && 0 <= c && c < N;\n}\n\n// Output one turn\nvoid output_turn(char move, const vector<char>& rot, const vector<char>& act) {\n    string S(2 * V_prime, '.');\n    S[0] = move;\n    for (int i = 1; i <= K; ++i) {\n        S[i] = rot[i];\n    }\n    for (int i = 0; i <= K; ++i) {\n        if (act[i] == 'P') {\n            S[V_prime + i] = 'P';\n        }\n    }\n    cout << S << '\\n';\n}\n\n// Move root to (tr,tc) while rotating leaf `leaf` to direction `des_dir`.\n// Performs one step per turn, rotating the leaf as much as possible.\nvoid move_root_to(int tr, int tc, int leaf, int des_dir) {\n    while (root_r != tr || root_c != tc) {\n        // Determine movement direction\n        char move_char;\n        if (tr > root_r) move_char = 'D';\n        else if (tr < root_r) move_char = 'U';\n        else if (tc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Rotation for the leaf we are controlling\n        char rot_leaf = '.';\n        if (leaf != -1 && dir[leaf] != des_dir) {\n            int diff = (des_dir - dir[leaf] + 4) % 4;\n            if (diff == 1) {\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            } else if (diff == 3) {\n                rot_leaf = 'L';\n                dir[leaf] = (dir[leaf] + 3) % 4;\n            } else { // diff == 2, rotate arbitrarily (choose R)\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            }\n        }\n\n        vector<char> rot(K+1, '.');\n        if (leaf != -1) rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.'); // no pick/drop during movement\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        if (move_char == 'U') root_r--;\n        else if (move_char == 'D') root_r++;\n        else if (move_char == 'L') root_c--;\n        else if (move_char == 'R') root_c++;\n    }\n\n    // After reaching the target, finish rotation if needed\n    while (leaf != -1 && dir[leaf] != des_dir) {\n        char rot_leaf = '.';\n        int diff = (des_dir - dir[leaf] + 4) % 4;\n        if (diff == 1) {\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        } else if (diff == 3) {\n            rot_leaf = 'L';\n            dir[leaf] = (dir[leaf] + 3) % 4;\n        } else { // diff == 2\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        }\n        vector<char> rot(K+1, '.');\n        rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.');\n        output_turn('.', rot, act);\n    }\n}\n\n// Output a turn with only a pick/drop for a given leaf (no movement, no other rotations)\nvoid output_action(int leaf, char action) {\n    vector<char> rot(K+1, '.');\n    vector<char> act(K+1, '.');\n    act[leaf] = action;\n    output_turn('.', rot, act);\n}\n\n// Find any remaining target square that leaf i can reach, together with a suitable direction.\ntuple<int,int,int> find_target_for_leaf(int i) {\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (tgt_rem[r][c]) {\n                for (int d = 0; d < 4; ++d) {\n                    int nr = r - dr[d] * len[i];\n                    int nc = c - dc[d] * len[i];\n                    if (in_grid(nr, nc)) {\n                        return make_tuple(r, c, d);\n                    }\n                }\n            }\n        }\n    }\n    // should never happen\n    return make_tuple(-1, -1, -1);\n}\n\n// Find any remaining source square\npair<int,int> find_source() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (src_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Find any remaining target square\npair<int,int> find_target() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (tgt_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N >> M >> V;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Determine sources and targets (remove overlaps)\n    src_cnt = tgt_cnt = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool s = (s_grid[i][j] == '1');\n            bool t = (t_grid[i][j] == '1');\n            if (s && t) {\n                // already in place, ignore\n                src_rem[i][j] = false;\n                tgt_rem[i][j] = false;\n            } else if (s) {\n                src_rem[i][j] = true;\n                ++src_cnt;\n                tgt_rem[i][j] = false;\n            } else if (t) {\n                tgt_rem[i][j] = true;\n                ++tgt_cnt;\n                src_rem[i][j] = false;\n            } else {\n                src_rem[i][j] = tgt_rem[i][j] = false;\n            }\n        }\n    }\n\n    // Design the arm: star with root 0 and leaves 1..K, lengths = 1,2,...,K\n    V_prime = V;                // use all vertices\n    K = V_prime - 1;\n    len.resize(K+1);\n    for (int i = 1; i <= K; ++i) len[i] = i;   // guaranteed i <= N-1 because N>=15, K<=14\n\n    // Initial root position (choose (0,0))\n    root_r = 0; root_c = 0;\n\n    // Output arm design\n    cout << V_prime << '\\n';\n    for (int i = 1; i <= K; ++i) {\n        cout << \"0 \" << len[i] << '\\n';\n    }\n    cout << root_r << ' ' << root_c << '\\n';\n\n    // Initialize state\n    dir.assign(K+1, 0);          // all initially point right\n    holding.assign(K+1, false);\n\n    // Snake traversal: generate order of cells\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        } else {\n            for (int j = N-1; j >= 0; --j) cells.emplace_back(i, j);\n        }\n    }\n\n    // Perform moves along the snake\n    for (size_t idx = 0; idx+1 < cells.size(); ++idx) {\n        int nr = cells[idx+1].first;\n        int nc = cells[idx+1].second;\n\n        // Determine movement character\n        char move_char;\n        if (nr > root_r) move_char = 'D';\n        else if (nr < root_r) move_char = 'U';\n        else if (nc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Greedy assignment of picks/drops at the new position\n        vector<bool> used(K+1, false);\n        vector<int> desired_dir(K+1, -1);\n        vector<char> action(K+1, '.');\n\n        // Drops first\n        for (int i = 1; i <= K; ++i) {\n            if (holding[i] && !used[i]) {\n                // Try the three reachable directions\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && tgt_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = false;\n                        tgt_rem[pr][pc] = false;\n                        --tgt_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Picks\n        for (int i = 1; i <= K; ++i) {\n            if (!holding[i] && !used[i]) {\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && src_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = true;\n                        src_rem[pr][pc] = false;\n                        --src_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Build rotation commands\n        vector<char> rot(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (desired_dir[i] != -1) {\n                int delta = (desired_dir[i] - dir[i] + 4) % 4;\n                if (delta == 0) rot[i] = '.';\n                else if (delta == 1) rot[i] = 'R';\n                else if (delta == 3) rot[i] = 'L';\n                // delta == 2 cannot happen because we only used reachable directions\n                dir[i] = desired_dir[i];\n            }\n        }\n\n        // Build action vector (root action always '.')\n        vector<char> act(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (action[i] == 'P') act[i] = 'P';\n        }\n\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        root_r = nr;\n        root_c = nc;\n    }\n\n    // If all takoyaki are already at targets, we are done\n    if (src_cnt == 0 && tgt_cnt == 0) {\n        return 0;\n    }\n\n    // ----- Cleanup phase -----\n    // Step 1: Drop any takoyaki still held by leaves\n    for (int i = 1; i <= K; ++i) {\n        while (holding[i]) {\n            auto [tr, tc, d] = find_target_for_leaf(i);\n            int nr = tr - dr[d] * len[i];\n            int nc = tc - dc[d] * len[i];\n            move_root_to(nr, nc, i, d);\n            output_action(i, 'P');\n            holding[i] = false;\n            tgt_rem[tr][tc] = false;\n            --tgt_cnt;\n        }\n    }\n\n    // Step 2: Move remaining sources to targets using leaf 1 (length = 1)\n    while (src_cnt > 0) {\n        auto [sr, sc] = find_source();\n        auto [tr, tc] = find_target();\n\n        // Pick with leaf 1\n        int d_pick = -1, nr_pick, nc_pick;\n        for (int d = 0; d < 4; ++d) {\n            nr_pick = sr - dr[d] * len[1];\n            nc_pick = sc - dc[d] * len[1];\n            if (in_grid(nr_pick, nc_pick)) {\n                d_pick = d;\n                break;\n            }\n        }\n        move_root_to(nr_pick, nc_pick, 1, d_pick);\n        output_action(1, 'P');\n        holding[1] = true;\n        src_rem[sr][sc] = false;\n        --src_cnt;\n\n        // Drop with leaf 1\n        int d_drop = -1, nr_drop, nc_drop;\n        for (int d = 0; d < 4; ++d) {\n            nr_drop = tr - dr[d] * len[1];\n            nc_drop = tc - dc[d] * len[1];\n            if (in_grid(nr_drop, nc_drop)) {\n                d_drop = d;\n                break;\n            }\n        }\n        move_root_to(nr_drop, nc_drop, 1, d_drop);\n        output_action(1, 'P');\n        holding[1] = false;\n        tgt_rem[tr][tc] = false;\n        --tgt_cnt;\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n};\n\nint compute_score(int x1, int x2, int y1, int y2, \n                  const vector<Point>& mack, const vector<Point>& sard) {\n    int a = 0, b = 0;\n    for (const auto& p : mack) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) a++;\n    }\n    for (const auto& p : sard) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) b++;\n    }\n    return max(0, a - b + 1);\n}\n\nvoid local_optimize(int& x1, int& x2, int& y1, int& y2,\n                    const vector<Point>& mack, const vector<Point>& sard,\n                    const vector<int>& xs, const vector<int>& ys) {\n    auto get_next_left = [&](int x) {\n        auto it = lower_bound(xs.begin(), xs.end(), x);\n        if (it == xs.begin()) return x;\n        return *(--it);\n    };\n    auto get_next_right = [&](int x) {\n        auto it = upper_bound(xs.begin(), xs.end(), x);\n        if (it == xs.end()) return x;\n        return *it;\n    };\n    auto get_next_bottom = [&](int y) {\n        auto it = lower_bound(ys.begin(), ys.end(), y);\n        if (it == ys.begin()) return y;\n        return *(--it);\n    };\n    auto get_next_top = [&](int y) {\n        auto it = upper_bound(ys.begin(), ys.end(), y);\n        if (it == ys.end()) return y;\n        return *it;\n    };\n\n    int current_score = compute_score(x1, x2, y1, y2, mack, sard);\n    for (int iter = 0; iter < 100; iter++) {\n        bool improved = false;\n        // Try left\n        int new_x1 = get_next_left(x1);\n        if (new_x1 < x1 && new_x1 < x2) {\n            int new_score = compute_score(new_x1, x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = new_x1;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        // Try right\n        int new_x2 = get_next_right(x2);\n        if (new_x2 > x2 && x1 < new_x2) {\n            int new_score = compute_score(x1, new_x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x2 = new_x2;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        // Try bottom\n        int new_y1 = get_next_bottom(y1);\n        if (new_y1 < y1 && new_y1 < y2) {\n            int new_score = compute_score(x1, x2, new_y1, y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = new_y1;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        // Try top\n        int new_y2 = get_next_top(y2);\n        if (new_y2 > y2 && y1 < new_y2) {\n            int new_score = compute_score(x1, x2, y1, new_y2, mack, sard);\n            if (new_score > current_score) {\n                y2 = new_y2;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nvector<tuple<int, int, int, int, int>> process_cell_size(int cell_size,\n                                                         const vector<Point>& mack,\n                                                         const vector<Point>& sard) {\n    int num_cells_x = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    int num_cells_y = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    vector<vector<int>> mack_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<vector<int>> sard_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<pair<int, int>> mack_cells(mack.size());\n\n    for (size_t i = 0; i < mack.size(); i++) {\n        int cx = mack[i].x / cell_size;\n        int cy = mack[i].y / cell_size;\n        mack_count[cx][cy]++;\n        mack_cells[i] = {cx, cy};\n    }\n    for (size_t i = 0; i < sard.size(); i++) {\n        int cx = sard[i].x / cell_size;\n        int cy = sard[i].y / cell_size;\n        sard_count[cx][cy]++;\n    }\n\n    vector<vector<int>> weight(num_cells_x, vector<int>(num_cells_y, 0));\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            weight[i][j] = mack_count[i][j] - sard_count[i][j];\n        }\n    }\n\n    vector<vector<bool>> visited(num_cells_x, vector<bool>(num_cells_y, false));\n    vector<vector<pair<int, int>>> components;\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0 && !visited[i][j]) {\n                vector<pair<int, int>> comp;\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();\n                    q.pop();\n                    comp.push_back({x, y});\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 < num_cells_x && ny >= 0 && ny < num_cells_y &&\n                            weight[nx][ny] > 0 && !visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n        }\n    }\n\n    auto count_mack = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : mack) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) cnt++;\n        }\n        return cnt;\n    };\n\n    auto count_sard = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : sard) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) cnt++;\n        }\n        return cnt;\n    };\n\n    vector<tuple<int, int, int, int, int>> candidates;\n\n    // Cell rectangles\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0) {\n                int x1 = i * cell_size;\n                int x2 = min(MAX_COORD, (i + 1) * cell_size);\n                int y1 = j * cell_size;\n                int y2 = min(MAX_COORD, (j + 1) * cell_size);\n                if (x1 < x2 && y1 < y2) {\n                    int a = count_mack(x1, x2, y1, y2);\n                    int b = count_sard(x1, x2, y1, y2);\n                    int score = max(0, a - b + 1);\n                    candidates.push_back({x1, x2, y1, y2, score});\n                }\n            }\n        }\n    }\n\n    // Component bounding boxes\n    for (const auto& comp : components) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (size_t i = 0; i < mack.size(); i++) {\n            int cx = mack_cells[i].first, cy = mack_cells[i].second;\n            bool found = false;\n            for (const auto& cell : comp) {\n                if (cell.first == cx && cell.second == cy) {\n                    found = true;\n                    break;\n                }\n            }\n            if (found) {\n                min_x = min(min_x, mack[i].x);\n                max_x = max(max_x, mack[i].x);\n                min_y = min(min_y, mack[i].y);\n                max_y = max(max_y, mack[i].y);\n            }\n        }\n        if (min_x == max_x) {\n            min_x = max(0, min_x - 1);\n            max_x = min(MAX_COORD, max_x + 1);\n        }\n        if (min_y == max_y) {\n            min_y = max(0, min_y - 1);\n            max_y = min(MAX_COORD, max_y + 1);\n        }\n        if (min_x < max_x && min_y < max_y) {\n            int a = count_mack(min_x, max_x, min_y, max_y);\n            int b = count_sard(min_x, max_x, min_y, max_y);\n            int score = max(0, a - b + 1);\n            candidates.push_back({min_x, max_x, min_y, max_y, score});\n        }\n    }\n\n    // Union of all positive cells\n    {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (size_t i = 0; i < mack.size(); i++) {\n            int cx = mack_cells[i].first, cy = mack_cells[i].second;\n            if (weight[cx][cy] > 0) {\n                min_x = min(min_x, mack[i].x);\n                max_x = max(max_x, mack[i].x);\n                min_y = min(min_y, mack[i].y);\n                max_y = max(max_y, mack[i].y);\n            }\n        }\n        if (min_x <= max_x && min_y <= max_y) {\n            if (min_x == max_x) {\n                min_x = max(0, min_x - 1);\n                max_x = min(MAX_COORD, max_x + 1);\n            }\n            if (min_y == max_y) {\n                min_y = max(0, min_y - 1);\n                max_y = min(MAX_COORD, max_y + 1);\n            }\n            if (min_x < max_x && min_y < max_y) {\n                int a = count_mack(min_x, max_x, min_y, max_y);\n                int b = count_sard(min_x, max_x, min_y, max_y);\n                int score = max(0, a - b + 1);\n                candidates.push_back({min_x, max_x, min_y, max_y, score});\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mack(N), sard(N);\n    for (int i = 0; i < N; i++) {\n        cin >> mack[i].x >> mack[i].y;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sard[i].x >> sard[i].y;\n    }\n\n    // Precompute sorted unique coordinates for local optimization\n    vector<int> xs, ys;\n    for (const auto& p : mack) {\n        xs.push_back(p.x);\n        ys.push_back(p.y);\n    }\n    for (const auto& p : sard) {\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    vector<int> cell_sizes = {2000, 5000, 10000};\n    vector<tuple<int, int, int, int, int>> all_candidates;\n\n    for (int cell_size : cell_sizes) {\n        auto candidates = process_cell_size(cell_size, mack, sard);\n        all_candidates.insert(all_candidates.end(), candidates.begin(), candidates.end());\n    }\n\n    // Find best candidate\n    int best_score = -1;\n    int best_x1, best_x2, best_y1, best_y2;\n    for (const auto& cand : all_candidates) {\n        auto [x1, x2, y1, y2, score] = cand;\n        if (score > best_score) {\n            best_score = score;\n            best_x1 = x1;\n            best_x2 = x2;\n            best_y1 = y1;\n            best_y2 = y2;\n        }\n    }\n\n    // Apply local optimization to the best candidate\n    if (best_score != -1) {\n        local_optimize(best_x1, best_x2, best_y1, best_y2, mack, sard, xs, ys);\n        best_score = compute_score(best_x1, best_x2, best_y1, best_y2, mack, sard);\n    }\n\n    // Fallback if no candidate found\n    if (best_score == -1) {\n        best_x1 = 0;\n        best_x2 = 1;\n        best_y1 = 0;\n        best_y2 = 1;\n        best_score = 1;\n    }\n\n    // Output as rectangle (4 vertices)\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference rectangle, -1 for boundary\n};\n\n// Row-based packing (uses L direction) with skipping\nvector<Placement> generate_row_packing(const vector<int>& w, const vector<int>& h,\n                                       mt19937& rng, double alpha, double noise, double skip_threshold) {\n    int n = w.size();\n    vector<Placement> res;\n    bool shelf_exists = false;\n    int shelf_ref = -1;          // b for the current shelf\n    long long shelf_top = 0;     // y coordinate of the shelf\n    long long shelf_x = 0;       // next x in this shelf\n    long long shelf_max_h = 0;   // max height in this shelf\n    long long overall_width = 0;\n    long long overall_height = 0;\n    int max_bottom_rect = -1;    // rectangle with maximum bottom (y+h)\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        double best_cost = 1e100;\n        int best_r = 0, best_option = 0; // option 0: current shelf, 1: new shelf\n        long long best_delta_w = 0, best_delta_h = 0;\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            // Option: place in current shelf\n            if (shelf_exists) {\n                long long new_width = max(overall_width, shelf_x + wc);\n                long long new_shelf_max_h = max(shelf_max_h, (long long)hc);\n                long long new_height = max(overall_height, shelf_top + new_shelf_max_h);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = delta_w + alpha * delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 0;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n\n            // Option: start a new shelf\n            {\n                long long new_width = max(overall_width, (long long)wc);\n                long long new_height = overall_height + hc;\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = delta_w + alpha * delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 1;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n        }\n\n        // Actual increase in W+H for the chosen placement\n        long long actual_increase = best_delta_w + best_delta_h;\n        // Penalty for skipping: w_i + h_i (using original dimensions, not rotated)\n        long long penalty = w[i] + h[i];\n\n        if (actual_increase > skip_threshold * penalty) {\n            // Skip this rectangle\n            continue;\n        }\n\n        int r = best_r;\n        int wc = (r == 0 ? w[i] : h[i]);\n        int hc = (r == 0 ? h[i] : w[i]);\n\n        if (best_option == 0) { // current shelf\n            int b = shelf_ref;\n            res.push_back({i, r, 'L', b});\n\n            long long x = shelf_x;\n            long long y = shelf_top;\n            shelf_x += wc;\n            shelf_max_h = max(shelf_max_h, (long long)hc);\n            overall_width = max(overall_width, shelf_x);\n            long long new_bottom = y + hc;\n            if (new_bottom > overall_height) {\n                overall_height = new_bottom;\n                max_bottom_rect = i;\n            }\n        } else { // new shelf\n            int b = (max_bottom_rect == -1) ? -1 : max_bottom_rect;\n            res.push_back({i, r, 'L', b});\n\n            long long x = 0;\n            long long y = overall_height;\n            shelf_ref = b;\n            shelf_top = y;\n            shelf_x = wc;\n            shelf_max_h = hc;\n            overall_width = max(overall_width, (long long)wc);\n            long long new_bottom = y + hc;\n            overall_height = new_bottom;\n            max_bottom_rect = i;\n            shelf_exists = true;\n        }\n    }\n    return res;\n}\n\n// Column-based packing (uses U direction) with skipping\nvector<Placement> generate_column_packing(const vector<int>& w, const vector<int>& h,\n                                          mt19937& rng, double alpha, double noise, double skip_threshold) {\n    int n = w.size();\n    vector<Placement> res;\n    bool col_exists = false;\n    int col_ref = -1;            // b for the current column\n    long long col_left = 0;      // x coordinate of the column\n    long long col_y = 0;         // next y in this column\n    long long col_max_w = 0;     // max width in this column\n    long long overall_width = 0;\n    long long overall_height = 0;\n    int max_right_rect = -1;     // rectangle with maximum right edge (x+w)\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        double best_cost = 1e100;\n        int best_r = 0, best_option = 0; // option 0: current column, 1: new column\n        long long best_delta_w = 0, best_delta_h = 0;\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            // Option: place in current column\n            if (col_exists) {\n                long long new_col_y = col_y + hc;\n                long long new_col_max_w = max(col_max_w, (long long)wc);\n                long long new_width = max(overall_width, col_left + new_col_max_w);\n                long long new_height = max(overall_height, new_col_y);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = alpha * delta_w + delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 0;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n\n            // Option: start a new column\n            {\n                long long new_width = overall_width + wc;\n                long long new_height = max(overall_height, (long long)hc);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = alpha * delta_w + delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 1;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n        }\n\n        // Actual increase in W+H for the chosen placement\n        long long actual_increase = best_delta_w + best_delta_h;\n        // Penalty for skipping: w_i + h_i (using original dimensions, not rotated)\n        long long penalty = w[i] + h[i];\n\n        if (actual_increase > skip_threshold * penalty) {\n            // Skip this rectangle\n            continue;\n        }\n\n        int r = best_r;\n        int wc = (r == 0 ? w[i] : h[i]);\n        int hc = (r == 0 ? h[i] : w[i]);\n\n        if (best_option == 0) { // current column\n            int b = col_ref;\n            res.push_back({i, r, 'U', b});\n\n            long long x = col_left;\n            long long y = col_y;\n            col_y += hc;\n            col_max_w = max(col_max_w, (long long)wc);\n            long long old_overall_width = overall_width;\n            overall_width = max(overall_width, col_left + col_max_w);\n            overall_height = max(overall_height, col_y);\n            if (overall_width > old_overall_width) {\n                max_right_rect = i;\n            }\n        } else { // new column\n            int b = (max_right_rect == -1) ? -1 : max_right_rect;\n            res.push_back({i, r, 'U', b});\n\n            long long x = overall_width;\n            long long y = 0;\n            col_ref = b;\n            col_left = x;\n            col_y = hc;\n            col_max_w = wc;\n            overall_width = x + wc;\n            overall_height = max(overall_height, (long long)hc);\n            max_right_rect = i;\n            col_exists = true;\n        }\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<long long> sum_w(N), sum_h(N);\n    vector<int> cnt(N, 1); // start with the given noisy measurements\n    for (int i = 0; i < N; ++i) {\n        int wp, hp;\n        cin >> wp >> hp;\n        sum_w[i] = wp;\n        sum_h[i] = hp;\n    }\n\n    // Estimate true sizes from the given data (already one sample)\n    vector<int> est_w(N), est_h(N);\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n    }\n\n    // Order rectangles by estimated area to prioritize measurement\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return (long long)est_w[a] * est_h[a] > (long long)est_w[b] * est_h[b];\n    });\n\n    const int PACK_TURNS = 30; // desired number of packing attempts\n    int M = max(0, T - PACK_TURNS); // number of measurement turns\n\n    // ---------- Measurement phase ----------\n    for (int t = 0; t < M; ++t) {\n        int idx = order[t % N]; // cycle through rectangles, most important first\n        cout << \"1\\n\";\n        cout << idx << \" 0 U -1\\n\";\n        cout << flush;\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Update measurements\n        sum_w[idx] += Wp;\n        sum_h[idx] += Hp;\n        cnt[idx]++;\n        // Update estimates on the fly (optional, but we will recompute later)\n        est_w[idx] = (sum_w[idx] + cnt[idx]/2) / cnt[idx];\n        est_h[idx] = (sum_h[idx] + cnt[idx]/2) / cnt[idx];\n    }\n\n    // Recompute all estimates after measurement phase\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n        if (est_w[i] < 1) est_w[i] = 1;\n        if (est_h[i] < 1) est_h[i] = 1;\n    }\n\n    // ---------- Packing phase ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<double> alphas = {0.5, 0.8, 1.0, 1.2, 1.5, 2.0};\n    vector<double> skip_thresholds = {0.8, 1.0, 1.2, 1.5};\n    uniform_int_distribution<int> alpha_dist(0, alphas.size()-1);\n    uniform_int_distribution<int> skip_dist(0, skip_thresholds.size()-1);\n    uniform_int_distribution<int> type_dist(0, 1); // 0: row, 1: column\n    const double noise = 0.1;\n\n    for (int t = M; t < T; ++t) {\n        int type = type_dist(rng);\n        double alpha = alphas[alpha_dist(rng)];\n        double skip_threshold = skip_thresholds[skip_dist(rng)];\n\n        vector<Placement> placements;\n        if (type == 0) {\n            placements = generate_row_packing(est_w, est_h, rng, alpha, noise, skip_threshold);\n        } else {\n            placements = generate_column_packing(est_w, est_h, rng, alpha, noise, skip_threshold);\n        }\n\n        // Output the placement\n        cout << placements.size() << \"\\n\";\n        for (const auto& pl : placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << \"\\n\";\n        }\n        cout << flush;\n\n        // Read the measurement (ignored for further decisions)\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <tuple>\nusing namespace std;\n\n// Parameters for simulated annealing\nconst int MAX_ITER = 300000;\nconst double START_TEMP = 50.0;\nconst double COOLING = 0.99998;\nconst double START_PENALTY = 1.0;\nconst double END_PENALTY = 10000.0;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\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    // ---------- Greedy initial solution ----------\n    vector<int> depth(N, -1);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });\n\n    for (int v : order) {\n        if (depth[v] != -1) continue;\n        depth[v] = 0;\n        queue<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [u, d] = q.front(); q.pop();\n            if (d == H) continue;\n            for (int w : adj[u]) {\n                if (depth[w] == -1) {\n                    depth[w] = d + 1;\n                    q.emplace(w, d + 1);\n                }\n            }\n        }\n    }\n\n    // Compute initial support and unsatisfied count\n    vector<int> support(N, 0);\n    int unsatisfied_cnt = 0;\n    long long current_score = 0;\n    for (int v = 0; v < N; ++v) {\n        current_score += (long long)depth[v] * A[v];\n        if (depth[v] > 0) {\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v] - 1) {\n                    support[v]++;\n                }\n            }\n            if (support[v] == 0) unsatisfied_cnt++;\n        }\n    }\n\n    // Best feasible solution\n    long long best_score = current_score;\n    vector<int> best_depths = depth;\n\n    // ---------- Simulated Annealing ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_vertex(0, N - 1);\n    uniform_int_distribution<int> rand_depth(0, H);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    double temp = START_TEMP;\n    double penalty_weight = START_PENALTY;\n    const double penalty_inc = (END_PENALTY - START_PENALTY) / MAX_ITER;\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        int v = rand_vertex(rng);\n        int old_d = depth[v];\n        int new_d;\n\n        // Choose move type\n        double r = rand_real(rng);\n        if (r < 0.5) {\n            new_d = rand_depth(rng);\n        } else if (r < 0.8) { // try to increase\n            if (old_d < H) new_d = old_d + 1;\n            else new_d = rand_depth(rng);\n        } else { // try to decrease\n            if (old_d > 0) new_d = old_d - 1;\n            else new_d = rand_depth(rng);\n        }\n\n        if (old_d == new_d) {\n            temp *= COOLING;\n            penalty_weight += penalty_inc;\n            continue;\n        }\n\n        // Evaluate move\n        long long delta_score = (long long)(new_d - old_d) * A[v];\n        double delta_penalty = 0.0;\n        int delta_unsatisfied = 0;\n        vector<pair<int, int>> updates; // (vertex, new_support)\n\n        // Affected vertices: v and its neighbours\n        vector<int> affected = {v};\n        for (int u : adj[v]) affected.push_back(u);\n\n        for (int w : affected) {\n            int depth_w_old = depth[w];\n            int depth_w_new = (w == v) ? new_d : depth[w];\n            bool old_sat = (depth_w_old == 0) || (support[w] > 0);\n\n            // Compute new support for w\n            int new_support_w = 0;\n            for (int x : adj[w]) {\n                int depth_x = (x == v) ? new_d : depth[x];\n                if (depth_x == depth_w_new - 1) {\n                    new_support_w++;\n                }\n            }\n            bool new_sat = (depth_w_new == 0) || (new_support_w > 0);\n\n            delta_penalty += penalty_weight * ((new_sat ? 0 : A[w]) - (old_sat ? 0 : A[w]));\n            delta_unsatisfied += (new_sat ? 0 : 1) - (old_sat ? 0 : 1);\n            updates.emplace_back(w, new_support_w);\n        }\n\n        double delta_total = delta_score - delta_penalty;\n\n        if (delta_total > 0.0 || rand_real(rng) < exp(delta_total / temp)) {\n            // Accept move\n            depth[v] = new_d;\n            for (auto& [w, ns] : updates) {\n                support[w] = ns;\n            }\n            current_score += delta_score;\n            unsatisfied_cnt += delta_unsatisfied;\n\n            if (unsatisfied_cnt == 0 && current_score > best_score) {\n                best_score = current_score;\n                best_depths = depth;\n            }\n        }\n\n        temp *= COOLING;\n        penalty_weight += penalty_inc;\n    }\n\n    // ---------- Output ----------\n    // Use the best feasible solution found\n    depth = best_depths;\n\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (depth[v] == 0) continue;\n        for (int u : adj[v]) {\n            if (depth[u] == depth[v] - 1) {\n                parent[v] = u;\n                break;\n            }\n        }\n        // In a feasible solution such a neighbour must exist\n    }\n\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid apply_left_shift(vector<vector<char>>& board, int row, int l) {\n    int N = board.size();\n    vector<char> new_row(N, '.');\n    for (int j = l; j < N; ++j) {\n        if (board[row][j] != '.') new_row[j - l] = board[row][j];\n    }\n    board[row] = new_row;\n}\n\nvoid apply_right_shift(vector<vector<char>>& board, int row, int r) {\n    int N = board.size();\n    vector<char> new_row(N, '.');\n    for (int j = 0; j < N - r; ++j) {\n        if (board[row][j] != '.') new_row[j + r] = board[row][j];\n    }\n    board[row] = new_row;\n}\n\nvoid apply_up_shift(vector<vector<char>>& board, int col, int t) {\n    int N = board.size();\n    vector<char> new_col(N, '.');\n    for (int i = t; i < N; ++i) {\n        if (board[i][col] != '.') new_col[i - t] = board[i][col];\n    }\n    for (int i = 0; i < N; ++i) board[i][col] = new_col[i];\n}\n\nvoid apply_down_shift(vector<vector<char>>& board, int col, int b) {\n    int N = board.size();\n    vector<char> new_col(N, '.');\n    for (int i = 0; i < N - b; ++i) {\n        if (board[i][col] != '.') new_col[i + b] = board[i][col];\n    }\n    for (int i = 0; i < N; ++i) board[i][col] = new_col[i];\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    // initial board\n    vector<vector<char>> board(N, vector<char>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            board[i][j] = grid[i][j];\n\n    // precompute column data from initial board\n    int col_top[20], col_bottom[20];\n    bool has_top_oni[20] = {}, has_bottom_oni[20] = {};\n    int top_zone_size[20] = {}, bottom_zone_size[20] = {};\n\n    for (int j = 0; j < N; ++j) {\n        col_top[j] = N;\n        col_bottom[j] = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                col_top[j] = min(col_top[j], i);\n                col_bottom[j] = max(col_bottom[j], i);\n            }\n        }\n        // top zone\n        if (col_top[j] > 0) {\n            for (int i = 0; i < col_top[j]; ++i)\n                if (board[i][j] == 'x') { has_top_oni[j] = true; break; }\n            if (has_top_oni[j]) top_zone_size[j] = col_top[j];\n        }\n        // bottom zone\n        if (col_bottom[j] < N - 1) {\n            for (int i = col_bottom[j] + 1; i < N; ++i)\n                if (board[i][j] == 'x') { has_bottom_oni[j] = true; break; }\n            if (has_bottom_oni[j]) bottom_zone_size[j] = N - 1 - col_bottom[j];\n        }\n    }\n\n    // precompute row data from initial board\n    int row_left[20], row_right[20];\n    bool has_left_oni[20] = {}, has_right_oni[20] = {};\n    int left_zone_size[20] = {}, right_zone_size[20] = {};\n\n    for (int i = 0; i < N; ++i) {\n        row_left[i] = N;\n        row_right[i] = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                row_left[i] = min(row_left[i], j);\n                row_right[i] = max(row_right[i], j);\n            }\n        }\n        // left zone\n        if (row_left[i] > 0) {\n            for (int j = 0; j < row_left[i]; ++j)\n                if (board[i][j] == 'x') { has_left_oni[i] = true; break; }\n            if (has_left_oni[i]) left_zone_size[i] = row_left[i];\n        }\n        // right zone\n        if (row_right[i] < N - 1) {\n            for (int j = row_right[i] + 1; j < N; ++j)\n                if (board[i][j] == 'x') { has_right_oni[i] = true; break; }\n            if (has_right_oni[i]) right_zone_size[i] = N - 1 - row_right[i];\n        }\n    }\n\n    // compute total zone sizes\n    int sum_col_zones = 0, sum_row_zones = 0;\n    for (int j = 0; j < N; ++j) {\n        sum_col_zones += top_zone_size[j] + bottom_zone_size[j];\n    }\n    for (int i = 0; i < N; ++i) {\n        sum_row_zones += left_zone_size[i] + right_zone_size[i];\n    }\n\n    // estimate operations for two strategies\n    int estA = 2 * sum_col_zones + sum_row_zones; // columns double, rows single\n    int estB = 2 * sum_row_zones + sum_col_zones; // rows double, columns single\n\n    vector<string> ops;\n\n    if (estA <= estB) {\n        // Strategy A: columns double, rows single\n        // Phase 1: columns with double shifts\n        for (int j = 0; j < N; ++j) {\n            // top zone\n            if (has_top_oni[j]) {\n                int t = top_zone_size[j];\n                for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n                // remove oni in top zone\n                for (int i = 0; i < t; ++i)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n            // bottom zone\n            if (has_bottom_oni[j]) {\n                int b = bottom_zone_size[j];\n                for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n                // remove oni in bottom zone\n                for (int i = col_bottom[j] + 1; i < N; ++i)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n        }\n        // Phase 2: rows with single shifts (recompute zones)\n        for (int i = 0; i < N; ++i) {\n            // left zone\n            int left_f = N;\n            for (int j = 0; j < N; ++j)\n                if (board[i][j] == 'o') { left_f = j; break; }\n            if (left_f > 0) {\n                bool has_oni = false;\n                for (int j = 0; j < left_f; ++j)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int l = left_f;\n                    apply_left_shift(board, i, l);\n                    for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                }\n            }\n            // right zone\n            int right_f = -1;\n            for (int j = N - 1; j >= 0; --j)\n                if (board[i][j] == 'o') { right_f = j; break; }\n            if (right_f < N - 1) {\n                bool has_oni = false;\n                for (int j = right_f + 1; j < N; ++j)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int r = N - 1 - right_f;\n                    apply_right_shift(board, i, r);\n                    for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                }\n            }\n        }\n    } else {\n        // Strategy B: rows double, columns single\n        // Phase 1: rows with double shifts\n        for (int i = 0; i < N; ++i) {\n            // left zone\n            if (has_left_oni[i]) {\n                int l = left_zone_size[i];\n                for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n                // remove oni in left zone\n                for (int j = 0; j < l; ++j)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n            // right zone\n            if (has_right_oni[i]) {\n                int r = right_zone_size[i];\n                for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n                // remove oni in right zone\n                for (int j = row_right[i] + 1; j < N; ++j)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n        }\n        // Phase 2: columns with single shifts (recompute zones)\n        for (int j = 0; j < N; ++j) {\n            // top zone\n            int top_f = N;\n            for (int i = 0; i < N; ++i)\n                if (board[i][j] == 'o') { top_f = i; break; }\n            if (top_f > 0) {\n                bool has_oni = false;\n                for (int i = 0; i < top_f; ++i)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int t = top_f;\n                    apply_up_shift(board, j, t);\n                    for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                }\n            }\n            // bottom zone\n            int bottom_f = -1;\n            for (int i = N - 1; i >= 0; --i)\n                if (board[i][j] == 'o') { bottom_f = i; break; }\n            if (bottom_f < N - 1) {\n                bool has_oni = false;\n                for (int i = bottom_f + 1; i < N; ++i)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int b = N - 1 - bottom_f;\n                    apply_down_shift(board, j, b);\n                    for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                }\n            }\n        }\n    }\n\n    // output operations\n    for (const string& op : ops) cout << op << '\\n';\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint best_a[N], best_b[N];\nint best_error;\n\nint simulate(const int a[], const int b[]) {\n    int count[N] = {0};\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int t = count[current];\n        int next;\n        if (t % 2 == 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nvoid greedy_init() {\n    int count[N] = {0};\n    fill(a, a + N, -1);\n    fill(b, b + N, -1);\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int parity = count[current] % 2;\n        int next;\n        if (parity == 1) {\n            if (a[current] == -1) {\n                int best_j = 0;\n                int best_val = T[0] - count[0];\n                for (int j = 1; j < N; j++) {\n                    int val = T[j] - count[j];\n                    if (val > best_val) {\n                        best_val = val;\n                        best_j = j;\n                    }\n                }\n                a[current] = best_j;\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                int best_j = 0;\n                int best_val = T[0] - count[0];\n                for (int j = 1; j < N; j++) {\n                    int val = T[j] - count[j];\n                    if (val > best_val) {\n                        best_val = val;\n                        best_j = j;\n                    }\n                }\n                b[current] = best_j;\n            }\n            next = b[current];\n        }\n        current = next;\n    }\n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int n, l;\n    cin >> n >> l;\n    for (int i = 0; i < n; i++) {\n        cin >> T[i];\n    }\n\n    greedy_init();\n    int current_error = simulate(a, b);\n    best_error = current_error;\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis_emp(0, N - 1);\n    uniform_int_distribution<> dis_which(0, 1);\n\n    for (int iter = 0; iter < 100; iter++) {\n        int new_a[N], new_b[N];\n        memcpy(new_a, a, sizeof(a));\n        memcpy(new_b, b, sizeof(b));\n\n        int i = dis_emp(gen);\n        int which = dis_which(gen);\n        int new_val = dis_emp(gen);\n        if (which == 0) {\n            new_a[i] = new_val;\n        } else {\n            new_b[i] = new_val;\n        }\n\n        int new_error = simulate(new_a, new_b);\n        if (new_error < current_error) {\n            memcpy(a, new_a, sizeof(a));\n            memcpy(b, new_b, sizeof(b));\n            current_error = new_error;\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, new_a, sizeof(new_a));\n                memcpy(best_b, new_b, sizeof(new_b));\n            }\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n#include <functional>\n\nusing namespace std;\n\n// Query function\nvector<pair<int, int>> query(const vector<int>& cities) {\n    int l = cities.size();\n    cout << \"? \" << l;\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(min(a, b), max(a, b));\n    }\n    return edges;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Sort cities by center coordinates\n    vector<int> cities(N);\n    for (int i = 0; i < N; i++) cities[i] = i;\n    \n    sort(cities.begin(), cities.end(), [&](int i, int j) {\n        int ci = lx[i] + rx[i];\n        int cj = lx[j] + rx[j];\n        if (ci != cj) return ci < cj;\n        int di = ly[i] + ry[i];\n        int dj = ly[j] + ry[j];\n        if (di != dj) return di < dj;\n        return i < j;\n    });\n    \n    // Partition into groups\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(cities[idx++]);\n        }\n    }\n    \n    // Store edges for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    \n    // Process each group\n    for (int i = 0; i < M; i++) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n        \n        // If group size is small enough, query entire group\n        if (sz <= L) {\n            auto edges = query(groups[i]);\n            group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n        } else {\n            // Overlapping windows\n            int start = 0;\n            while (start < sz - 1) {\n                int end = min(start + L, sz);\n                vector<int> window(groups[i].begin() + start, groups[i].begin() + end);\n                if (window.size() >= 2) {\n                    auto edges = query(window);\n                    group_edges[i].insert(group_edges[i].end(), edges.begin(), edges.end());\n                }\n                start = end - 1; // Overlap by one city\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        // Output cities in group\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        \n        // Output edges\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 <string>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    vector<string> actions;\n    int cx = targets[0].first, cy = targets[0].second;\n    const int MAX_ACTIONS = 800;\n\n    for (int k = 1; k < M; ++k) {\n        int tx = targets[k].first, ty = targets[k].second;\n        while ((cx != tx || cy != ty) && actions.size() < MAX_ACTIONS) {\n            if (cx == tx) {\n                if (ty == 0 && cy > 0) {\n                    actions.push_back(\"S L\");\n                    cy = 0;\n                } else if (ty == N - 1 && cy < N - 1) {\n                    actions.push_back(\"S R\");\n                    cy = N - 1;\n                } else {\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            } else if (cy == ty) {\n                if (tx == 0 && cx > 0) {\n                    actions.push_back(\"S U\");\n                    cx = 0;\n                } else if (tx == N - 1 && cx < N - 1) {\n                    actions.push_back(\"S D\");\n                    cx = N - 1;\n                } else {\n                    if (cx < tx) {\n                        actions.push_back(\"M D\");\n                        cx++;\n                    } else {\n                        actions.push_back(\"M U\");\n                        cx--;\n                    }\n                }\n            } else {\n                // Move vertically first\n                if (cx < tx) {\n                    actions.push_back(\"M D\");\n                    cx++;\n                } else if (cx > tx) {\n                    actions.push_back(\"M U\");\n                    cx--;\n                } else {\n                    // Should not happen, but fallback\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            }\n        }\n        if (actions.size() >= MAX_ACTIONS) {\n            break;\n        }\n    }\n\n    // Output actions\n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n\n    return 0;\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <tuple>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nvector<Company> comps;\nvector<Rect> rects;\n\nbool overlaps(const Rect& r1, const Rect& r2) {\n    return !(r1.c <= r2.a || r2.c <= r1.a || r1.d <= r2.b || r2.d <= r1.b);\n}\n\nvoid rec(vector<int>& idx, int x_min, int x_max, int y_min, int y_max) {\n    if (idx.empty()) return;\n    if (idx.size() == 1) {\n        int i = idx[0];\n        int W = x_max - x_min;\n        int H = y_max - y_min;\n        int r = comps[i].r;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - r);\n        for (int w = 1; w <= W; ++w) {\n            int h1 = max(1, min(H, (int)(r / w)));\n            int h2 = max(1, min(H, (int)ceil((double)r / w)));\n            int area1 = w * h1;\n            int diff1 = abs(area1 - r);\n            if (diff1 < best_diff) {\n                best_diff = diff1;\n                best_w = w;\n                best_h = h1;\n            }\n            int area2 = w * h2;\n            int diff2 = abs(area2 - r);\n            if (diff2 < best_diff) {\n                best_diff = diff2;\n                best_w = w;\n                best_h = h2;\n            }\n        }\n        int a = max(x_min, comps[i].x - (best_w - 1));\n        a = min(a, x_max - best_w);\n        int b = max(y_min, comps[i].y - (best_h - 1));\n        b = min(b, y_max - best_h);\n        int c = a + best_w;\n        int d = b + best_h;\n        rects[i] = {a, b, c, d};\n        return;\n    }\n\n    long long total_r = 0;\n    for (int i : idx) total_r += comps[i].r;\n\n    double best_diff = 1e18;\n    int best_dir = -1; // 0 vertical, 1 horizontal\n    int best_c = -1;\n\n    // Try vertical split\n    vector<int> sorted_x = idx;\n    sort(sorted_x.begin(), sorted_x.end(), [&](int i, int j) { return comps[i].x < comps[j].x; });\n    if (comps[sorted_x.front()].x != comps[sorted_x.back()].x) {\n        vector<long long> prefix_x(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_x.size(); ++j) {\n            prefix_x[j + 1] = prefix_x[j] + comps[sorted_x[j]].r;\n        }\n        for (int p = 1; p < sorted_x.size(); ++p) {\n            long long left_sum = prefix_x[p];\n            double desired_width = (left_sum / (double)total_r) * (x_max - x_min);\n            double ideal_c = x_min + desired_width;\n            int c_min = comps[sorted_x[p - 1]].x + 1;\n            int c_max = comps[sorted_x[p]].x;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_width = c - x_min;\n            double diff = fabs(actual_width - desired_width);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 0;\n                best_c = c;\n            }\n        }\n    }\n\n    // Try horizontal split\n    vector<int> sorted_y = idx;\n    sort(sorted_y.begin(), sorted_y.end(), [&](int i, int j) { return comps[i].y < comps[j].y; });\n    if (comps[sorted_y.front()].y != comps[sorted_y.back()].y) {\n        vector<long long> prefix_y(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_y.size(); ++j) {\n            prefix_y[j + 1] = prefix_y[j] + comps[sorted_y[j]].r;\n        }\n        for (int p = 1; p < sorted_y.size(); ++p) {\n            long long left_sum = prefix_y[p];\n            double desired_height = (left_sum / (double)total_r) * (y_max - y_min);\n            double ideal_c = y_min + desired_height;\n            int c_min = comps[sorted_y[p - 1]].y + 1;\n            int c_max = comps[sorted_y[p]].y;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_height = c - y_min;\n            double diff = fabs(actual_height - desired_height);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 1;\n                best_c = c;\n            }\n        }\n    }\n\n    if (best_dir == 0) {\n        vector<int> left_idx, right_idx;\n        for (int i : idx) {\n            if (comps[i].x < best_c) left_idx.push_back(i);\n            else right_idx.push_back(i);\n        }\n        rec(left_idx, x_min, best_c, y_min, y_max);\n        rec(right_idx, best_c, x_max, y_min, y_max);\n    } else {\n        vector<int> bottom_idx, top_idx;\n        for (int i : idx) {\n            if (comps[i].y < best_c) bottom_idx.push_back(i);\n            else top_idx.push_back(i);\n        }\n        rec(bottom_idx, x_min, x_max, y_min, best_c);\n        rec(top_idx, x_min, x_max, best_c, y_max);\n    }\n}\n\nvoid compute_expansions(int i, int& L_max, int& R_max, int& D_max, int& U_max) {\n    int a = rects[i].a, b = rects[i].b, c = rects[i].c, d = rects[i].d;\n    L_max = a;\n    R_max = 10000 - c;\n    D_max = b;\n    U_max = 10000 - d;\n\n    for (int j = 0; j < rects.size(); ++j) {\n        if (i == j) continue;\n        int a2 = rects[j].a, b2 = rects[j].b, c2 = rects[j].c, d2 = rects[j].d;\n        // Check for potential horizontal overlap after vertical expansion\n        // We consider the worst-case vertical expansion: we might expand to cover the entire vertical range\n        // So we assume y-overlap is possible if the vertical ranges could overlap after expansion.\n        // To be safe, we consider if the current y-ranges are disjoint, but after expanding vertically they might overlap.\n        // Actually, we can't predict, so we conservatively assume they might overlap if the vertical gap is not too large.\n        // Instead, we use the current y-ranges and also consider that we might expand vertically.\n        // A simpler approach: for horizontal constraints, we consider rectangles that could become overlapping in y after vertical expansion.\n        // Since we don't know vertical expansion, we consider all rectangles that are not completely separated in y.\n        // That is, if there exists any vertical overlap possibility (i.e., not (d <= b2 || d2 <= b)), then we need to respect horizontal separation.\n        if (!(d <= b2 || d2 <= b)) { // current or potential y-overlap\n            if (c2 <= a) { // j is to the left\n                L_max = min(L_max, a - c2);\n            }\n            if (a2 >= c) { // j is to the right\n                R_max = min(R_max, a2 - c);\n            }\n        }\n        // Similarly for vertical constraints: consider potential horizontal overlap\n        if (!(c <= a2 || c2 <= a)) { // current or potential x-overlap\n            if (d2 <= b) { // j is below\n                D_max = min(D_max, b - d2);\n            }\n            if (b2 >= d) { // j is above\n                U_max = min(U_max, b2 - d);\n            }\n        }\n    }\n    L_max = max(0, L_max);\n    R_max = max(0, R_max);\n    D_max = max(0, D_max);\n    U_max = max(0, U_max);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    cin >> n;\n    comps.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> comps[i].x >> comps[i].y >> comps[i].r;\n    }\n\n    rects.resize(n);\n    vector<int> all_idx(n);\n    for (int i = 0; i < n; ++i) all_idx[i] = i;\n    rec(all_idx, 0, 10000, 0, 10000);\n\n    // Post-processing: expand rectangles to better match desired area\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 g(seed);\n    for (int pass = 0; pass < 20; ++pass) {\n        vector<int> order(n);\n        for (int i = 0; i < n; ++i) order[i] = i;\n        shuffle(order.begin(), order.end(), g);\n        bool changed = false;\n        for (int i : order) {\n            int w = rects[i].c - rects[i].a;\n            int h = rects[i].d - rects[i].b;\n            int s = w * h;\n            int r = comps[i].r;\n            if (s >= r) continue; // already at or above desired area\n\n            int L_max, R_max, D_max, U_max;\n            compute_expansions(i, L_max, R_max, D_max, U_max);\n            int w_max = w + L_max + R_max;\n            int h_max = h + D_max + U_max;\n            int best_w = w, best_h = h;\n            int best_diff = abs(s - r);\n            for (int w2 = w; w2 <= w_max; ++w2) {\n                double h_ideal = (double)r / w2;\n                int h1 = max(h, min(h_max, (int)floor(h_ideal)));\n                int h2 = max(h, min(h_max, (int)ceil(h_ideal)));\n                int area1 = w2 * h1;\n                int diff1 = abs(area1 - r);\n                if (diff1 < best_diff) {\n                    best_diff = diff1;\n                    best_w = w2;\n                    best_h = h1;\n                }\n                int area2 = w2 * h2;\n                int diff2 = abs(area2 - r);\n                if (diff2 < best_diff) {\n                    best_diff = diff2;\n                    best_w = w2;\n                    best_h = h2;\n                }\n            }\n            if (best_w == w && best_h == h) continue;\n\n            int need_w = best_w - w;\n            int need_h = best_h - h;\n            int L = min(need_w, L_max);\n            int R = need_w - L;\n            if (R > R_max) {\n                R = R_max;\n                L = need_w - R;\n            }\n            int D = min(need_h, D_max);\n            int U = need_h - D;\n            if (U > U_max) {\n                U = U_max;\n                D = need_h - U;\n            }\n            Rect candidate = {rects[i].a - L, rects[i].b - D, rects[i].c + R, rects[i].d + U};\n            // Check for overlap with all other rectangles\n            bool overlap = false;\n            for (int j = 0; j < n; ++j) {\n                if (i == j) continue;\n                if (overlaps(candidate, rects[j])) {\n                    overlap = true;\n                    break;\n                }\n            }\n            if (overlap) continue; // skip expansion if it causes overlap\n\n            // Also ensure the point is still contained\n            if (candidate.a > comps[i].x || candidate.c < comps[i].x + 1 ||\n                candidate.b > comps[i].y || candidate.d < comps[i].y + 1) {\n                continue;\n            }\n\n            rects[i] = candidate;\n            changed = true;\n        }\n        if (!changed) break;\n    }\n\n    for (int i = 0; i < n; ++i) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <algorithm>\n#include <string>\n#include <utility>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nstruct State {\n    int i, j;\n    int score;\n    vector<pair<int, int>> neighbors;\n    int next_idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> t(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    vector<vector<int>> p(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    int M = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            M = max(M, t[i][j] + 1);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 1.9; // seconds\n\n    int best_score = p[si][sj];\n    vector<char> best_path;\n\n    vector<char> visited(M, 0);\n    visited[t[si][sj]] = 1;\n\n    // Helper to count unvisited neighbors of (i,j)\n    auto count_unvisited = [&](int i, int j) {\n        int cnt = 0;\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 && !visited[t[ni][nj]])\n                ++cnt;\n        }\n        return cnt;\n    };\n\n    vector<State> stack;\n    vector<char> current_path;\n\n    // Initialize start state\n    vector<pair<int, int>> start_neighbors;\n    for (int d = 0; d < 4; ++d) {\n        int ni = si + di[d], nj = sj + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[t[ni][nj]])\n            start_neighbors.emplace_back(ni, nj);\n    }\n    // Sort start_neighbors by heuristic\n    vector<tuple<int, int, int, int>> temp;\n    for (auto [ni, nj] : start_neighbors) {\n        int weight = p[ni][nj] + 5 * count_unvisited(ni, nj);\n        int rand_val = uniform_int_distribution<int>(0, 1000000)(rng);\n        temp.emplace_back(ni, nj, weight, rand_val);\n    }\n    sort(temp.begin(), temp.end(), [](const auto& a, const auto& b) {\n        if (get<2>(a) != get<2>(b)) return get<2>(a) > get<2>(b);\n        return get<3>(a) > get<3>(b);\n    });\n    start_neighbors.clear();\n    for (auto [ni, nj, w, r] : temp)\n        start_neighbors.emplace_back(ni, nj);\n\n    stack.push_back({si, sj, p[si][sj], start_neighbors, 0});\n\n    while (!stack.empty() &&\n           chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < time_limit) {\n        State& top = stack.back();\n        if (top.next_idx >= (int)top.neighbors.size()) {\n            // Backtrack\n            if (t[top.i][top.j] != t[si][sj]) // do not unmark start tile\n                visited[t[top.i][top.j]] = 0;\n            stack.pop_back();\n            if (!current_path.empty())\n                current_path.pop_back();\n            continue;\n        }\n\n        // Try next neighbor\n        auto [ni, nj] = top.neighbors[top.next_idx++];\n        int tile = t[ni][nj];\n        visited[tile] = 1;\n        int new_score = top.score + p[ni][nj];\n\n        // Compute move character\n        char move;\n        if (ni == top.i - 1 && nj == top.j) move = 'U';\n        else if (ni == top.i + 1 && nj == top.j) move = 'D';\n        else if (ni == top.i && nj == top.j - 1) move = 'L';\n        else if (ni == top.i && nj == top.j + 1) move = 'R';\n        else assert(false);\n\n        current_path.push_back(move);\n        if (new_score > best_score) {\n            best_score = new_score;\n            best_path = current_path;\n        }\n\n        // Generate neighbors for the new state\n        vector<pair<int, int>> new_neighbors;\n        for (int d = 0; d < 4; ++d) {\n            int nni = ni + di[d], nnj = nj + dj[d];\n            if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && !visited[t[nni][nnj]])\n                new_neighbors.emplace_back(nni, nnj);\n        }\n\n        // Sort new_neighbors by heuristic with random tie-breaking\n        vector<tuple<int, int, int, int>> temp_new;\n        for (auto [nni, nnj] : new_neighbors) {\n            int weight = p[nni][nnj] + 5 * count_unvisited(nni, nnj);\n            int rand_val = uniform_int_distribution<int>(0, 1000000)(rng);\n            temp_new.emplace_back(nni, nnj, weight, rand_val);\n        }\n        sort(temp_new.begin(), temp_new.end(), [](const auto& a, const auto& b) {\n            if (get<2>(a) != get<2>(b)) return get<2>(a) > get<2>(b);\n            return get<3>(a) > get<3>(b);\n        });\n        new_neighbors.clear();\n        for (auto [nni, nnj, w, r] : temp_new)\n            new_neighbors.emplace_back(nni, nnj);\n\n        stack.push_back({ni, nj, new_score, new_neighbors, 0});\n    }\n\n    // Output the best path\n    for (char c : best_path)\n        cout << c;\n    cout << endl;\n\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int ROWS = 30;\nconst int COLS = 30;\nconst int MAX_QUERIES = 1000;\n\n// Direction vectors: U, D, L, R\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Edge weight estimation\nvector<vector<double>> h_est(ROWS, vector<double>(COLS-1));\nvector<vector<double>> v_est(ROWS-1, vector<double>(COLS));\nvector<vector<int>> h_count(ROWS, vector<int>(COLS-1, 0));\nvector<vector<int>> v_count(ROWS-1, vector<int>(COLS, 0));\n\n// Track row and column base values\nvector<double> row_base(ROWS, 5000.0);\nvector<double> col_base(COLS, 5000.0);\nvector<int> row_count(ROWS, 0);\nvector<int> col_count(COLS, 0);\n\n// For \u03b5-greedy exploration\nrandom_device rd;\nmt19937 gen(rd());\nuniform_real_distribution<> dis(0.0, 1.0);\n\nvoid initialize_estimates() {\n    // Initialize with row/column bases\n    for (int i = 0; i < ROWS; i++) {\n        for (int j = 0; j < COLS-1; j++) {\n            h_est[i][j] = row_base[i] + (dis(gen) - 0.5) * 200.0; // Small random variation\n        }\n    }\n    for (int i = 0; i < ROWS-1; i++) {\n        for (int j = 0; j < COLS; j++) {\n            v_est[i][j] = col_base[j] + (dis(gen) - 0.5) * 200.0; // Small random variation\n        }\n    }\n}\n\npair<string, double> find_path(int si, int sj, int ti, int tj, bool explore = false) {\n    vector<vector<double>> dist(ROWS, vector<double>(COLS, 1e18));\n    vector<vector<pair<int,int>>> parent(ROWS, vector<pair<int,int>>(COLS, {-1,-1}));\n    vector<vector<int>> dir_used(ROWS, vector<int>(COLS, -1));\n    \n    dist[si][sj] = 0;\n    using Node = pair<double, pair<int,int>>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    pq.push({0.0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, node] = pq.top(); pq.pop();\n        auto [i, j] = node;\n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n        \n        // For exploration, sometimes take random edges\n        vector<int> dirs = {0, 1, 2, 3};\n        if (explore && dis(gen) < 0.3) {\n            shuffle(dirs.begin(), dirs.end(), gen);\n        }\n        \n        for (int dir : dirs) {\n            int ni = i + dr[dir];\n            int nj = j + dc[dir];\n            if (ni < 0 || ni >= ROWS || nj < 0 || nj >= COLS) continue;\n            \n            double w;\n            if (dir == 0) w = v_est[ni][nj]; // U\n            else if (dir == 1) w = v_est[i][j]; // D\n            else if (dir == 2) w = h_est[i][nj]; // L\n            else w = h_est[i][j]; // R\n            \n            // Add small random noise during exploration\n            if (explore && dis(gen) < 0.2) {\n                w *= (0.9 + 0.2 * dis(gen));\n            }\n            \n            if (dist[ni][nj] > d + w + 1e-9) {\n                dist[ni][nj] = d + w;\n                parent[ni][nj] = {i, j};\n                dir_used[ni][nj] = dir;\n                pq.push({dist[ni][nj], {ni, nj}});\n            }\n        }\n    }\n    \n    string path;\n    double est_len = 0;\n    int ci = ti, cj = tj;\n    \n    while (ci != si || cj != sj) {\n        int dir = dir_used[ci][cj];\n        path += dir_char[dir];\n        \n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        \n        if (dir == 0) { // U\n            est_len += v_est[ci][cj];\n        } else if (dir == 1) { // D\n            est_len += v_est[pi][pj];\n        } else if (dir == 2) { // L\n            est_len += h_est[ci][cj];\n        } else { // R\n            est_len += h_est[pi][pj];\n        }\n        \n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, est_len};\n}\n\nvoid update_weights(const string& path, int si, int sj, double observed, int query_num) {\n    int i = si, j = sj;\n    double est_len = 0;\n    vector<tuple<int,int,bool>> edges;\n    \n    for (char c : path) {\n        int dir;\n        if (c == 'U') dir = 0;\n        else if (c == 'D') dir = 1;\n        else if (c == 'L') dir = 2;\n        else dir = 3;\n        \n        int ni = i + dr[dir];\n        int nj = j + dc[dir];\n        \n        if (dir == 0) {\n            edges.emplace_back(ni, nj, false);\n            est_len += v_est[ni][nj];\n        } else if (dir == 1) {\n            edges.emplace_back(i, j, false);\n            est_len += v_est[i][j];\n        } else if (dir == 2) {\n            edges.emplace_back(i, nj, true);\n            est_len += h_est[i][nj];\n        } else {\n            edges.emplace_back(i, j, true);\n            est_len += h_est[i][j];\n        }\n        \n        i = ni;\n        j = nj;\n    }\n    \n    double error = observed - est_len;\n    int edge_count = edges.size();\n    if (edge_count == 0) return;\n    \n    // More aggressive learning rate that decays slowly\n    double base_lr = 0.8 * exp(-query_num / 800.0);\n    \n    for (auto [r, c, is_horiz] : edges) {\n        int count = is_horiz ? h_count[r][c] : v_count[r][c];\n        double lr = base_lr / (1.0 + 0.05 * count);\n        \n        // Update edge weight\n        double delta = lr * error / edge_count;\n        if (is_horiz) {\n            h_est[r][c] += delta;\n            h_est[r][c] = max(1000.0, min(9000.0, h_est[r][c]));\n            h_count[r][c]++;\n            \n            // Update row base estimate with stronger influence\n            row_base[r] = 0.85 * row_base[r] + 0.15 * h_est[r][c];\n            row_count[r]++;\n        } else {\n            v_est[r][c] += delta;\n            v_est[r][c] = max(1000.0, min(9000.0, v_est[r][c]));\n            v_count[r][c]++;\n            \n            // Update column base estimate with stronger influence\n            col_base[c] = 0.85 * col_base[c] + 0.15 * v_est[r][c];\n            col_count[c]++;\n        }\n    }\n    \n    // More frequent re-initialization of poorly learned edges\n    if (query_num % 50 == 49) {\n        for (int i = 0; i < ROWS; i++) {\n            for (int j = 0; j < COLS-1; j++) {\n                if (h_count[i][j] < 3) {\n                    h_est[i][j] = row_base[i] + (dis(gen) - 0.5) * 500.0;\n                }\n            }\n        }\n        for (int i = 0; i < ROWS-1; i++) {\n            for (int j = 0; j < COLS; j++) {\n                if (v_count[i][j] < 3) {\n                    v_est[i][j] = col_base[j] + (dis(gen) - 0.5) * 500.0;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_estimates();\n    \n    for (int q = 0; q < MAX_QUERIES; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        // \u03b5-greedy: explore with probability decaying over time\n        double explore_prob = 0.3 * exp(-q / 300.0);\n        bool explore = (dis(gen) < explore_prob);\n        \n        auto [path, est_len] = find_path(si, sj, ti, tj, explore);\n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_weights(path, si, sj, observed, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    int dummy;\n    cin >> dummy >> M;\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Simple constructive approach: fill grid with random characters\n    char grid[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + rng() % 8;\n        }\n    }\n    \n    // For each string, try to ensure it's covered by adjusting the grid\n    // Process strings in random order\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    for (int idx : order) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.5) {\n            break;\n        }\n        \n        const string& s = strs[idx];\n        int L = s.size();\n        \n        // Try to find a placement that almost matches\n        int best_i = -1, best_j = -1, best_dir = -1, best_mismatches = L + 1;\n        \n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int dir = 0; dir < 2; ++dir) {\n                    int mismatches = 0;\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        if (grid[ni][nj] != s[p]) {\n                            mismatches++;\n                        }\n                    }\n                    if (mismatches < best_mismatches) {\n                        best_mismatches = mismatches;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = dir;\n                    }\n                }\n            }\n        }\n        \n        // If we found a placement with few mismatches, try to fix it\n        if (best_mismatches <= 2 && best_i != -1) {\n            // Try to fix the mismatches\n            for (int p = 0; p < L; ++p) {\n                int ni, nj;\n                if (best_dir == 0) {\n                    ni = best_i;\n                    nj = (best_j + p) % N;\n                } else {\n                    ni = (best_i + p) % N;\n                    nj = best_j;\n                }\n                if (grid[ni][nj] != s[p]) {\n                    // Change this cell to match\n                    grid[ni][nj] = s[p];\n                }\n            }\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        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<int>> cost;               // -1 for obstacle, else digit 5-9\nvector<vector<int>> row_seg, col_seg;   // segment ids for each cell\nint R_cnt, C_cnt;                       // number of row/column segments\nvector<vector<pair<int, int>>> row_cells, col_cells; // cells in each segment\nvector<unordered_map<int, pair<int, int>>> cell_of;  // (r,c) -> (i,j)\n\n// Directions: up, down, left, right\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// Linear index for a cell\ninline int to_id(int i, int j) { return i * N + j; }\ninline pair<int, int> from_id(int id) { return {id / N, id % N}; }\n\n// ----------------------------------------------------------------------\n// Dijkstra from a source, returns distances and predecessors\nstruct DijkstraResult {\n    vector<vector<int>> dist;\n    vector<vector<int>> prev;   // previous cell as linear id\n    DijkstraResult() : dist(N, vector<int>(N, INF)), prev(N, vector<int>(N, -1)) {}\n};\n\nDijkstraResult run_dijkstra(int si, int sj) {\n    DijkstraResult res;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    res.dist[si][sj] = 0;\n    pq.push({0, to_id(si, sj)});\n    while (!pq.empty()) {\n        auto [d, id] = pq.top(); pq.pop();\n        auto [i, j] = from_id(id);\n        if (d != res.dist[i][j]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (cost[ni][nj] == -1) continue;   // obstacle\n            int nd = d + cost[ni][nj];\n            if (nd < res.dist[ni][nj]) {\n                res.dist[ni][nj] = nd;\n                res.prev[ni][nj] = id;\n                pq.push({nd, to_id(ni, nj)});\n            }\n        }\n    }\n    return res;\n}\n\n// ----------------------------------------------------------------------\n// Hopcroft\u2013Karp for bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> matchL, matchR, dist;\n    HopcroftKarp(int nL, int nR) : nL(nL), nR(nR), adj(nL), matchL(nL, -1), matchR(nR, -1), dist(nL) {}\n    void addEdge(int u, int v) { adj[u].push_back(v); }\n    bool bfs() {\n        queue<int> q;\n        for (int u = 0; u < nL; ++u) {\n            if (matchL[u] == -1) {\n                dist[u] = 0;\n                q.push(u);\n            } else dist[u] = INF;\n        }\n        bool found = false;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (matchR[v] == -1) found = true;\n                else if (dist[matchR[v]] == INF) {\n                    dist[matchR[v]] = dist[u] + 1;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n        return found;\n    }\n    bool dfs(int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 || (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = INF;\n        return false;\n    }\n    int maxMatching() {\n        int matching = 0;\n        while (bfs()) {\n            for (int u = 0; u < nL; ++u)\n                if (matchL[u] == -1 && dfs(u))\n                    ++matching;\n        }\n        return matching;\n    }\n};\n\n// ----------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input --------------------------------------------------------\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    cost.assign(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                cost[i][j] = grid[i][j] - '0';\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n\n    // ----- Row segments -------------------------------------------------\n    row_seg.assign(N, vector<int>(N, -1));\n    R_cnt = 0;\n    row_cells.clear();\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (cost[i][j] != -1) {\n                int start_j = j;\n                while (j < N && cost[i][j] != -1) {\n                    row_seg[i][j] = R_cnt;\n                    ++j;\n                }\n                row_cells.emplace_back();\n                for (int k = start_j; k < j; ++k)\n                    row_cells.back().emplace_back(i, k);\n                ++R_cnt;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ----- Column segments ----------------------------------------------\n    col_seg.assign(N, vector<int>(N, -1));\n    C_cnt = 0;\n    col_cells.clear();\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (cost[i][j] != -1) {\n                int start_i = i;\n                while (i < N && cost[i][j] != -1) {\n                    col_seg[i][j] = C_cnt;\n                    ++i;\n                }\n                col_cells.emplace_back();\n                for (int k = start_i; k < i; ++k)\n                    col_cells.back().emplace_back(k, j);\n                ++C_cnt;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ----- Build full bipartite graph (row segments vs column segments) -\n    HopcroftKarp hk_full(R_cnt, C_cnt);\n    cell_of.resize(R_cnt);\n    for (auto [i, j] : road_cells) {\n        int r = row_seg[i][j];\n        int c = col_seg[i][j];\n        hk_full.addEdge(r, c);\n        cell_of[r][c] = {i, j};\n    }\n\n    // ----- Maximum matching and minimum vertex cover --------------------\n    hk_full.maxMatching();\n\n    vector<bool> visL(R_cnt, false), visR(C_cnt, false);\n    function<void(int)> dfs_cover = [&](int u) {\n        visL[u] = true;\n        for (int v : hk_full.adj[u]) {\n            if (!visR[v] && hk_full.matchL[u] != v) {\n                visR[v] = true;\n                if (hk_full.matchR[v] != -1 && !visL[hk_full.matchR[v]])\n                    dfs_cover(hk_full.matchR[v]);\n            }\n        }\n    };\n    for (int u = 0; u < R_cnt; ++u)\n        if (hk_full.matchL[u] == -1)\n            dfs_cover(u);\n\n    vector<bool> inX(R_cnt, false), inY(C_cnt, false);\n    for (int u = 0; u < R_cnt; ++u) if (!visL[u]) inX[u] = true;\n    for (int v = 0; v < C_cnt; ++v) if (visR[v]) inY[v] = true;\n\n    // ----- Remove start's own segments ----------------------------------\n    int r_start = row_seg[si][sj];\n    int c_start = col_seg[si][sj];\n    if (r_start != -1) inX[r_start] = false;\n    if (c_start != -1) inY[c_start] = false;\n\n    // ----- Collect vertices that still need covering --------------------\n    vector<int> X_list, Y_list;\n    for (int u = 0; u < R_cnt; ++u) if (inX[u]) X_list.push_back(u);\n    for (int v = 0; v < C_cnt; ++v) if (inY[v]) Y_list.push_back(v);\n    int nX = X_list.size(), nY = Y_list.size();\n\n    // If nothing left to cover, we only need to start and return.\n    if (nX == 0 && nY == 0) {\n        // Trivial tour: go to an adjacent road cell and back.\n        for (int d = 0; d < 4; ++d) {\n            int ni = si + di[d], nj = sj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && cost[ni][nj] != -1) {\n                cout << dir_char[d];\n                // Opposite direction\n                if (d == 0) cout << 'D';\n                else if (d == 1) cout << 'U';\n                else if (d == 2) cout << 'R';\n                else cout << 'L';\n                cout << endl;\n                return 0;\n            }\n        }\n        // Should not happen (graph is connected), but fallback:\n        cout << endl;\n        return 0;\n    }\n\n    // ----- Build subgraph between X_list and Y_list --------------------\n    vector<int> X_index(R_cnt, -1), Y_index(C_cnt, -1);\n    for (int i = 0; i < nX; ++i) X_index[X_list[i]] = i;\n    for (int i = 0; i < nY; ++i) Y_index[Y_list[i]] = i;\n\n    HopcroftKarp hk_sub(nX, nY);\n    vector<unordered_map<int, pair<int, int>>> sub_cell_of(nX);\n    for (int r : X_list) {\n        int i = X_index[r];\n        for (auto &[c, coord] : cell_of[r]) {\n            if (inY[c]) {\n                int j = Y_index[c];\n                hk_sub.addEdge(i, j);\n                sub_cell_of[i][j] = {r, c};\n            }\n        }\n    }\n\n    // ----- Maximum matching in subgraph ---------------------------------\n    hk_sub.maxMatching();\n\n    // ----- Precompute distances from start (for picking close cells) ----\n    auto dist_start_res = run_dijkstra(si, sj);\n    auto &dist_start = dist_start_res.dist;\n\n    // ----- Construct set S of cells to visit ----------------------------\n    set<pair<int, int>> S_set;\n\n    // Cells from the matching\n    for (int i = 0; i < nX; ++i) {\n        int j = hk_sub.matchL[i];\n        if (j != -1) {\n            auto [r, c] = sub_cell_of[i][j];\n            S_set.insert(cell_of[r][c]);\n        }\n    }\n\n    // Unmatched row segments: pick closest cell to start\n    for (int i = 0; i < nX; ++i) {\n        if (hk_sub.matchL[i] == -1) {\n            int r = X_list[i];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : row_cells[r]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    // Unmatched column segments: pick closest cell to start\n    for (int j = 0; j < nY; ++j) {\n        if (hk_sub.matchR[j] == -1) {\n            int c = Y_list[j];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : col_cells[c]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    vector<pair<int, int>> points(S_set.begin(), S_set.end());\n    int K = points.size();\n\n    // ----- All-pairs shortest paths among points and start -------------\n    int total_nodes = K + 1;          // indices 0..K-1 : points, K : start\n    vector<vector<int>> dist_mat(total_nodes, vector<int>(total_nodes, INF));\n    vector<DijkstraResult> dijkstra_res(total_nodes);\n\n    for (int idx = 0; idx < total_nodes; ++idx) {\n        int i, j;\n        if (idx < K) {\n            i = points[idx].first, j = points[idx].second;\n        } else {\n            i = si, j = sj;\n        }\n        dijkstra_res[idx] = run_dijkstra(i, j);\n        auto &res = dijkstra_res[idx];\n        for (int other = 0; other < total_nodes; ++other) {\n            int oi, oj;\n            if (other < K) {\n                oi = points[other].first, oj = points[other].second;\n            } else {\n                oi = si, oj = sj;\n            }\n            dist_mat[idx][other] = res.dist[oi][oj];\n        }\n    }\n\n    // ----- Initial tour using nearest neighbor --------------------------\n    vector<int> order;                 // order of visiting points (indices 0..K-1)\n    vector<bool> visited(K, false);\n    int cur = K;                       // start index\n    while ((int)order.size() < K) {\n        int nxt = -1;\n        int best = INF;\n        for (int j = 0; j < K; ++j) {\n            if (!visited[j] && dist_mat[cur][j] < best) {\n                best = dist_mat[cur][j];\n                nxt = j;\n            }\n        }\n        if (nxt == -1) break;          // should not happen (graph connected)\n        visited[nxt] = true;\n        order.push_back(nxt);\n        cur = nxt;\n    }\n\n    // ----- 2-opt improvement for directed TSP --------------------------\n    auto compute_order_cost = [&](const vector<int>& ord) {\n        int total = 0;\n        int cur = K;\n        for (int idx : ord) {\n            total += dist_mat[cur][idx];\n            cur = idx;\n        }\n        total += dist_mat[cur][K];\n        return total;\n    };\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < K-1; ++i) {\n            for (int j = i+1; j < K; ++j) {\n                // Nodes before and after the segment\n                int a = (i == 0) ? K : order[i-1];\n                int b = order[i];\n                int c = order[j];\n                int d = (j == K-1) ? K : order[j+1];\n\n                // Old edges\n                int old_edges = dist_mat[a][b] + dist_mat[c][d];\n                // New edges after reversal\n                int new_edges = dist_mat[a][c] + dist_mat[b][d];\n\n                // Old internal cost of segment i..j\n                int old_internal = 0;\n                for (int k = i; k < j; ++k) {\n                    old_internal += dist_mat[order[k]][order[k+1]];\n                }\n                // New internal cost after reversal\n                int new_internal = 0;\n                for (int k = j; k > i; --k) {\n                    new_internal += dist_mat[order[k]][order[k-1]];\n                }\n\n                int delta = (new_edges + new_internal) - (old_edges + old_internal);\n                if (delta < 0) {\n                    // Apply reversal\n                    reverse(order.begin() + i, order.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n\n    // ----- Build final tour (start -> order -> start) -------------------\n    vector<int> tour;\n    tour.push_back(K);                 // start\n    for (int x : order) tour.push_back(x);\n    tour.push_back(K);                 // return to start\n\n    // ----- Reconstruct the move string ---------------------------------\n    string moves;\n    for (size_t t = 0; t + 1 < tour.size(); ++t) {\n        int from_idx = tour[t], to_idx = tour[t + 1];\n        auto [fi, fj] = (from_idx < K) ? points[from_idx] : make_pair(si, sj);\n        auto [ti, tj] = (to_idx < K) ? points[to_idx] : make_pair(si, sj);\n        auto &res = dijkstra_res[from_idx];\n\n        // Backtrack from (ti,tj) to (fi,fj)\n        vector<pair<int, int>> path;\n        int ci = ti, cj = tj;\n        while (!(ci == fi && cj == fj)) {\n            path.emplace_back(ci, cj);\n            int pid = res.prev[ci][cj];\n            if (pid == -1) break;      // should not happen\n            auto [pi, pj] = from_id(pid);\n            ci = pi; cj = pj;\n        }\n        path.emplace_back(fi, fj);\n        reverse(path.begin(), path.end());\n\n        // Convert path to moves\n        for (size_t i = 0; i + 1 < path.size(); ++i) {\n            auto [cur_i, cur_j] = path[i];\n            auto [nxt_i, nxt_j] = path[i + 1];\n            for (int d = 0; d < 4; ++d) {\n                if (cur_i + di[d] == nxt_i && cur_j + dj[d] == nxt_j) {\n                    moves += dir_char[d];\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << moves << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N+1, vector<int>(K));\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n        }\n    }\n    \n    // Build dependency graph\n    vector<vector<int>> children(N+1), parents(N+1);\n    vector<int> num_children(N+1, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        children[u].push_back(v);\n        parents[v].push_back(u);\n        num_children[u]++;\n    }\n    \n    // Compute critical path length (primary priority)\n    vector<int> priority1(N+1, 1);\n    for (int i = N; i >= 1; i--) {\n        for (int child : children[i]) {\n            priority1[i] = max(priority1[i], priority1[child] + 1);\n        }\n    }\n    \n    // Secondary priority: number of tasks that depend on this one\n    vector<int> priority2(N+1, 0);\n    for (int i = 1; i <= N; i++) {\n        priority2[i] = num_children[i];\n    }\n    \n    // State tracking\n    vector<int> task_status(N+1, -1); // -1: not started, 0: in progress, 1: completed\n    vector<int> worker_task(M+1, -1); // -1: idle, else: task being worked on\n    vector<vector<int>> worker_skills(M+1, vector<int>(K, 0)); // Lower bounds\n    vector<int> worker_confidence(M+1, 0); // Number of 1-day completions\n    vector<int> start_day(N+1, -1); // Day when task was started\n    vector<int> task_difficulty(N+1, 0); // Total requirement for each task\n    \n    // Precompute task difficulty (sum of requirements)\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            task_difficulty[i] += d[i][k];\n        }\n    }\n    \n    // For randomness\n    auto seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    int day = 0;\n    while (true) {\n        day++;\n        \n        // Find available workers\n        vector<int> available_workers;\n        for (int w = 1; w <= M; w++) {\n            if (worker_task[w] == -1) {\n                available_workers.push_back(w);\n            }\n        }\n        \n        // Find ready tasks (all dependencies completed)\n        vector<int> ready_tasks;\n        for (int t = 1; t <= N; t++) {\n            if (task_status[t] != -1) continue;\n            \n            bool all_deps_completed = true;\n            for (int parent : parents[t]) {\n                if (task_status[parent] != 1) {\n                    all_deps_completed = false;\n                    break;\n                }\n            }\n            \n            if (all_deps_completed) {\n                ready_tasks.push_back(t);\n            }\n        }\n        \n        // Sort ready tasks by combined priority\n        sort(ready_tasks.begin(), ready_tasks.end(), \n             [&](int a, int b) { \n                 if (priority1[a] != priority1[b]) return priority1[a] > priority1[b];\n                 if (priority2[a] != priority2[b]) return priority2[a] > priority2[b];\n                 return task_difficulty[a] > task_difficulty[b]; // Tertiary: harder tasks first\n             });\n        \n        // Prepare assignments\n        vector<pair<int, int>> assignments;\n        vector<bool> worker_used(M+1, false);\n        \n        // Dynamic exploration: reduce exploration as day increases\n        double base_explore_prob = 0.15; // Start with higher exploration\n        double explore_prob = max(0.05, base_explore_prob * exp(-day / 400.0));\n        \n        for (int task : ready_tasks) {\n            if (available_workers.empty()) break;\n            \n            int best_worker = -1;\n            double best_score = -1e18;\n            \n            // With exploration probability, do strategic exploration\n            uniform_real_distribution<double> explore_dist(0.0, 1.0);\n            bool do_exploration = explore_dist(rng) < explore_prob;\n            \n            if (do_exploration && available_workers.size() > 1) {\n                // Strategic exploration: prefer workers with low confidence\n                vector<int> low_confidence_workers;\n                for (int w : available_workers) {\n                    if (worker_confidence[w] < 3) {\n                        low_confidence_workers.push_back(w);\n                    }\n                }\n                \n                if (!low_confidence_workers.empty()) {\n                    // Assign to a low-confidence worker\n                    uniform_int_distribution<int> worker_dist(0, low_confidence_workers.size()-1);\n                    best_worker = low_confidence_workers[worker_dist(rng)];\n                } else {\n                    // All workers have decent confidence, assign randomly\n                    uniform_int_distribution<int> worker_dist(0, available_workers.size()-1);\n                    best_worker = available_workers[worker_dist(rng)];\n                }\n            } else {\n                // Find worker that minimizes expected completion time\n                for (int w : available_workers) {\n                    if (worker_used[w]) continue;\n                    \n                    // Estimate completion time based on current skill bounds\n                    int expected_time = 1;\n                    int deficiency = 0;\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > worker_skills[w][k]) {\n                            deficiency += d[task][k] - worker_skills[w][k];\n                        }\n                    }\n                    if (deficiency > 0) {\n                        expected_time = max(1, deficiency); // Conservative estimate\n                    }\n                    \n                    // Score calculation with multiple factors\n                    double priority_score = priority1[task] * 1000.0 + priority2[task] * 10.0;\n                    double time_penalty = expected_time * 2.0;\n                    double confidence_bonus = min(worker_confidence[w] * 5.0, 50.0);\n                    \n                    // Additional bonus for tasks that match worker's strong skills\n                    double skill_match_bonus = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > 0 && worker_skills[w][k] >= d[task][k]) {\n                            skill_match_bonus += 10.0;\n                        }\n                    }\n                    \n                    // Penalty for very difficult tasks if worker has low confidence\n                    double difficulty_penalty = 0.0;\n                    if (worker_confidence[w] < 3 && task_difficulty[task] > 100) {\n                        difficulty_penalty = 20.0;\n                    }\n                    \n                    double score = priority_score - time_penalty + confidence_bonus + \n                                   skill_match_bonus - difficulty_penalty;\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_worker = w;\n                    }\n                }\n            }\n            \n            if (best_worker != -1) {\n                assignments.emplace_back(best_worker, task);\n                worker_task[best_worker] = task;\n                task_status[task] = 0;\n                start_day[task] = day;\n                \n                // Remove worker from available list\n                available_workers.erase(\n                    remove(available_workers.begin(), available_workers.end(), best_worker),\n                    available_workers.end()\n                );\n                worker_used[best_worker] = true;\n            }\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [w, t] : assignments) {\n            cout << \" \" << w << \" \" << t;\n        }\n        cout << endl;\n        cout.flush();\n        \n        // Read completion information\n        int completion_count;\n        cin >> completion_count;\n        \n        if (completion_count == -1) {\n            break; // End of simulation\n        }\n        \n        // Update based on completions\n        for (int i = 0; i < completion_count; i++) {\n            int worker;\n            cin >> worker;\n            \n            int task = worker_task[worker];\n            if (task != -1) {\n                // Check if completed in 1 day\n                if (day - start_day[task] + 1 == 1) {\n                    // Update skill lower bounds and confidence\n                    for (int k = 0; k < K; k++) {\n                        worker_skills[worker][k] = max(worker_skills[worker][k], d[task][k]);\n                    }\n                    worker_confidence[worker]++;\n                }\n                task_status[task] = 1;\n                worker_task[worker] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nPoint center = {400, 400};\n\ninline int manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Delta cost for inserting pickup X at position p and dropoff Y at position q (p <= q)\n// into the current sequence seq.\nint delta_insert(const vector<int>& seq, int p, int q, int X, int Y,\n                 const vector<vector<int>>& dist) {\n    int n = seq.size();\n    if (n == 0) {\n        // only possible: p = q = 0\n        return dist[100][X] + dist[X][Y] + dist[Y][100];\n    }\n    int A, B;\n    if (p == 0) A = 100; else A = seq[p-1];\n    if (p == n) B = 100; else B = seq[p];\n    if (q == p) {\n        // dropoff immediately after pickup\n        return dist[A][X] + dist[X][Y] + dist[Y][B] - dist[A][B];\n    } else {\n        // q > p\n        int delta = dist[A][X] + dist[X][B] - dist[A][B];\n        // Determine left and right neighbors for Y after X has been inserted\n        int left, right;\n        if (q == n) {\n            left = seq[q-1];\n            right = 100;\n        } else {\n            left = seq[q-1];\n            right = seq[q];\n        }\n        delta += dist[left][Y] + dist[Y][right] - dist[left][right];\n        return delta;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input -----\n    vector<Point> pickup(1000), dropoff(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> pickup[i].x >> pickup[i].y >> dropoff[i].x >> dropoff[i].y;\n    }\n\n    // ----- Order selection -----\n    // Use sum of distances from center to pickup and dropoff as score.\n    vector<int> order_idx(1000);\n    iota(order_idx.begin(), order_idx.end(), 0);\n    vector<int> score(1000);\n    for (int i = 0; i < 1000; ++i) {\n        score[i] = manhattan(center, pickup[i]) + manhattan(center, dropoff[i]);\n    }\n    sort(order_idx.begin(), order_idx.end(),\n         [&](int a, int b) { return score[a] < score[b]; });\n    vector<int> selected(order_idx.begin(), order_idx.begin() + 50);  // original 0\u2011based indices\n\n    // ----- Build nodes for selected orders -----\n    // nodes 0..49 : pickups, nodes 50..99 : dropoffs\n    vector<Point> nodes(100);\n    for (int i = 0; i < 50; ++i) {\n        int ord = selected[i];\n        nodes[i] = pickup[ord];\n        nodes[i + 50] = dropoff[ord];\n    }\n\n    // ----- Precompute distances (including center as node 100) -----\n    vector<Point> pts(101);\n    for (int i = 0; i < 100; ++i) pts[i] = nodes[i];\n    pts[100] = center;\n    vector<vector<int>> dist(101, vector<int>(101));\n    for (int i = 0; i < 101; ++i)\n        for (int j = 0; j < 101; ++j)\n            dist[i][j] = manhattan(pts[i], pts[j]);\n\n    // ----- Initial route construction (insertion heuristic) -----\n    vector<int> seq;                     // current sequence of node indices (0..99)\n    vector<bool> used(50, false);        // which orders are already in the route\n    int current_cost = 0;                // total travel time of current route\n\n    for (int step = 0; step < 50; ++step) {\n        int best_order = -1, best_p, best_q, best_delta = 1e9;\n        // Try every not yet used order\n        for (int i = 0; i < 50; ++i) {\n            if (used[i]) continue;\n            int X = i;          // pickup node\n            int Y = i + 50;     // dropoff node\n            int n = seq.size();\n            // Try all insertion positions p (for pickup) and q (for dropoff) with p <= q\n            for (int p = 0; p <= n; ++p) {\n                for (int q = p; q <= n; ++q) {\n                    int delta = delta_insert(seq, p, q, X, Y, dist);\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_order = i;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        // Insert the best order\n        int X = best_order;\n        int Y = best_order + 50;\n        seq.insert(seq.begin() + best_p, X);\n        seq.insert(seq.begin() + best_q + 1, Y);   // after first insertion, index shifts\n        used[best_order] = true;\n        current_cost += best_delta;\n    }\n\n    // ----- Simulated Annealing (swap moves only) -----\n    int best_cost = current_cost;\n    vector<int> best_seq = seq;\n\n    // Position of each node in the current sequence\n    vector<int> pos(100);\n    for (int i = 0; i < 100; ++i) pos[seq[i]] = i;\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> rand_pos(0, 99);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    const int MAX_ITER = 1000000;\n    double temp = 100.0;\n    const double cooling = 0.999999;   // slow cooling for many iterations\n\n    // Helper: can we swap positions a and b? (a < b)\n    auto can_swap = [&](int a, int b) -> bool {\n        int nodeA = seq[a], nodeB = seq[b];\n        // For nodeA\n        bool pickupA = (nodeA < 50);\n        int new_pos_pickupA, new_pos_dropoffA;\n        if (pickupA) {\n            new_pos_pickupA = b;\n            int dropoffA = nodeA + 50;\n            new_pos_dropoffA = (dropoffA == nodeB) ? a : pos[dropoffA];\n        } else {\n            new_pos_dropoffA = b;\n            int pickupA = nodeA - 50;\n            new_pos_pickupA = (pickupA == nodeB) ? a : pos[pickupA];\n        }\n        if (new_pos_pickupA >= new_pos_dropoffA) return false;\n\n        // For nodeB\n        bool pickupB = (nodeB < 50);\n        int new_pos_pickupB, new_pos_dropoffB;\n        if (pickupB) {\n            new_pos_pickupB = a;\n            int dropoffB = nodeB + 50;\n            new_pos_dropoffB = (dropoffB == nodeA) ? b : pos[dropoffB];\n        } else {\n            new_pos_dropoffB = a;\n            int pickupB = nodeB - 50;\n            new_pos_pickupB = (pickupB == nodeA) ? b : pos[pickupB];\n        }\n        if (new_pos_pickupB >= new_pos_dropoffB) return false;\n\n        return true;\n    };\n\n    // Helper: delta cost for swapping positions a and b (a < b)\n    auto delta_swap = [&](int a, int b) -> int {\n        int n1 = seq[a], n2 = seq[b];\n        int old_cost = 0, new_cost = 0;\n\n        auto get_node = [&](int p) -> int {\n            if (p < 0 || p >= 100) return 100;\n            return seq[p];\n        };\n\n        int lefts[4] = {a-1, a, b-1, b};\n        bool used[4] = {false};\n        for (int i = 0; i < 4; ++i) {\n            if (used[i]) continue;\n            int lp = lefts[i];\n            if (lp < -1 || lp >= 100) continue;\n            for (int j = i+1; j < 4; ++j)\n                if (lefts[j] == lp) used[j] = true;\n\n            int u = get_node(lp);\n            int v = get_node(lp+1);\n            old_cost += dist[u][v];\n\n            int u_new = (lp == a) ? n2 : (lp == b) ? n1 : u;\n            int v_new = (lp+1 == a) ? n2 : (lp+1 == b) ? n1 : v;\n            new_cost += dist[u_new][v_new];\n        }\n        return new_cost - old_cost;\n    };\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        temp *= cooling;\n        int a = rand_pos(gen);\n        int b = rand_pos(gen);\n        if (a == b) continue;\n        if (a > b) swap(a, b);\n        if (!can_swap(a, b)) continue;\n\n        int delta = delta_swap(a, b);\n        if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n            int nodeA = seq[a], nodeB = seq[b];\n            seq[a] = nodeB;\n            seq[b] = nodeA;\n            pos[nodeA] = b;\n            pos[nodeB] = a;\n            current_cost += delta;\n            if (current_cost < best_cost) {\n                best_cost = current_cost;\n                best_seq = seq;\n            }\n        }\n    }\n\n    // ----- Output -----\n    // Selected orders (convert to 1\u2011based)\n    cout << \"50\";\n    for (int idx : selected) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n\n    // Full route: center -> best_seq -> center\n    vector<Point> route;\n    route.push_back(center);\n    for (int id : best_seq) route.push_back(nodes[id]);\n    route.push_back(center);\n\n    cout << route.size();\n    for (Point p : route) cout << \" \" << p.x << \" \" << p.y;\n    cout << endl;\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, d;\n};\n\nclass DSU {\n    vector<int> parent, rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\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]) parent[x] = y;\n        else if (rank[x] > rank[y]) parent[y] = x;\n        else {\n            parent[y] = x;\n            rank[x]++;\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    int M;\n    cin >> M;\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        double dx = x[u] - x[v];\n        double dy = y[u] - y[v];\n        double dist = sqrt(dx * dx + dy * dy);\n        int d = round(dist);\n        edges[i] = {u, v, d};\n    }\n    \n    DSU dsu(N);\n    const int K = 400;  // fallback threshold\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        int u = edges[i].u, v = edges[i].v;\n        \n        // If already connected, skip\n        if (dsu.find(u) == dsu.find(v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // In the last K edges, accept any connecting edge to ensure connectivity\n        if (i >= M - K) {\n            dsu.unite(u, v);\n            cout << 1 << endl;\n            continue;\n        }\n        \n        // Find minimum d between the two components\n        int comp_u = dsu.find(u);\n        int comp_v = dsu.find(v);\n        int min_d = INT_MAX;\n        \n        for (int j = 0; j < M; j++) {\n            int a = dsu.find(edges[j].u);\n            int b = dsu.find(edges[j].v);\n            if ((a == comp_u && b == comp_v) || (a == comp_v && b == comp_u)) {\n                min_d = min(min_d, edges[j].d);\n            }\n        }\n        \n        // Accept if length is reasonable compared to best possible\n        if (l <= 2 * min_d) {\n            dsu.unite(u, v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID = 30;\n\n// Pet movement directions\nconst int dx[4] = {1, -1, 0, 0};\nconst int dy[4] = {0, 0, 1, -1};\n\nstruct Task {\n    int target_x, target_y;   // where to stand to build\n    char build_action;        // 'U','D','L','R' to build adjacent wall\n    int wall_x, wall_y;       // the wall square to build\n};\n\nint N, M;\nvector<int> pet_x, pet_y, pet_type;\nvector<int> human_x, human_y;\nbool wall[GRID+1][GRID+1] = {false};  // true if wall\n\n// Helper functions\nbool inside(int x, int y) {\n    return 1 <= x && x <= GRID && 1 <= y && y <= GRID;\n}\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; ++i)\n        if (pet_x[i] == x && pet_y[i] == y)\n            return true;\n    return false;\n}\n\nbool has_adjacent_pet(int x, int y) {\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + dx[d], ny = y + dy[d];\n        if (inside(nx, ny) && has_pet_at(nx, ny))\n            return true;\n    }\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; ++i)\n        if (human_x[i] == x && human_y[i] == y)\n            return true;\n    return false;\n}\n\nchar move_towards(int cx, int cy, int tx, int ty) {\n    if (cx == tx && cy == ty) return '.';\n    int dx = tx - cx, dy = ty - cy;\n    if (abs(dx) >= abs(dy))\n        return (dx > 0) ? 'D' : 'U';\n    else\n        return (dy > 0) ? 'R' : 'L';\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Read input\n    cin >> N;\n    pet_x.resize(N); pet_y.resize(N); pet_type.resize(N);\n    for (int i = 0; i < N; ++i)\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n    cin >> M;\n    human_x.resize(M); human_y.resize(M);\n    for (int i = 0; i < M; ++i)\n        cin >> human_x[i] >> human_y[i];\n\n    // Initial pet grid for plan selection\n    bool pet_init[GRID+1][GRID+1] = {false};\n    for (int i = 0; i < N; ++i)\n        pet_init[pet_x[i]][pet_y[i]] = true;\n\n    // Plan selection: maximize interior size\n    int best_size = -1;\n    int plan_type = -1;   // 0: horizontal only, 1: vertical only, 2: both\n    int plan_H = -1, plan_V = -1;\n    bool plan_interior_above = true;   // for horizontal\n    bool plan_interior_left = true;    // for vertical\n    int plan_corner = -1;              // for both (0:TL,1:TR,2:BL,3:BR)\n\n    // ---------- One\u2011wall horizontal ----------\n    for (int H = 2; H <= GRID; ++H) {\n        // Wall squares (H, 1..30)\n        bool wall_ok = true;\n        for (int y = 1; y <= GRID; ++y)\n            if (pet_init[H][y]) { wall_ok = false; break; }\n        if (!wall_ok) continue;\n\n        // Interior above\n        bool interior_ok = true;\n        for (int x = 1; x < H; ++x)\n            for (int y = 1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = (H - 1) * GRID;\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 0;\n                plan_H = H;\n                plan_interior_above = true;\n            }\n        }\n\n        // Interior below\n        interior_ok = true;\n        for (int x = H+1; x <= GRID; ++x)\n            for (int y = 1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = (GRID - H) * GRID;\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 0;\n                plan_H = H;\n                plan_interior_above = false;\n            }\n        }\n    }\n\n    // ---------- One\u2011wall vertical ----------\n    for (int V = 2; V <= GRID; ++V) {\n        // Wall squares (1..30, V)\n        bool wall_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            if (pet_init[x][V]) { wall_ok = false; break; }\n        if (!wall_ok) continue;\n\n        // Interior left\n        bool interior_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            for (int y = 1; y < V; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = GRID * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 1;\n                plan_V = V;\n                plan_interior_left = true;\n            }\n        }\n\n        // Interior right\n        interior_ok = true;\n        for (int x = 1; x <= GRID; ++x)\n            for (int y = V+1; y <= GRID; ++y)\n                if (pet_init[x][y]) { interior_ok = false; break; }\n        if (interior_ok) {\n            int size = GRID * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 1;\n                plan_V = V;\n                plan_interior_left = false;\n            }\n        }\n    }\n\n    // ---------- Two\u2011wall corners ----------\n    // Corner 0: top\u2011left\n    for (int H = 2; H <= GRID; ++H) {\n        for (int V = 2; V <= GRID; ++V) {\n            // Wall: (H, 1..V) and (1..H, V)\n            bool wall_ok = true;\n            for (int y = 1; y <= V; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = 1; x <= H; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: 1..H-1 , 1..V-1\n            bool interior_ok = true;\n            for (int x = 1; x < H; ++x)\n                for (int y = 1; y < V; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (H - 1) * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 0;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 1: top\u2011right\n    for (int H = 2; H <= GRID; ++H) {\n        for (int V = 1; V <= GRID-1; ++V) {\n            // Wall: (H, V..30) and (1..H, V)\n            bool wall_ok = true;\n            for (int y = V; y <= GRID; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = 1; x <= H; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: 1..H-1 , V+1..30\n            bool interior_ok = true;\n            for (int x = 1; x < H; ++x)\n                for (int y = V+1; y <= GRID; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (H - 1) * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 1;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 2: bottom\u2011left\n    for (int H = 1; H <= GRID-1; ++H) {\n        for (int V = 2; V <= GRID; ++V) {\n            // Wall: (H, 1..V) and (H..30, V)\n            bool wall_ok = true;\n            for (int y = 1; y <= V; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = H; x <= GRID; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: H+1..30 , 1..V-1\n            bool interior_ok = true;\n            for (int x = H+1; x <= GRID; ++x)\n                for (int y = 1; y < V; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (GRID - H) * (V - 1);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 2;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // Corner 3: bottom\u2011right\n    for (int H = 1; H <= GRID-1; ++H) {\n        for (int V = 1; V <= GRID-1; ++V) {\n            // Wall: (H, V..30) and (H..30, V)\n            bool wall_ok = true;\n            for (int y = V; y <= GRID; ++y)\n                if (pet_init[H][y]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            for (int x = H; x <= GRID; ++x)\n                if (pet_init[x][V]) { wall_ok = false; break; }\n            if (!wall_ok) continue;\n            // Interior: H+1..30 , V+1..30\n            bool interior_ok = true;\n            for (int x = H+1; x <= GRID; ++x)\n                for (int y = V+1; y <= GRID; ++y)\n                    if (pet_init[x][y]) { interior_ok = false; break; }\n            if (!interior_ok) continue;\n            int size = (GRID - H) * (GRID - V);\n            if (size > best_size) {\n                best_size = size;\n                plan_type = 2;\n                plan_corner = 3;\n                plan_H = H;\n                plan_V = V;\n            }\n        }\n    }\n\n    // ---------- Prepare tasks and roles ----------\n    vector<Task> hor_tasks, ver_tasks;\n    int gather_x = 1, gather_y = 1;   // default, will be overwritten\n    vector<int> role(M, 0);           // 0: normal, 1: horizontal builder, 2: vertical builder\n\n    if (plan_type == 0) { // horizontal only\n        if (plan_interior_above) {\n            gather_x = 1; gather_y = 1;\n            for (int y = 1; y <= GRID; ++y)\n                hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n        } else {\n            gather_x = GRID; gather_y = 1;\n            for (int y = 1; y <= GRID; ++y)\n                hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n        }\n        if (M > 0) role[0] = 1;\n    }\n    else if (plan_type == 1) { // vertical only\n        if (plan_interior_left) {\n            gather_x = 1; gather_y = 1;\n            for (int x = 1; x <= GRID; ++x)\n                ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n        } else {\n            gather_x = 1; gather_y = GRID;\n            for (int x = 1; x <= GRID; ++x)\n                ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n        }\n        if (M > 0) role[0] = 2;\n    }\n    else if (plan_type == 2) { // both walls\n        switch (plan_corner) {\n            case 0: // top\u2011left\n                gather_x = 1; gather_y = 1;\n                for (int y = 1; y <= plan_V; ++y)\n                    hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n                for (int x = 1; x < plan_H; ++x)\n                    ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n                break;\n            case 1: // top\u2011right\n                gather_x = 1; gather_y = GRID;\n                for (int y = plan_V; y <= GRID; ++y)\n                    hor_tasks.push_back({plan_H-1, y, 'D', plan_H, y});\n                for (int x = 1; x < plan_H; ++x)\n                    ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n                break;\n            case 2: // bottom\u2011left\n                gather_x = GRID; gather_y = 1;\n                for (int y = 1; y <= plan_V; ++y)\n                    hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n                for (int x = plan_H; x <= GRID; ++x)\n                    ver_tasks.push_back({x, plan_V-1, 'R', x, plan_V});\n                break;\n            case 3: // bottom\u2011right\n                gather_x = GRID; gather_y = GRID;\n                for (int y = plan_V; y <= GRID; ++y)\n                    hor_tasks.push_back({plan_H+1, y, 'U', plan_H, y});\n                for (int x = plan_H; x <= GRID; ++x)\n                    ver_tasks.push_back({x, plan_V+1, 'L', x, plan_V});\n                break;\n        }\n        if (M > 0) role[0] = 1;\n        if (M > 1) role[1] = 2;\n    }\n\n    // Builder indices\n    int hor_idx = 0, ver_idx = 0;\n\n    // ---------- Simulation ----------\n    for (int turn = 0; turn < 300; ++turn) {\n        vector<char> actions(M, '.');\n\n        for (int i = 0; i < M; ++i) {\n            if (role[i] == 0) { // normal\n                actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n            }\n            else if (role[i] == 1) { // horizontal builder\n                if (hor_idx >= (int)hor_tasks.size()) {\n                    // done \u2013 go to gathering point\n                    actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n                } else {\n                    Task &t = hor_tasks[hor_idx];\n                    if (human_x[i] == t.target_x && human_y[i] == t.target_y) {\n                        // try to build\n                        if (!wall[t.wall_x][t.wall_y] &&\n                            !has_pet_at(t.wall_x, t.wall_y) &&\n                            !has_human_at(t.wall_x, t.wall_y) &&\n                            !has_adjacent_pet(t.wall_x, t.wall_y)) {\n                            actions[i] = t.build_action;\n                            wall[t.wall_x][t.wall_y] = true;\n                            ++hor_idx;\n                        } else {\n                            actions[i] = '.';\n                        }\n                    } else {\n                        actions[i] = move_towards(human_x[i], human_y[i], t.target_x, t.target_y);\n                    }\n                }\n            }\n            else if (role[i] == 2) { // vertical builder\n                if (ver_idx >= (int)ver_tasks.size()) {\n                    actions[i] = move_towards(human_x[i], human_y[i], gather_x, gather_y);\n                } else {\n                    Task &t = ver_tasks[ver_idx];\n                    if (human_x[i] == t.target_x && human_y[i] == t.target_y) {\n                        if (!wall[t.wall_x][t.wall_y] &&\n                            !has_pet_at(t.wall_x, t.wall_y) &&\n                            !has_human_at(t.wall_x, t.wall_y) &&\n                            !has_adjacent_pet(t.wall_x, t.wall_y)) {\n                            actions[i] = t.build_action;\n                            wall[t.wall_x][t.wall_y] = true;\n                            ++ver_idx;\n                        } else {\n                            actions[i] = '.';\n                        }\n                    } else {\n                        actions[i] = move_towards(human_x[i], human_y[i], t.target_x, t.target_y);\n                    }\n                }\n            }\n        }\n\n        // Output actions\n        for (char c : actions) cout << c;\n        cout << endl;\n        cout.flush();\n\n        // Update human positions according to actions\n        for (int i = 0; i < M; ++i) {\n            if (actions[i] == 'U') human_x[i]--;\n            else if (actions[i] == 'D') human_x[i]++;\n            else if (actions[i] == 'L') human_y[i]--;\n            else if (actions[i] == 'R') human_y[i]++;\n            // build or '.' \u2192 no movement\n        }\n\n        // Read pet movements\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20, W = 20;\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint si, sj, ti, tj;\ndouble p;\nint h[H][W - 1]; // horizontal walls: between (i,j) and (i,j+1)\nint v[H - 1][W]; // vertical walls: between (i,j) and (i+1,j)\n\nstruct MoveData {\n    double stay;       // probability to stay in the same cell\n    double move;       // probability to move to neighbour (0 if blocked)\n    int ni, nj;        // neighbour coordinates (valid only if move>0)\n    bool is_target;    // does moving lead directly to the office?\n};\nMoveData move_info[H][W][4];\nint dir_to_idx[256];\n\n// Precompute transition data for every cell and direction.\nvoid precompute_move_info() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            for (int d = 0; d < 4; ++d) {\n                auto& data = move_info[i][j][d];\n                data.ni = i + di[d];\n                data.nj = j + dj[d];\n                bool blocked = false;\n                if (d == 0) { // U\n                    if (i == 0) blocked = true;\n                    else if (v[i - 1][j] == 1) blocked = true;\n                } else if (d == 1) { // D\n                    if (i == H - 1) blocked = true;\n                    else if (v[i][j] == 1) blocked = true;\n                } else if (d == 2) { // L\n                    if (j == 0) blocked = true;\n                    else if (h[i][j - 1] == 1) blocked = true;\n                } else { // R\n                    if (j == W - 1) blocked = true;\n                    else if (h[i][j] == 1) blocked = true;\n                }\n                data.stay = p + (1 - p) * blocked;\n                data.move = blocked ? 0.0 : (1 - p);\n                data.is_target = (!blocked && data.ni == ti && data.nj == tj);\n            }\n        }\n    }\n    dir_to_idx['U'] = 0;\n    dir_to_idx['D'] = 1;\n    dir_to_idx['L'] = 2;\n    dir_to_idx['R'] = 3;\n}\n\n// Compute expected score for a given command string.\ndouble compute_score(const string& s) {\n    double a[20][20], b[20][20];\n    double (*cur)[20] = a;\n    double (*nxt)[20] = b;\n    memset(a, 0, sizeof(a));\n    cur[si][sj] = 1.0;\n    double score = 0.0;\n    int L = s.size();\n    for (int step = 0; step < L; ++step) {\n        int d = dir_to_idx[s[step]];\n        memset(nxt, 0, sizeof(a));\n        for (int i = 0; i < H; ++i) {\n            for (int j = 0; j < W; ++j) {\n                double prob = cur[i][j];\n                if (prob == 0.0) continue;\n                const MoveData& data = move_info[i][j][d];\n                nxt[i][j] += prob * data.stay;\n                if (data.move > 0) {\n                    if (data.is_target) {\n                        score += (401 - (step + 1)) * prob * data.move;\n                    } else {\n                        nxt[data.ni][data.nj] += prob * data.move;\n                    }\n                }\n            }\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\n// BFS to find a shortest valid path (ignoring forgetting).\nstring bfs_path() {\n    queue<pair<int, int>> q;\n    vector<vector<bool>> visited(H, vector<bool>(W, false));\n    vector<vector<int>> parent_i(H, vector<int>(W, -1));\n    vector<vector<int>> parent_j(H, vector<int>(W, -1));\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            const MoveData& data = move_info[i][j][d];\n            if (data.move > 0) { // move allowed\n                int ni = data.ni, nj = data.nj;\n                if (!visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent_i[ni][nj] = i;\n                    parent_j[ni][nj] = j;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n    // Reconstruct path from target to start.\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int pi = parent_i[ci][cj];\n        int pj = parent_j[ci][cj];\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Repeat a string to reach length max_len (truncate if longer).\nstring repeat_to_length(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U'); // fallback, should not happen\n    string result;\n    while (result.size() < max_len) {\n        result += s;\n    }\n    result.resize(max_len);\n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj >> ti >> tj >> p;\n    for (int i = 0; i < 20; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 19; ++j) h[i][j] = line[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 20; ++j) v[i][j] = line[j] - '0';\n    }\n\n    precompute_move_info();\n\n    string bfs_str = bfs_path();\n    double bfs_score = compute_score(bfs_str);\n    string current = bfs_str;\n    double current_score = bfs_score;\n\n    // Try doubled path if it fits.\n    if (bfs_str.size() * 2 <= 200) {\n        string doubled = bfs_str + bfs_str;\n        double doubled_score = compute_score(doubled);\n        if (doubled_score > current_score) {\n            current = doubled;\n            current_score = doubled_score;\n        }\n    }\n\n    // Try repeated path up to length 200.\n    string repeated = repeat_to_length(bfs_str, 200);\n    double repeated_score = compute_score(repeated);\n    if (repeated_score > current_score) {\n        current = repeated;\n        current_score = repeated_score;\n    }\n\n    string best = current;\n    double best_score = current_score;\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    auto rand_index = [&](int n) -> int {\n        return uniform_int_distribution<int>(0, n - 1)(rng);\n    };\n\n    const double time_limit = 1.98; // seconds\n    auto start_time = chrono::steady_clock::now();\n\n    double start_temp = 1.0;\n    double end_temp = 1e-4;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        double progress = elapsed / time_limit;\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        // Generate neighbour solution\n        string neighbour = current;\n        int L = neighbour.size();\n\n        // Adjust operation probabilities based on current score.\n        double insert_prob, delete_prob, replace_prob, swap_prob;\n        if (current_score < 1000) {\n            insert_prob = 0.5;\n            delete_prob = 0.1;\n            replace_prob = 0.2;\n            swap_prob = 0.2;\n        } else {\n            insert_prob = 0.25;\n            delete_prob = 0.25;\n            replace_prob = 0.35;\n            swap_prob = 0.15;\n        }\n\n        double op = uniform(rng);\n        if (op < replace_prob) { // replace one character\n            int pos = rand_index(L);\n            char old = neighbour[pos];\n            char newc;\n            do { newc = dir_chars[rand_dir(rng)]; } while (newc == old);\n            neighbour[pos] = newc;\n        } else if (op < replace_prob + insert_prob && L < 200) { // insert a character\n            int pos = rand_index(L + 1); // 0 .. L\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour.insert(neighbour.begin() + pos, newc);\n        } else if (op < replace_prob + insert_prob + delete_prob && L > 1) { // delete\n            int pos = rand_index(L);\n            neighbour.erase(neighbour.begin() + pos);\n        } else if (L >= 2) { // swap adjacent\n            int pos = rand_index(L - 1);\n            swap(neighbour[pos], neighbour[pos + 1]);\n        } else {\n            // fallback to replace\n            int pos = rand_index(L);\n            char old = neighbour[pos];\n            char newc;\n            do { newc = dir_chars[rand_dir(rng)]; } while (newc == old);\n            neighbour[pos] = newc;\n        }\n\n        double new_score = compute_score(neighbour);\n        double delta = new_score - current_score;\n        if (delta > 0 || uniform(rng) < exp(delta / T)) {\n            current = move(neighbour);\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best = current;\n            }\n        }\n    }\n\n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cstring>\n#include <cmath>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Predefined connection table from problem statement\nconst int 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 grid[N][N];\nint conn[N][N][4]; // Internal connections for each tile\n\n// Compute internal connections based on rotations\nvoid compute_conn(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            int r = rotations[i][j];\n            for (int d = 0; d < 4; d++) {\n                int d0 = (d - r + 4) % 4;\n                if (to[type][d0] == -1) {\n                    conn[i][j][d] = -1;\n                } else {\n                    conn[i][j][d] = (to[type][d0] + r) % 4;\n                }\n            }\n        }\n    }\n}\n\n// Optimized cycle detection using BFS from each half-edge\nint compute_score(int rotations[][N]) {\n    compute_conn(rotations);\n    vector<bool> visited(N*N*4, false);\n    vector<int> cycle_lengths;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                int start_id = (i*N + j)*4 + d;\n                if (conn[i][j][d] != -1 && !visited[start_id]) {\n                    // Use BFS to find the component\n                    queue<int> q;\n                    q.push(start_id);\n                    visited[start_id] = true;\n                    int count = 0;\n                    bool is_cycle = true;\n                    vector<int> component;\n                    \n                    while (!q.empty()) {\n                        int cur_id = q.front();\n                        q.pop();\n                        component.push_back(cur_id);\n                        count++;\n                        \n                        int tile_id = cur_id / 4;\n                        int ci = tile_id / N;\n                        int cj = tile_id % N;\n                        int cd = cur_id % 4;\n                        \n                        // Check internal connection\n                        int d2 = conn[ci][cj][cd];\n                        if (d2 != -1) {\n                            int internal_id = (ci*N + cj)*4 + d2;\n                            if (!visited[internal_id]) {\n                                visited[internal_id] = true;\n                                q.push(internal_id);\n                            }\n                        }\n                        \n                        // Check external connection\n                        int ni = ci + di[cd];\n                        int nj = cj + dj[cd];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            int opp_d = (cd + 2) % 4;\n                            if (conn[ni][nj][opp_d] != -1) {\n                                int external_id = (ni*N + nj)*4 + opp_d;\n                                if (!visited[external_id]) {\n                                    visited[external_id] = true;\n                                    q.push(external_id);\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Check if it's a cycle: all nodes should have degree 2\n                    for (int id : component) {\n                        int tile_id = id / 4;\n                        int ci = tile_id / N;\n                        int cj = tile_id % N;\n                        int cd = id % 4;\n                        \n                        int degree = 0;\n                        // Internal connection\n                        if (conn[ci][cj][cd] != -1) degree++;\n                        // External connection\n                        int ni = ci + di[cd];\n                        int nj = cj + dj[cd];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n                            conn[ni][nj][(cd+2)%4] != -1) {\n                            degree++;\n                        }\n                        \n                        if (degree != 2) {\n                            is_cycle = false;\n                            break;\n                        }\n                    }\n                    \n                    if (is_cycle && count >= 4) { // Minimum cycle has 2 edges = 4 half-edges\n                        cycle_lengths.push_back(count / 2);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Sort and get top two\n    if (cycle_lengths.empty()) return 0;\n    sort(cycle_lengths.rbegin(), cycle_lengths.rend());\n    int L1 = cycle_lengths[0];\n    int L2 = cycle_lengths.size() > 1 ? cycle_lengths[1] : 0;\n    return L1 * L2;\n}\n\n// Generate a good initial solution by aligning straight tiles\nvoid generate_initial_solution(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            if (type == 6) { // Horizontal straight\n                // Try to align with left/right neighbors\n                rotations[i][j] = 0; // Default horizontal\n                // Check if we should rotate to vertical\n                bool left_ok = (j > 0) && (grid[i][j-1] == 7);\n                bool right_ok = (j < N-1) && (grid[i][j+1] == 7);\n                if (left_ok || right_ok) {\n                    rotations[i][j] = 1; // Rotate to vertical\n                }\n            } else if (type == 7) { // Vertical straight\n                rotations[i][j] = 0; // Default vertical\n                // Check if we should rotate to horizontal\n                bool up_ok = (i > 0) && (grid[i-1][j] == 6);\n                bool down_ok = (i < N-1) && (grid[i+1][j] == 6);\n                if (up_ok || down_ok) {\n                    rotations[i][j] = 1; // Rotate to horizontal\n                }\n            } else if (type >= 4 && type <= 5) { // Double curves\n                // Random for now\n                rotations[i][j] = rand() % 4;\n            } else { // Single curves\n                // Try to connect to neighbors\n                rotations[i][j] = rand() % 4;\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[j] - '0';\n        }\n    }\n\n    // Initialize random number generators\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> tile_dist(0, N*N-1);\n    uniform_int_distribution<> rot_dist(0, 3);\n    uniform_real_distribution<> prob_dist(0.0, 1.0);\n\n    // Start with a better initial solution\n    int current_rotations[N][N];\n    generate_initial_solution(current_rotations);\n    int current_score = compute_score(current_rotations);\n    \n    // Keep track of best solution\n    int best_rotations[N][N];\n    memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n    int best_score = current_score;\n\n    // Simulated annealing parameters - more aggressive\n    double temperature = 20.0;\n    double cooling_rate = 0.9999;\n    int sa_steps = 20000;\n    int no_improve_count = 0;\n    int restart_threshold = 2000;\n\n    // Simulated annealing with restarts\n    for (int step = 0; step < sa_steps; step++) {\n        // If stuck, restart from best solution\n        if (no_improve_count > restart_threshold) {\n            memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n            current_score = best_score;\n            temperature = 20.0; // Reset temperature\n            no_improve_count = 0;\n        }\n\n        // Pick a random tile and a new rotation\n        int tile_idx = tile_dist(gen);\n        int i = tile_idx / N;\n        int j = tile_idx % N;\n        int old_rot = current_rotations[i][j];\n        int new_rot = rot_dist(gen);\n        \n        // Skip if same rotation\n        if (new_rot == old_rot) {\n            continue;\n        }\n\n        // Apply change\n        current_rotations[i][j] = new_rot;\n        int new_score = compute_score(current_rotations);\n\n        // Decide whether to accept the new solution\n        int score_diff = new_score - current_score;\n        if (score_diff > 0 || \n            prob_dist(gen) < exp(score_diff / temperature)) {\n            // Accept\n            current_score = new_score;\n            no_improve_count = 0;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n            }\n        } else {\n            // Reject - revert change\n            current_rotations[i][j] = old_rot;\n            no_improve_count++;\n        }\n\n        // Cool down\n        temperature *= cooling_rate;\n    }\n\n    // Final intensive greedy search on promising tiles\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    current_score = best_score;\n    \n    // Focus on tiles that are part of cycles or could connect cycles\n    for (int iter = 0; iter < 3; iter++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int original = current_rotations[i][j];\n                int best_local_score = current_score;\n                int best_local_rot = original;\n                \n                for (int r = 0; r < 4; r++) {\n                    if (r == original) continue;\n                    current_rotations[i][j] = r;\n                    int new_score = compute_score(current_rotations);\n                    if (new_score > best_local_score) {\n                        best_local_score = new_score;\n                        best_local_rot = r;\n                    }\n                }\n                \n                current_rotations[i][j] = best_local_rot;\n                if (best_local_score > current_score) {\n                    current_score = best_local_score;\n                    if (current_score > best_score) {\n                        best_score = current_score;\n                        memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n                    }\n                }\n            }\n        }\n    }\n\n    // Output best solution found\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <cstring>\n#include <tuple>\n\nusing namespace std;\n\n// Direction arrays: L, R, U, D\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'L', 'R', 'U', 'D'};\nconst int dir_bit[4] = {1, 4, 2, 8};  // L=1, R=4, U=2, D=8\nconst int opposite[4] = {1, 0, 3, 2};  // opposite directions\n\nint N, T;\nvector<vector<int>> board;\nint empty_r, empty_c;\n\n// Check if moving in direction d is valid\nbool can_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    // Must be within bounds and must contain a tile (non-zero)\n    return nr >= 0 && nr < N && nc >= 0 && nc < N && board[nr][nc] != 0;\n}\n\n// Execute move in direction d\nvoid make_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    empty_r = nr;\n    empty_c = nc;\n}\n\n// Calculate size of largest tree and count components\npair<int, int> analyze_board() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree_size = 0;\n    int total_components = 0;\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]) {\n                total_components++;\n                // BFS to find component\n                vector<pair<int,int>> component;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [r, c] = q.front();\n                    q.pop();\n                    component.push_back({r, c});\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dy[d];\n                        int nc = c + dx[d];\n                        if (nr >= 0 && nr < N && nc >= 0 && nc < N && \n                            board[nr][nc] != 0 && !visited[nr][nc]) {\n                            // Check if connection exists\n                            int curr_bit = dir_bit[d];\n                            int next_bit = dir_bit[opposite[d]];\n                            if ((board[r][c] & curr_bit) && (board[nr][nc] & next_bit)) {\n                                visited[nr][nc] = true;\n                                q.push({nr, nc});\n                            }\n                        }\n                    }\n                }\n                \n                // Count edges in component\n                int V = component.size();\n                int E = 0;\n                vector<vector<bool>> in_comp(N, vector<bool>(N, false));\n                for (auto [r, c] : component) {\n                    in_comp[r][c] = true;\n                }\n                \n                for (auto [r, c] : component) {\n                    // Check right neighbor\n                    if (c + 1 < N && in_comp[r][c+1]) {\n                        if ((board[r][c] & 4) && (board[r][c+1] & 1)) {\n                            E++;\n                        }\n                    }\n                    // Check down neighbor\n                    if (r + 1 < N && in_comp[r+1][c]) {\n                        if ((board[r][c] & 8) && (board[r+1][c] & 2)) {\n                            E++;\n                        }\n                    }\n                }\n                \n                // Check if this component is a tree (connected and acyclic)\n                if (E == V - 1) {\n                    max_tree_size = max(max_tree_size, V);\n                }\n            }\n        }\n    }\n    \n    return {max_tree_size, total_components};\n}\n\n// Evaluate a move: returns (tree_size, components, benefit_score)\ntuple<int, int, int> evaluate_move(int d) {\n    // Simulate move\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    int saved_er = empty_r, saved_ec = empty_c;\n    empty_r = nr;\n    empty_c = nc;\n    \n    auto [tree_size, components] = analyze_board();\n    \n    // Calculate a benefit score: higher is better\n    // We want to maximize tree size and minimize number of components\n    int benefit_score = tree_size * 1000 - components * 10;\n    \n    // Restore board\n    empty_r = saved_er;\n    empty_c = saved_ec;\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    \n    return {tree_size, components, benefit_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.resize(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] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_r = i;\n                empty_c = j;\n            }\n        }\n    }\n    \n    string moves;\n    auto [current_max, current_components] = analyze_board();\n    \n    for (int step = 0; step < T; step++) {\n        if (current_max == N * N - 1) {\n            break;  // Already achieved full tree\n        }\n        \n        int best_d = -1;\n        int best_tree_size = current_max;\n        int best_components = current_components;\n        int best_score = -1000000;\n        \n        // Try all possible moves\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(d)) continue;\n            \n            auto [tree_size, components, score] = evaluate_move(d);\n            \n            // Update best move based on score\n            if (score > best_score || \n                (score == best_score && tree_size > best_tree_size)) {\n                best_score = score;\n                best_tree_size = tree_size;\n                best_components = components;\n                best_d = d;\n            }\n        }\n        \n        // If no move found, choose any valid move that minimizes components\n        if (best_d == -1) {\n            for (int d = 0; d < 4; d++) {\n                if (!can_move(d)) continue;\n                \n                auto [tree_size, components, score] = evaluate_move(d);\n                \n                if (best_d == -1 || components < best_components) {\n                    best_components = components;\n                    best_d = d;\n                }\n            }\n            if (best_d == -1) {\n                // No valid moves? This shouldn't happen, but break to be safe\n                break;\n            }\n        }\n        \n        // Execute best move\n        make_move(best_d);\n        moves += dir_char[best_d];\n        tie(current_max, current_components) = analyze_board();\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nstruct Pt { ll x, y; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K = 100;\n    cin >> N >> K;\n    int a[11] = {};\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    vector<Pt> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n\n    vector<int> sx(N), sy(N);\n    iota(sx.begin(), sx.end(), 0);\n    iota(sy.begin(), sy.end(), 0);\n    sort(sx.begin(), sx.end(), [&](int i, int j) {\n        return pts[i].x < pts[j].x || (pts[i].x == pts[j].x && pts[i].y < pts[j].y);\n    });\n    sort(sy.begin(), sy.end(), [&](int i, int j) {\n        return pts[i].y < pts[j].y || (pts[i].y == pts[j].y && pts[i].x < pts[j].x);\n    });\n\n    auto calc = [&](const vector<array<ll,4>>& L) {\n        int cnt[11] = {};\n        for (int i = 0; i < N; i++) {\n            int s = 0;\n            for (auto& l : L) {\n                ll d = (l[2]-l[0])*(pts[i].y-l[1]) - (l[3]-l[1])*(pts[i].x-l[0]);\n                if (d < 0) s |= 1; else if (d > 0) s |= 2;\n            }\n            if (s) { int b = __builtin_popcount(s); if (b <= 10) cnt[b]++; }\n        }\n        int sc = 0, tot = 0;\n        for (int d = 1; d <= 10; d++) { sc += min(a[d], cnt[d]); tot += a[d]; }\n        return tot ? (int)round(1e6 * sc / (double)tot) : 0;\n    };\n\n    vector<array<ll,4>> best;\n    int bs = -1;\n\n    // === Strategy 1: Split approach (alternating vertical/horizontal) ===\n    {\n        vector<pair<int,int>> seg = {{0, N-1}};\n        vector<array<ll,4>> sol;\n        for (int cut = 0; cut < K; cut++) {\n            int bi = -1, bsz = 0;\n            for (int i = 0; i < (int)seg.size(); i++) {\n                int sz = seg[i].second - seg[i].first + 1;\n                if (sz > bsz) { bsz = sz; bi = i; }\n            }\n            if (bsz <= 1) break;\n            auto [lo, hi] = seg[bi];\n            int mid;\n            if (cut % 2 == 0) {\n                vector<int> idx;\n                for (int j = 0; j < N; j++) if (sx[j] >= lo && sx[j] <= hi) idx.push_back(sx[j]);\n                mid = idx[(int)idx.size()/2];\n                ll mx = pts[mid].x;\n                if ((int)idx.size() > 1 && idx.size()/2 > 0) {\n                    ll mx2 = pts[idx[idx.size()/2-1]].x;\n                    mx = (mx + mx2 + 1) / 2;\n                }\n                sol.push_back({mx, -20000, mx, 20000});\n            } else {\n                vector<int> idx;\n                for (int j = 0; j < N; j++) if (sy[j] >= lo && sy[j] <= hi) idx.push_back(sy[j]);\n                mid = idx[(int)idx.size()/2];\n                ll my = pts[mid].y;\n                if ((int)idx.size() > 1 && idx.size()/2 > 0) {\n                    ll my2 = pts[idx[idx.size()/2-1]].y;\n                    my = (my + my2 + 1) / 2;\n                }\n                sol.push_back({-20000, my, 20000, my});\n            }\n            seg.erase(seg.begin() + bi);\n            seg.push_back({lo, mid - 1});\n            seg.push_back({mid, hi});\n        }\n        int sc = calc(sol);\n        if (sc > bs) { bs = sc; best = sol; }\n    }\n\n    // === Strategy 2: Angle-based grouping with refinement ===\n    if (N <= 2000) {\n        vector<pair<double,int>> ai(N);\n        for (int i = 0; i < N; i++) ai[i] = {atan2(pts[i].y, pts[i].x), i};\n        sort(ai.begin(), ai.end());\n\n        vector<pair<double,double>> dirs;\n        for (int i = 0; i < 32; i++) {\n            double ag = 2*M_PI*i/32;\n            dirs.push_back({cos(ag), sin(ag)});\n        }\n\n        int G = 0;\n        for (int i = 1; i <= 10; i++) G += a[i];\n\n        for (int rot = 0; rot < 3; rot++) {\n            vector<int> gr(N, -1);\n            int idx = 0;\n            for (int d = 1; d <= 10; d++)\n                for (int j = 0; j < a[d] && idx < N; j++, idx++)\n                    gr[ai[idx].second] = d;\n\n            vector<array<ll,4>> sol;\n            for (int g = 0; g < G; g++) {\n                int i0 = (g + rot) % N, i1 = (g + 1 + rot) % N;\n                double a0 = ai[i0].first, a1 = ai[i1].first;\n                double bd;\n                if (g < G - 1) bd = (a0 + a1) * 0.5;\n                else {\n                    double gap = a1 - a0;\n                    while (gap < 0) gap += 2*M_PI;\n                    bd = a0 + gap * 0.5;\n                    if (bd > M_PI) bd -= 2*M_PI;\n                }\n                double na = -sin(bd), nb = cos(bd);\n                ll r = 10000;\n                sol.push_back({llround(r*na),llround(r*nb),llround(-r*na),llround(-r*nb)});\n            }\n\n            vector<vector<int>> gm(G+1);\n            for (int i = 0; i < N; i++) if (gr[i] > 0) gm[gr[i]].push_back(i);\n\n            auto rdirs = dirs;\n            for (int gv = 1; gv <= G && (int)rdirs.size() < 64; gv++) {\n                if ((int)gm[gv].size() <= 1) continue;\n                for (int x = 0; x < (int)gm[gv].size() && (int)rdirs.size() < 64; x++)\n                    for (int y = 0; y < N && (int)rdirs.size() < 64; y++) {\n                        if (gr[y] == gv) continue;\n                        double dx = pts[gm[gv][x]].x - pts[y].x;\n                        double dy = pts[gm[gv][x]].y - pts[y].y;\n                        double ln = sqrt(dx*dx+dy*dy);\n                        if (ln > 1e-9) rdirs.push_back({dx/ln, dy/ln});\n                    }\n            }\n\n            for (int gv = 1; gv <= G && (int)sol.size() < K; gv++) {\n                if ((int)gm[gv].size() <= 1) continue;\n                bool ok = false;\n                for (int di = 0; di < (int)rdirs.size() && !ok; di++) {\n                    double dx = rdirs[di].first, dy = rdirs[di].second;\n                    vector<pair<double,int>> pp(N);\n                    for (int i = 0; i < N; i++) pp[i] = {pts[i].x*dx+pts[i].y*dy, i};\n                    sort(pp.begin(), pp.end());\n                    double mxg = -1e30, mng = 1e30;\n                    for (int i = 0; i < N; i++) {\n                        if (gr[pp[i].second] == gv) mxg = max(mxg, pp[i].first);\n                        else mng = min(mng, pp[i].first);\n                    }\n                    if (mxg >= mng - 0.5) continue;\n                    ll c = llround(pts[gm[gv][0]].x*dx + pts[gm[gv][0]].y*dy);\n                    double px = -dy, py = dx;\n                    ll dxx = llround(px*1e4), dyy = llround(py*1e4);\n                    ll gc = __gcd(abs(dxx), abs(dyy));\n                    if (gc > 1) { dxx /= gc; dyy /= gc; }\n                    if (!dxx && !dyy) { dxx = 1; }\n                    dxx *= 10000; dyy *= 10000;\n                    ll bx = llround((double)c*dx), by = llround((double)c*dy);\n                    sol.push_back({bx+dxx,by+dyy,bx-dxx,by-dyy});\n                    ok = true;\n                }\n            }\n            int sc = calc(sol);\n            if (sc > bs) { bs = sc; best = sol; }\n        }\n    }\n\n    if ((int)best.size() > K) best.resize(K);\n    cout << best.size() << \"\\n\";\n    for (auto& l : best) cout << l[0]<<\" \"<<l[1]<<\" \"<<l[2]<<\" \"<<l[3]<<\"\\n\";\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Cand {\n    double score;\n    int nx, ny, p1x, p1y, p2x, p2y, p3x, p3y;\n    bool operator<(const Cand& o) const { return score > o.score; }\n};\n\nint main(){\n    int N, M;\n    scanf(\"%d%d\",&N,&M);\n    const int MX=62;\n    bool g[MX][MX]={};\n    vector<pair<int,int>> dots;\n    for(int i=0;i<M;i++){\n        int x,y; scanf(\"%d%d\",&x,&y);\n        g[x][y]=true; dots.push_back({x,y});\n    }\n    double c=(N-1)/2.0;\n    double w[MX][MX];\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)\n        w[x][y]=(x-c)*(x-c)+(y-c)*(y-c)+1;\n    bitset<60> hz[MX][MX],vt[MX][MX],ne[MX][MX],nw[MX][MX];\n    auto ckH=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y>=N)return false;\n        return !hz[x][y].test(0);};\n    auto ckV=[&](int x,int y)->bool{\n        if(x<0||x<N||y<0||y>=N-1)return false;\n        return !vt[x][y].test(0);};\n    auto ckNE=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y>=N)return false;\n        return !ne[x][y].test(0);};\n    auto ckNW=[&](int x,int y)->bool{\n        if(x<1||x<N||y<0||y>=N)return false;\n        return !nw[x][y].test(0);};\n    auto sH=[&](int x,int y){hz[x][y].set(0);};\n    auto sV=[&](int x,int y){vt[x][y].set(0);};\n    auto sNE=[&](int x,int y){ne[x][y].set(0);};\n    auto sNW=[&](int x,int y){nw[x][y].set(0);};\n    vector<array<int,8>> ops;\n    auto getTime=[&]()->double{\n        auto now=chrono::steady_clock::now();\n        return chrono::duration<double>(now.time_since_epoch()).count();};\n    double startTime=getTime();\n    while(getTime()-startTime<4.5){\n        vector<Cand> cands;\n        for(auto&[px,py]:dots){\n            for(int d=0;d<4;d++){\n                static const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};\n                int qx=px+dx[d]*2,qy=py+dy[d]*2;\n                if(qx<0||qx>=N||qy<0||qy>=N||g[qx][qy])continue;\n                int c1x=px+dx[d],c1y=py+dy[d],c2x=qx-dx[d],c2y=qy-dy[d];\n                if(c2x<0||c2x>=N||c2y<0||c2y>=N||!g[c2x][c2y])continue;\n                double sc=w[qx][qy];\n                if(d==0||d==2){\n                    if(!ckV(qx,min(qy,c1y))||!ckV(c2x,min(c2y,py))||\n                       !ckH(min(qx,c2x),qy)||!ckH(min(px,c1x),c1y))continue;\n                }else{\n                    if(!ckH(min(qx,c1x),qy)||!ckH(min(c2x,px),c2y)||\n                       !ckV(qx,min(qy,c2y))||!ckV(c1x,min(c1y,py)))continue;\n                }\n                cands.push_back({sc,qx,qy,px,py,c1x,c1y,c2x,c2y});\n            }\n            for(int d=0;d<2;d++){\n                int nx=px+1,ny=py+(d==0?1:-1);\n                if(nx<0||nx>=N||ny<0||ny>=N||g[nx][ny])continue;\n                int x1=px,y1=py,x2=nx,y2=ny;\n                if((x1+y1)%2!=(x2+y2)%2)continue;\n                int a1x=(x1+y1+x2-y2)/2,a1y=(x1+y1-x2+y2)/2;\n                int b1x=(x2+y2+x1-y1)/2,b1y=(x2+y2-x1+y1)/2;\n                int ok1=(a1x>=0&&a1x<N&&a1y>=0&&a1y<N&&b1x>=0&&b1x<N&&b1y>=0&&b1y<N);\n                if(ok1){\n                    bool f1=g[a1x][a1y],f2=g[b1x][b1y];\n                    if(f1&&!f2){\n                        double sc=w[b1x][b1y];\n                        if(ckNE(min(b1x,a1x),min(b1y,a1y))&&\n                           ckNW(min(a1x,x1),min(a1y,y1))&&\n                           ckNE(min(x1,b1x),min(y1,b1y))&&\n                           ckNW(min(b1x,x2),min(b1y,y2)))\n                            cands.push_back({sc,b1x,b1y,x1,y1,a1x,a1y,x2,y2});\n                    }else if(!f1&&f2){\n                        double sc=w[a1x][a1y];\n                        if(ckNE(min(a1x,b1x),min(a1y,b1y))&&\n                           ckNW(min(b1x,x1),min(b1y,y1))&&\n                           ckNE(min(x1,a1x),min(y1,a1y))&&\n                           ckNW(min(a1x,x2),min(a1y,y2)))\n                            cands.push_back({sc,a1x,a1y,x1,y1,b1x,b1y,x2,y2});\n                    }\n                }\n                int c1x=(x1+y1+x2+y2)/2,c1y=(x1-y1+x2+y2)/2;\n                int c2x=(x1+y1-x2-y2)/2,c2y=(x1-y1-x2-y2)/2;\n                int ok2=(c1x>=0&&c1x<N&&c1y>=0&&c1y<N&&c2x>=0&&c2x<N&&c2y>=0&&c2y<N);\n                if(ok2){\n                    bool f1=g[c1x][c1y],f2=g[c2x][c2y];\n                    if(f1&&!f2){\n                        double sc=w[c2x][c2y];\n                        if(ckNE(min(c2x,x2),min(c2y,y2))&&\n                           ckNW(min(x2,c1x),min(y2,c1y))&&\n                           ckNE(min(c1x,x1),min(c1y,y1))&&\n                           ckNW(min(x1,c2x),min(y1,c2y)))\n                            cands.push_back({sc,c2x,c2y,x1,y1,x2,y2,c1x,c1y});\n                    }else if(!f1&&f2){\n                        double sc=w[c1x][c1y];\n                        if(ckNE(min(c1x,x2),min(c1y,y2))&&\n                           ckNW(min(x2,c2x),min(y2,c2y))&&\n                           ckNE(min(c2x,x1),min(c2y,y1))&&\n                           ckNW(min(x1,c1x),min(y1,c1y)))\n                            cands.push_back({sc,c1x,c1y,x1,y1,x2,y2,c2x,c2y});\n                    }\n                }\n            }\n        }\n        sort(cands.begin(),cands.end());\n        bool found=false;\n        for(auto& cd:cands){\n            int nx=cd.nx,ny=cd.ny,p1x=cd.p1x,p1y=cd.p1y;\n            int p2x=cd.p2x,p2y=cd.p2y,p3x=cd.p3x,p3y=cd.p3y;\n            if(!ckH(min(nx,p1x),min(ny,p1y)))continue;\n            if(!ckV(min(p1x,p2x),min(p1y,p2y)))continue;\n            if(!ckH(min(p2x,p3x),min(p2y,p3y)))continue;\n            if(!ckV(min(p3x,nx),min(p3y,ny)))continue;\n            if(!ckNE(min(nx,p2x),min(ny,p2y)))continue;\n            if(!ckNW(min(p2x,p1x),min(p2y,p1y)))continue;\n            if(!ckNE(min(p1x,p3x),min(p1y,p3y)))continue;\n            if(!ckNW(min(p3x,nx),min(p3y,ny)))continue;\n            sH(min(nx,p1x),min(ny,p1y));sV(min(p1x,p2x),min(p1y,p2y));\n            sH(min(p2x,p3x),min(p2y,p3y));sV(min(p3x,nx),min(p3y,ny));\n            sNE(min(nx,p2x),min(ny,p2y));sNW(min(p2x,p1x),min(p2y,p1y));\n            sNE(min(p1x,p3x),min(p1y,p3y));sNW(min(p3x,nx),min(p3y,ny));\n            g[nx][ny]=true;\n            dots.push_back({nx,ny});\n            array<int,8> op={nx,ny,p1x,p1y,p2x,p2y,p3x,p3y};\n            ops.push_back(op);\n            found=true;break;\n        }\n        if(!found)break;\n    }\n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&o:ops)\n        printf(\"%d %d %d %d %d %d %d %d\\n\",o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7]);\n    double ws=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(g[x][y])ws+=w[x][y];\n    double S=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)S+=w[x][y];\n    printf(\"Score: %lld\\n\",(long long)round(1e6*N*N/M*ws/S));\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[100];\n\nvoid tilt(char dir, int g[N][N]) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; ++j) {\n            int write = 0;\n            for (int i = 0; i < N; ++i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int i = write; i < N; ++i) g[i][j] = 0;\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; ++j) {\n            int write = N - 1;\n            for (int i = N - 1; i >= 0; --i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    --write;\n                }\n            }\n            for (int i = write; i >= 0; --i) g[i][j] = 0;\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; ++i) {\n            int write = 0;\n            for (int j = 0; j < N; ++j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int j = write; j < N; ++j) g[i][j] = 0;\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < N; ++i) {\n            int write = N - 1;\n            for (int j = N - 1; j >= 0; --j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    --write;\n                }\n            }\n            for (int j = write; j >= 0; --j) g[i][j] = 0;\n        }\n    }\n}\n\nint compute_score(int g[N][N]) {\n    bool visited[N][N] = {};\n    int total = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (g[i][j] != 0 && !visited[i][j]) {\n                int flavor = g[i][j];\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int size = 0;\n                while (!q.empty()) {\n                    auto [r, c] = q.front(); q.pop();\n                    ++size;\n                    if (r > 0 && g[r-1][c] == flavor && !visited[r-1][c]) {\n                        visited[r-1][c] = true;\n                        q.push({r-1, c});\n                    }\n                    if (r < N-1 && g[r+1][c] == flavor && !visited[r+1][c]) {\n                        visited[r+1][c] = true;\n                        q.push({r+1, c});\n                    }\n                    if (c > 0 && g[r][c-1] == flavor && !visited[r][c-1]) {\n                        visited[r][c-1] = true;\n                        q.push({r, c-1});\n                    }\n                    if (c < N-1 && g[r][c+1] == flavor && !visited[r][c+1]) {\n                        visited[r][c+1] = true;\n                        q.push({r, c+1});\n                    }\n                }\n                total += size * size;\n            }\n        }\n    }\n    return total;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n\n    memset(grid, 0, sizeof(grid));\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell in front-to-back, left-to-right order.\n        vector<pair<int, int>> empties;\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                if (grid[i][j] == 0) {\n                    empties.push_back({i, j});\n                }\n            }\n        }\n        auto [r, c] = empties[p - 1];\n        grid[r][c] = flavors[t];\n\n        // Try each direction and pick the one with maximum score.\n        int best_score = -1;\n        char best_dir = 'F';\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            int temp[N][N];\n            memcpy(temp, grid, sizeof(temp));\n            tilt(dir, temp);\n            int score = compute_score(temp);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        cout.flush();\n\n        // Apply the chosen tilt to the actual grid.\n        tilt(best_dir, grid);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <limits>\n\nusing namespace std;\n\ndouble q_function(double x) {\n    return 0.5 * erfc(x / sqrt(2.0));\n}\n\nint main() {\n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    if (M == 1) {\n        cout << \"4\" << endl;\n        cout << \"000000\" << endl;\n        for (int q = 0; q < 100; ++q) {\n            string H;\n            cin >> H;\n            cout << \"0\" << endl;\n        }\n        return 0;\n    }\n    \n    double best_expected_score = -1.0;\n    int best_N = 4;\n    \n    for (int N = 4; N <= 100; ++N) {\n        int T = N * (N - 1) / 2;\n        if (T < M - 1) continue;\n        \n        double delta = (double)T * (1.0 - 2.0 * eps) / (M - 1);\n        double noise = sqrt(T * eps * (1.0 - eps));\n        \n        double p_error;\n        if (noise < 1e-12) {\n            p_error = (delta > 0) ? 0.0 : 1.0;\n        } else {\n            double x = delta / (2.0 * noise);\n            double Q = q_function(x);\n            p_error = (2.0 - 2.0 / M) * Q;\n            if (p_error > 1.0) p_error = 1.0;\n        }\n        \n        double survival_prob = 1.0 - 0.1 * p_error;\n        if (survival_prob < 0.0) survival_prob = 0.0;\n        double expected_score = 1e9 * pow(survival_prob, 100) / N;\n        \n        if (expected_score > best_expected_score) {\n            best_expected_score = expected_score;\n            best_N = N;\n        }\n    }\n    \n    int N = best_N;\n    int T = N * (N - 1) / 2;\n    \n    vector<int> edge_counts(M);\n    for (int s = 0; s < M; ++s) {\n        edge_counts[s] = (s * T) / (M - 1);\n    }\n    \n    cout << N << endl;\n    for (int s = 0; s < M; ++s) {\n        string graph(T, '0');\n        for (int i = 0; i < edge_counts[s]; ++i) {\n            graph[i] = '1';\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n    \n    vector<double> expected_observed(M);\n    for (int s = 0; s < M; ++s) {\n        expected_observed[s] = edge_counts[s] * (1.0 - 2.0 * eps) + T * eps;\n    }\n    \n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        \n        int observed_edges = 0;\n        for (char c : H) {\n            if (c == '1') observed_edges++;\n        }\n        \n        int best_s = 0;\n        double min_diff = numeric_limits<double>::max();\n        for (int s = 0; s < M; ++s) {\n            double diff = abs(observed_edges - expected_observed[s]);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        \n        cout << best_s << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <cassert>\n#include <tuple>\n#include <chrono>\n#include <functional>\n\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\n\nstruct Edge {\n    int u, v, w;\n    int idx;\n};\n\nstruct EdgeAdj {\n    int to, idx;\n    ll w;\n};\n\nvector<ll> dijkstra(int s, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\nvector<ll> dijkstra_ignore_set(int s, const vector<bool>& ignore_edge, \n                               const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (ignore_edge[e.idx]) continue;\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\n// Compute betweenness centrality for edges\nvector<double> compute_edge_betweenness(int N, const vector<Edge>& edges, \n                                        const vector<vector<ll>>& dist) {\n    int M = edges.size();\n    vector<double> edge_betw(M, 0.0);\n    \n    for (int s = 0; s < N; ++s) {\n        const auto& d_s = dist[s];\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 0);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) { \n            return d_s[a] < d_s[b]; \n        });\n        \n        vector<double> sigma(N, 0.0);\n        sigma[s] = 1.0;\n        vector<vector<int>> preds(N);\n        vector<vector<int>> pred_edges(N);\n        \n        for (int i = 0; i < M; ++i) {\n            int u = edges[i].u, v = edges[i].v;\n            ll w = edges[i].w;\n            if (d_s[u] + w == d_s[v]) {\n                preds[v].push_back(u);\n                pred_edges[v].push_back(i);\n            }\n            if (d_s[v] + w == d_s[u]) {\n                preds[u].push_back(v);\n                pred_edges[u].push_back(i);\n            }\n        }\n        \n        for (int v : nodes) {\n            if (v == s) continue;\n            for (int u : preds[v]) {\n                sigma[v] += sigma[u];\n            }\n        }\n        \n        vector<double> dep(N, 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int v = *it;\n            if (v == s) continue;\n            for (size_t i = 0; i < preds[v].size(); ++i) {\n                int u = preds[v][i];\n                int edge_idx = pred_edges[v][i];\n                double contrib = (sigma[u] / sigma[v]) * (1.0 + dep[v]);\n                dep[u] += contrib;\n                edge_betw[edge_idx] += contrib;\n            }\n        }\n    }\n    \n    return edge_betw;\n}\n\ndouble compute_day_frustration(int day, const vector<int>& day_assignment, \n                              const vector<Edge>& edges, const vector<vector<ll>>& orig_dist,\n                              const vector<vector<EdgeAdj>>& adj, int N, \n                              const vector<int>& sample_sources) {\n    vector<bool> ignore_edge(edges.size(), false);\n    int edge_count = 0;\n    for (int i = 0; i < edges.size(); ++i) {\n        if (day_assignment[i] == day) {\n            ignore_edge[i] = true;\n            edge_count++;\n        }\n    }\n    \n    if (edge_count == 0) return 0.0;\n    \n    double total_increase = 0.0;\n    int pair_count = 0;\n    \n    for (int s : sample_sources) {\n        vector<ll> new_dist = dijkstra_ignore_set(s, ignore_edge, adj);\n        for (int t = 0; t < N; ++t) {\n            if (s == t) continue;\n            ll orig_d = orig_dist[s][t];\n            ll new_d = new_dist[t];\n            if (new_d >= INF/2) new_d = 1000000000;\n            total_increase += (new_d - orig_d);\n            pair_count++;\n        }\n    }\n    \n    double avg_increase = total_increase / pair_count;\n    return avg_increase * (N * (N - 1)) / (sample_sources.size() * (N - 1));\n}\n\nvector<int> greedy_initial_assignment(const vector<Edge>& edges, const vector<double>& edge_importance,\n                                      int D, int K, int M) {\n    vector<int> assignment(M, 0);\n    vector<int> day_count(D, 0);\n    vector<double> day_importance(D, 0.0);\n    \n    // Sort edges by importance descending\n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return edge_importance[a] > edge_importance[b];\n    });\n    \n    for (int e_idx : edge_order) {\n        // Find day with minimum importance that has capacity\n        int best_day = -1;\n        double min_importance = 1e18;\n        for (int d = 0; d < D; ++d) {\n            if (day_count[d] < K && day_importance[d] < min_importance) {\n                min_importance = day_importance[d];\n                best_day = d;\n            }\n        }\n        assignment[e_idx] = best_day;\n        day_count[best_day]++;\n        day_importance[best_day] += edge_importance[e_idx];\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    \n    vector<Edge> edges(M);\n    vector<vector<EdgeAdj>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        adj[u].push_back({v, i, w});\n        adj[v].push_back({u, i, w});\n    }\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Precompute original distances\n    vector<vector<ll>> orig_dist(N);\n    for (int s = 0; s < N; ++s) {\n        orig_dist[s] = dijkstra(s, adj);\n    }\n    \n    // Compute edge importance (betweenness * delta)\n    vector<double> edge_importance(M, 0.0);\n    vector<double> edge_betw = compute_edge_betweenness(N, edges, orig_dist);\n    \n    // Compute delta for each edge (alternative path length - original length)\n    vector<ll> edge_delta(M, 0);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u, v = edges[i].v;\n        ll w = edges[i].w;\n        vector<bool> ignore(M, false);\n        ignore[i] = true;\n        vector<ll> dist_u = dijkstra_ignore_set(u, ignore, adj);\n        edge_delta[i] = dist_u[v] - w;\n        if (edge_delta[i] < 0) edge_delta[i] = 0;\n    }\n    \n    for (int i = 0; i < M; ++i) {\n        edge_importance[i] = edge_betw[i] * edge_delta[i];\n    }\n    \n    // Sample vertices for frustration estimation\n    int sample_size = min(30, N);\n    vector<int> sample_sources(sample_size);\n    iota(sample_sources.begin(), sample_sources.end(), 0);\n    if (N > sample_size) {\n        random_device rd;\n        mt19937 gen(rd());\n        shuffle(sample_sources.begin(), sample_sources.end(), gen);\n        sample_sources.resize(sample_size);\n    }\n    \n    // Get initial assignment using greedy algorithm\n    vector<int> assignment = greedy_initial_assignment(edges, edge_importance, D, K, M);\n    \n    // Compute initial frustration\n    vector<double> day_frustration(D, 0.0);\n    double total_frustration = 0.0;\n    for (int day = 0; day < D; ++day) {\n        day_frustration[day] = compute_day_frustration(day, assignment, edges, orig_dist, \n                                                      adj, N, sample_sources);\n        total_frustration += day_frustration[day];\n    }\n    \n    // Simulated annealing with edge moves and swaps\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> dis(0.0, 1.0);\n    uniform_int_distribution<int> rand_edge(0, M - 1);\n    uniform_int_distribution<int> rand_day(0, D - 1);\n    uniform_int_distribution<int> rand_move_type(0, 1); // 0: move, 1: swap\n    \n    double temp = 1000.0;\n    double cooling = 0.9998;\n    const int ITER = 250000;\n    \n    for (int iter = 0; iter < ITER; ++iter) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 5.5) break;\n        \n        if (rand_move_type(gen) == 0) {\n            // Move single edge\n            int e = rand_edge(gen);\n            int old_day = assignment[e];\n            int new_day = rand_day(gen);\n            while (new_day == old_day) new_day = rand_day(gen);\n            \n            // Check capacity\n            int cnt_new = count(assignment.begin(), assignment.end(), new_day);\n            if (cnt_new >= K) continue;\n            \n            assignment[e] = new_day;\n            \n            double new_frustration_old = compute_day_frustration(old_day, assignment, edges, \n                                                                orig_dist, adj, N, sample_sources);\n            double new_frustration_new = compute_day_frustration(new_day, assignment, edges, \n                                                                orig_dist, adj, N, sample_sources);\n            \n            double new_total = total_frustration - day_frustration[old_day] - day_frustration[new_day] \n                              + new_frustration_old + new_frustration_new;\n            \n            double delta = new_total - total_frustration;\n            \n            if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n                total_frustration = new_total;\n                day_frustration[old_day] = new_frustration_old;\n                day_frustration[new_day] = new_frustration_new;\n            } else {\n                assignment[e] = old_day;\n            }\n        } else {\n            // Swap two edges between days\n            int e1 = rand_edge(gen);\n            int e2 = rand_edge(gen);\n            if (e1 == e2) continue;\n            \n            int day1 = assignment[e1];\n            int day2 = assignment[e2];\n            if (day1 == day2) continue;\n            \n            // Perform swap\n            assignment[e1] = day2;\n            assignment[e2] = day1;\n            \n            double new_frustration_day1 = compute_day_frustration(day1, assignment, edges, \n                                                                 orig_dist, adj, N, sample_sources);\n            double new_frustration_day2 = compute_day_frustration(day2, assignment, edges, \n                                                                 orig_dist, adj, N, sample_sources);\n            \n            double new_total = total_frustration - day_frustration[day1] - day_frustration[day2] \n                              + new_frustration_day1 + new_frustration_day2;\n            \n            double delta = new_total - total_frustration;\n            \n            if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n                total_frustration = new_total;\n                day_frustration[day1] = new_frustration_day1;\n                day_frustration[day2] = new_frustration_day2;\n            } else {\n                // Revert swap\n                assignment[e1] = day1;\n                assignment[e2] = day2;\n            }\n        }\n        \n        temp *= cooling;\n    }\n    \n    // Output (convert to 1-indexed days)\n    for (int i = 0; i < M; ++i) {\n        if (i > 0) cout << ' ';\n        cout << (assignment[i] + 1);\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    // Read silhouettes, remove spaces if any\n    vector<string> f[2], r[2];\n    for (int i = 0; i < 2; ++i) {\n        f[i].resize(D);\n        for (int j = 0; j < D; ++j) {\n            cin >> f[i][j];\n            string clean;\n            for (char c : f[i][j]) if (c != ' ') clean.push_back(c);\n            f[i][j] = clean;\n        }\n        r[i].resize(D);\n        for (int j = 0; j < D; ++j) {\n            cin >> r[i][j];\n            string clean;\n            for (char c : r[i][j]) if (c != ' ') clean.push_back(c);\n            r[i][j] = clean;\n        }\n    }\n\n    // Sets of occupied cells for each object\n    vector<array<int, 3>> cells[2];\n    // Common cells (intersection)\n    vector<array<int, 3>> common;\n\n    // Generate all allowed cells for each object and find intersection\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 in0 = (f[0][z][x] == '1' && r[0][z][y] == '1');\n                bool in1 = (f[1][z][x] == '1' && r[1][z][y] == '1');\n                if (in0 && in1) {\n                    common.push_back({x, y, z});\n                } else if (in0) {\n                    cells[0].push_back({x, y, z});\n                } else if (in1) {\n                    cells[1].push_back({x, y, z});\n                }\n            }\n        }\n    }\n\n    // Assign block IDs\n    int n = common.size() + cells[0].size() + cells[1].size();\n    vector<vector<vector<int>>> b[2];\n    for (int i = 0; i < 2; ++i) {\n        b[i].assign(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    }\n\n    int id = 1;\n    // Place common cells (shared blocks)\n    for (auto [x, y, z] : common) {\n        b[0][x][y][z] = id;\n        b[1][x][y][z] = id;\n        ++id;\n    }\n    // Place exclusive cells for object 0\n    for (auto [x, y, z] : cells[0]) {\n        b[0][x][y][z] = id++;\n    }\n    // Place exclusive cells for object 1\n    for (auto [x, y, z] : cells[1]) {\n        b[1][x][y][z] = id++;\n    }\n\n    // Output\n    cout << n << '\\n';\n    for (int obj = 0; obj < 2; ++obj) {\n        bool first = true;\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 (first) first = false;\n                    else cout << ' ';\n                    cout << b[obj][x][y][z];\n                }\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\nconst ll RADIUS_SQ = 25000000LL; // 5000^2\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // graph and edge index mapping\n    vector<vector<ll>> distV(N, vector<ll>(N, INF));\n    vector<vector<int>> nextV(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        distV[i][i] = 0;\n        nextV[i][i] = i;\n    }\n    vector<tuple<int, int, int>> edges(M); // u, v, w\n    vector<vector<int>> edgeIdx(N, vector<int>(N, -1));\n    for (int j = 0; j < M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u, --v;\n        edges[j] = {u, v, w};\n        distV[u][v] = distV[v][u] = w;\n        nextV[u][v] = v;\n        nextV[v][u] = u;\n        edgeIdx[u][v] = edgeIdx[v][u] = j;\n    }\n\n    // residents\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute distances between vertices and residents\n    vector<vector<ll>> sqDist(N, vector<ll>(K));\n    vector<vector<double>> eucDist(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = x[i] - a[k];\n            ll dy = y[i] - b[k];\n            sqDist[i][k] = dx*dx + dy*dy;\n            eucDist[i][k] = sqrt((double)sqDist[i][k]);\n        }\n    }\n\n    // Floyd-Warshall for shortest paths between vertices\n    for (int kk = 0; kk < N; ++kk) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][kk] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[kk][j] == INF) continue;\n                if (distV[i][j] > distV[i][kk] + distV[kk][j]) {\n                    distV[i][j] = distV[i][kk] + distV[kk][j];\n                    nextV[i][j] = nextV[i][kk];\n                }\n            }\n        }\n    }\n\n    // Initialize with all vertices connected to vertex 0\n    vector<int> S(N);\n    iota(S.begin(), S.end(), 0);\n    \n    // Greedy assignment to minimize sum of squares\n    vector<double> maxDist(N, 0.0);\n    vector<int> assign(K);\n    \n    // Initial assignment: each resident to nearest vertex\n    for (int k = 0; k < K; ++k) {\n        double minDist = 1e18;\n        int bestV = -1;\n        for (int v : S) {\n            double d = eucDist[v][k];\n            if (d < minDist) {\n                minDist = d;\n                bestV = v;\n            }\n        }\n        assign[k] = bestV;\n        if (minDist > maxDist[bestV]) {\n            maxDist[bestV] = minDist;\n        }\n    }\n\n    // Local search: try to remove vertices\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < (int)S.size(); ++i) {\n            int v = S[i];\n            if (v == 0) continue; // Keep vertex 0\n\n            // Try removing vertex v\n            vector<int> newS = S;\n            newS.erase(newS.begin() + i);\n            \n            // Check if all residents can be reassigned within 5000\n            bool canRemove = true;\n            vector<int> newAssign = assign;\n            vector<double> newMaxDist(N, 0.0);\n            \n            for (int k = 0; k < K; ++k) {\n                if (assign[k] == v) {\n                    // Find nearest vertex in newS within 5000\n                    double bestDist = 1e18;\n                    int bestVertex = -1;\n                    for (int u : newS) {\n                        double d = eucDist[u][k];\n                        if (d <= 5000.0 && d < bestDist) {\n                            bestDist = d;\n                            bestVertex = u;\n                        }\n                    }\n                    if (bestVertex == -1) {\n                        canRemove = false;\n                        break;\n                    }\n                    newAssign[k] = bestVertex;\n                    if (bestDist > newMaxDist[bestVertex]) {\n                        newMaxDist[bestVertex] = bestDist;\n                    }\n                } else {\n                    int u = assign[k];\n                    if (eucDist[u][k] > newMaxDist[u]) {\n                        newMaxDist[u] = eucDist[u][k];\n                    }\n                }\n            }\n            \n            if (!canRemove) continue;\n            \n            // Compute new costs\n            ll newSumSq = 0;\n            for (int u : newS) {\n                if (newMaxDist[u] > 0) {\n                    int p = (int)ceil(newMaxDist[u] - 1e-9);\n                    newSumSq += (ll)p * p;\n                }\n            }\n            \n            // Compute MST cost for newS\n            vector<tuple<ll, int, int>> mstEdges;\n            for (size_t a = 0; a < newS.size(); ++a) {\n                for (size_t b = a+1; b < newS.size(); ++b) {\n                    int u = newS[a], v2 = newS[b];\n                    mstEdges.emplace_back(distV[u][v2], u, v2);\n                }\n            }\n            sort(mstEdges.begin(), mstEdges.end());\n            vector<int> parent(N);\n            iota(parent.begin(), parent.end(), 0);\n            function<int(int)> find = [&](int x) {\n                return parent[x] == x ? x : parent[x] = find(parent[x]);\n            };\n            auto unite = [&](int x, int y) {\n                parent[find(x)] = find(y);\n            };\n            ll newMSTCost = 0;\n            for (auto [w, u, v2] : mstEdges) {\n                if (find(u) != find(v2)) {\n                    unite(u, v2);\n                    newMSTCost += w;\n                }\n            }\n            \n            // Current costs\n            ll currentSumSq = 0;\n            for (int u : S) {\n                if (maxDist[u] > 0) {\n                    int p = (int)ceil(maxDist[u] - 1e-9);\n                    currentSumSq += (ll)p * p;\n                }\n            }\n            \n            // Current MST cost\n            vector<tuple<ll, int, int>> currentMSTEdges;\n            for (size_t a = 0; a < S.size(); ++a) {\n                for (size_t b = a+1; b < S.size(); ++b) {\n                    int u = S[a], v2 = S[b];\n                    currentMSTEdges.emplace_back(distV[u][v2], u, v2);\n                }\n            }\n            sort(currentMSTEdges.begin(), currentMSTEdges.end());\n            vector<int> currentParent(N);\n            iota(currentParent.begin(), currentParent.end(), 0);\n            function<int(int)> currentFind = [&](int x) {\n                return currentParent[x] == x ? x : currentParent[x] = currentFind(currentParent[x]);\n            };\n            auto currentUnite = [&](int x, int y) {\n                currentParent[currentFind(x)] = currentFind(y);\n            };\n            ll currentMSTCost = 0;\n            for (auto [w, u, v2] : currentMSTEdges) {\n                if (currentFind(u) != currentFind(v2)) {\n                    currentUnite(u, v2);\n                    currentMSTCost += w;\n                }\n            }\n            \n            if (newSumSq + newMSTCost < currentSumSq + currentMSTCost) {\n                // Accept removal\n                S = newS;\n                assign = newAssign;\n                maxDist = newMaxDist;\n                improved = true;\n                break;\n            }\n        }\n    }\n\n    // Compute final P values\n    vector<int> P(N, 0);\n    for (int u : S) {\n        if (maxDist[u] > 0) {\n            int p = (int)ceil(maxDist[u] - 1e-9);\n            P[u] = p;\n        }\n    }\n\n    // Build final MST\n    vector<tuple<ll, int, int>> finalMSTEdges;\n    for (size_t i = 0; i < S.size(); ++i) {\n        for (size_t j = i+1; j < S.size(); ++j) {\n            int u = S[i], v = S[j];\n            finalMSTEdges.emplace_back(distV[u][v], u, v);\n        }\n    }\n    sort(finalMSTEdges.begin(), finalMSTEdges.end());\n    vector<int> finalParent(N);\n    iota(finalParent.begin(), finalParent.end(), 0);\n    function<int(int)> finalFind = [&](int x) {\n        return finalParent[x] == x ? x : finalParent[x] = finalFind(finalParent[x]);\n    };\n    auto finalUnite = [&](int x, int y) {\n        finalParent[finalFind(x)] = finalFind(y);\n    };\n    vector<pair<int, int>> finalMSTPairs;\n    for (auto [w, u, v] : finalMSTEdges) {\n        if (finalFind(u) != finalFind(v)) {\n            finalUnite(u, v);\n            finalMSTPairs.emplace_back(u, v);\n        }\n    }\n\n    // Turn on edges along shortest paths\n    vector<bool> edgeOn(M, false);\n    for (auto [u, v] : finalMSTPairs) {\n        int cur = u;\n        while (cur != v) {\n            int nxt = nextV[cur][v];\n            int idx = edgeIdx[cur][nxt];\n            if (idx != -1) {\n                edgeOn[idx] = true;\n            }\n            cur = nxt;\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N-1 ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; ++j) {\n        cout << edgeOn[j] << (j == M-1 ? '\\n' : ' ');\n    }\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    int grid[N][N];\n    map<int,pair<int,int>> pos;\n    vector<array<int,4>> ops;\n    \n    auto do_swap = [&](int x1,int y1,int x2,int y2){\n        int v1=grid[x1][y1], v2=grid[x2][y2];\n        grid[x1][y1]=v2; grid[x2][y2]=v1;\n        pos[v1]={x2,y2}; pos[v2]={x1,y1};\n        ops.push_back({x1,y1,x2,y2});\n    };\n    \n    auto find_path = [&](int sx,int sy,int ex,int ey){\n        queue<pair<int,int>> q;\n        vector<int> par(N*N,-1);\n        auto sk=[&](int a,int b){return a*N+b;};\n        q.push({sx,sy});\n        int ss=sk(sx,sy);\n        par[ss]=ss;\n        while(!q.empty()){\n            auto[x,y]=q.front();q.pop();\n            int s=sk(x,y);\n            if(x==ex&&y==ey){\n                vector<pair<int,int>> p;\n                int c=s;\n                while(c!=par[c]){\n                    p.push_back({c/N,c%N});\n                    c=par[c];\n                }\n                p.push_back({c/N,c%N});\n                reverse(p.begin(),p.end());\n                return p;\n            }\n            for(auto[dx,dy]:{pair{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}}){\n                int nx=x+dx,ny=y+dy;\n                if(nx>=0&&nx<N&&ny>=0&&ny<=nx){\n                    int ns=sk(nx,ny);\n                    if(par[ns]==-1){par[ns]=s;q.push({nx,ny});}\n                }\n            }\n        }\n        return vector<pair<int,int>>{{sx,sy}};\n    };\n    \n    auto exec_path = [&](int val,int tx,int ty){\n        auto[sx,sy]=pos[val];\n        if(sx==tx&&sy==ty)return;\n        auto path=find_path(sx,sy,tx,ty);\n        for(int i=0;i+1<(int)path.size();i++)\n            do_swap(path[i].first,path[i].second,path[i+1].first,path[i+1].second);\n    };\n    \n    for(int i=0;i<N;i++)\n        for(int j=0;j<=i;j++){\n            cin>>grid[i][j];\n            pos[grid[i][j]]={i,j};\n        }\n    \n    // Floyd's heapify with full sifting and backtrack\n    for(int x=N-2;x>=0;x--){\n        for(int y=x;y>=0;y--){\n            int cx=x, cy=y;\n            while(cx<N-1){\n                int v=grid[cx][cy];\n                int lx=cx+1, ly=cy, rx=cx+1, ry=cy+1;\n                int mx=cx, my=cy, mv=v;\n                if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mx=lx;my=ly;mv=grid[lx][ly];}\n                if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mx=rx;my=ry;mv=grid[rx][ry];}\n                if(mx==cx&&my==cy) break;\n                exec_path(v,mx,my);\n                cx=mx; cy=my;\n            }\n            // Backtrack: if a smaller value bubbled up, re-sift from parent\n            if(cx>x){\n                int px=cx-1, py=(cy>0&&cy>cx-1)?cy-1:cy;\n                if(px>=0&&py>=0&&py<=px&&grid[px][py]>grid[cx][cy]){\n                    int bx=px, by=py;\n                    while(bx<N-1){\n                        int v=grid[bx][by];\n                        int lx=bx+1, ly=by, rx=bx+1, ry=by+1;\n                        int mx=bx, my=by, mv=v;\n                        if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mx=lx;my=ly;mv=grid[lx][ly];}\n                        if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mx=rx;my=ry;mv=grid[rx][ry];}\n                        if(mx==bx&&my==by) break;\n                        exec_path(v,mx,my);\n                        bx=mx; by=my;\n                    }\n                }\n            }\n        }\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto& o:ops) cout<<o[0]<<\" \"<<o[1]<<\" \"<<o[2]<<\" \"<<o[3]<<\"\\n\";\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n#include <cmath>\n#include <set>\n#include <map>\n#include <climits>\nusing namespace std;\n\nconst int entrance_i = 0, entrance_j = 4;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nbool obstacle[9][9] = {false};\nbool occupied[9][9] = {false};\nint placed_number[9][9];  // Store the number placed at each position\nvector<pair<int, int>> container_squares;\nint M;\nint dist[9][9];\nint min_d = INT_MAX, max_d = 0;\n\ninline bool in_bounds(int i, int j) {\n    return i >= 0 && i < 9 && j >= 0 && j < 9;\n}\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    dist[entrance_i][entrance_j] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || dist[nx][ny] != -1) continue;\n            dist[nx][ny] = dist[x][y] + 1;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    // Find min and max distance among container squares\n    for (auto [i, j] : container_squares) {\n        if (dist[i][j] != -1) {\n            min_d = min(min_d, dist[i][j]);\n            max_d = max(max_d, dist[i][j]);\n        }\n    }\n}\n\nvector<pair<int, int>> get_reachable() {\n    bool vis[9][9] = {false};\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    vis[entrance_i][entrance_j] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n            if (nx == entrance_i && ny == entrance_j) continue;\n            if (occupied[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    vector<pair<int, int>> reachable;\n    for (auto [i, j] : container_squares) {\n        if (vis[i][j] && !occupied[i][j]) {\n            reachable.emplace_back(i, j);\n        }\n    }\n    return reachable;\n}\n\nbool would_disconnect(int i, int j, int remaining) {\n    occupied[i][j] = true;\n    \n    bool vis[9][9] = {false};\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    vis[entrance_i][entrance_j] = true;\n    int count = 1;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n            if (occupied[nx][ny]) continue;\n            vis[nx][ny] = true;\n            count++;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    occupied[i][j] = false;\n    return count != remaining;\n}\n\n// Calculate how \"strategic\" a position is for future placements\nint strategic_value(int i, int j, int remaining) {\n    // Count how many squares would become unreachable if we place here\n    int blocked_count = 0;\n    \n    // Temporarily occupy\n    occupied[i][j] = true;\n    \n    // For each unoccupied container square, check if it's still reachable\n    for (auto [x, y] : container_squares) {\n        if (occupied[x][y]) continue;\n        \n        // BFS from entrance to (x,y)\n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        bool reachable = false;\n        \n        while (!q.empty() && !reachable) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny] || occupied[nx][ny]) continue;\n                if (nx == x && ny == y) {\n                    reachable = true;\n                    break;\n                }\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n        \n        if (!reachable) {\n            blocked_count++;\n        }\n    }\n    \n    occupied[i][j] = false;\n    return blocked_count;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    memset(placed_number, -1, sizeof(placed_number));\n    \n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n    \n    // List container squares\n    for (int i = 0; i < 9; ++i) {\n        for (int j = 0; j < 9; ++j) {\n            if (i == entrance_i && j == entrance_j) continue;\n            if (obstacle[i][j]) continue;\n            container_squares.emplace_back(i, j);\n        }\n    }\n    M = container_squares.size();\n    \n    compute_distances();\n    \n    int placed = 0;\n    \n    for (int step = 0; step < M; ++step) {\n        int t;\n        cin >> t;\n        \n        auto reachable = get_reachable();\n        int remaining = M - placed;\n        \n        // Filter to safe squares\n        vector<pair<int, int>> safe_squares;\n        for (auto [i, j] : reachable) {\n            if (!would_disconnect(i, j, remaining)) {\n                safe_squares.emplace_back(i, j);\n            }\n        }\n        \n        if (safe_squares.empty()) {\n            safe_squares = reachable;\n        }\n        \n        // Improved placement strategy:\n        // 1. For very small numbers (t < M/10), place as close as possible\n        // 2. For very large numbers (t > 9M/10), place as far as possible\n        // 3. For others, use a balanced approach considering both distance and strategic value\n        \n        pair<int, int> best_pos = safe_squares[0];\n        double best_score = -1e18;\n        \n        for (auto [i, j] : safe_squares) {\n            int d = dist[i][j];\n            double distance_score = 0;\n            \n            // Normalize distance to [0, 1]\n            double normalized_d = (max_d == min_d) ? 0.5 : (double)(d - min_d) / (max_d - min_d);\n            \n            if (t < M / 10) {\n                // Very small numbers: strongly prefer close to entrance\n                distance_score = 100.0 * (1.0 - normalized_d);\n            } else if (t > 9 * M / 10) {\n                // Very large numbers: strongly prefer far from entrance\n                distance_score = 100.0 * normalized_d;\n            } else {\n                // Medium numbers: use a more nuanced approach\n                double target_normalized = (double)t / M;\n                distance_score = 50.0 * (1.0 - abs(normalized_d - target_normalized));\n            }\n            \n            // Strategic value: how many squares this placement would block\n            int blocked = strategic_value(i, j, remaining);\n            double strategic_score = 20.0 * (1.0 - (double)blocked / remaining);\n            \n            // Combined score\n            double score = distance_score + strategic_score;\n            \n            // Add small bonus for positions that are more \"central\" (have more neighbors)\n            int neighbor_count = 0;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (in_bounds(ni, nj) && !obstacle[ni][nj]) {\n                    neighbor_count++;\n                }\n            }\n            score += 5.0 * neighbor_count;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_pos = {i, j};\n            }\n        }\n        \n        auto [pi, pj] = best_pos;\n        cout << pi << \" \" << pj << endl;\n        occupied[pi][pj] = true;\n        placed_number[pi][pj] = t;\n        placed++;\n    }\n    \n    // Compute optimal retrieval order using priority queue simulation\n    vector<pair<int, int>> retrieval_order;\n    \n    // Create simulation state\n    bool sim_occupied[9][9];\n    int sim_numbers[9][9];\n    memcpy(sim_occupied, occupied, sizeof(sim_occupied));\n    memcpy(sim_numbers, placed_number, sizeof(sim_numbers));\n    \n    while (retrieval_order.size() < M) {\n        // Find reachable squares in simulation\n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        \n        vector<pair<int, int>> reachable;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n                if (sim_occupied[nx][ny]) {\n                    reachable.emplace_back(nx, ny);\n                    vis[nx][ny] = true;\n                } else {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n        \n        if (reachable.empty()) break;\n        \n        // Choose reachable square with smallest number\n        auto best_square = reachable[0];\n        for (auto [i, j] : reachable) {\n            if (sim_numbers[i][j] < sim_numbers[best_square.first][best_square.second]) {\n                best_square = {i, j};\n            }\n        }\n        \n        retrieval_order.push_back(best_square);\n        sim_occupied[best_square.first][best_square.second] = false;\n    }\n    \n    // Output retrieval order\n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int n = 50, m = 100;\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    // size of each color\n    vector<int> sz(m + 1, 0);\n    // whether color is originally adjacent to outside (0)\n    vector<bool> adj0(m + 1, false);\n    // adjacency between colors (excluding 0)\n    vector<vector<bool>> adj(m + 1, vector<bool>(m + 1, false));\n    // edge counts: edge[x][y] = number of unordered adjacent pairs between colors x and y\n    // (including y=0 for outside)\n    vector<vector<int>> edge(m + 1, vector<int>(m + 1, 0));\n\n    // first pass: sizes, adjacency, edge counts\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = grid[i][j];\n            sz[c]++;\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n                adj0[c] = true;\n            }\n            // right neighbor\n            if (j + 1 < n) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    adj[c][d] = adj[d][c] = true;\n                }\n            }\n            // down neighbor\n            if (i + 1 < n) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    adj[c][d] = adj[d][c] = true;\n                }\n            }\n        }\n    }\n\n    // second pass: initial edge counts (each internal edge counted once)\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c = grid[i][j];\n            // right\n            if (j + 1 < n) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // down\n            if (i + 1 < n) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // boundary to outside\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n                edge[c][0]++;\n                edge[0][c]++;\n            }\n        }\n    }\n\n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n\n    // visited array for BFS (token method)\n    int vis[50][50] = {};\n    int token = 0;\n\n    // lambda to check if removing (i,j) would disconnect its color\n    auto is_connected_without = [&](int i, int j, int c) -> bool {\n        token++;\n        queue<pair<int, int>> q;\n        // start from a neighbour of the same color\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == c) {\n                vis[ni][nj] = token;\n                q.emplace(ni, nj);\n                break;\n            }\n        }\n        if (q.empty()) return false;   // should not happen in a connected component\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            cnt++;\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == c && vis[nx][ny] != token && !(nx == i && ny == j)) {\n                    vis[nx][ny] = token;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n        return cnt == sz[c] - 1;\n    };\n\n    // lambda to test whether cell (i,j) can be turned to 0\n    auto is_removable = [&](int i, int j) -> bool {\n        int c = grid[i][j];\n        if (sz[c] <= 1) return false;\n\n        bool on_boundary = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n        // interior cells must touch an existing 0 cell\n        if (!on_boundary) {\n            bool touches_zero = false;\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] == 0) {\n                    touches_zero = true;\n                    break;\n                }\n            }\n            if (!touches_zero) return false;\n        }\n\n        // count neighbours\n        vector<int> cnt(m + 1, 0);\n        int n0 = 0;   // neighbours that are already 0\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol > 0) {\n                    if (!adj0[dcol]) return false;   // would create illegal 0-adjacency\n                    cnt[dcol]++;\n                } else if (dcol == 0) {\n                    n0++;\n                }\n            }\n        }\n        int nc = cnt[c];          // neighbours of the same colour\n        int b = on_boundary ? 1 : 0;\n\n        // check that after removal every required edge (c,d) still exists\n        for (int d = 1; d <= m; ++d) {\n            if (d == c) continue;\n            if (adj[c][d]) {\n                if (edge[c][d] - cnt[d] < 1) return false;\n            }\n        }\n\n        // check that colour c remains adjacent to 0 if required\n        if (adj0[c]) {\n            int new_edge_c0 = edge[c][0] - b - n0 + nc;\n            if (new_edge_c0 < 1) return false;\n        }\n\n        // connectivity of colour c\n        if (nc >= 2) {\n            if (!is_connected_without(i, j, c)) return false;\n        }\n        // if nc == 1, the cell is a leaf \u2192 removal cannot disconnect\n        return true;\n    };\n\n    // lambda to actually perform the removal\n    auto remove_cell = [&](int i, int j) {\n        int c = grid[i][j];\n        sz[c]--;\n\n        bool on_boundary = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n\n        // delete old edges\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol != c) {\n                    edge[c][dcol]--;\n                    edge[dcol][c]--;\n                }\n            }\n        }\n        if (on_boundary) {\n            edge[c][0]--;\n            edge[0][c]--;\n        }\n\n        // change to 0\n        grid[i][j] = 0;\n\n        // add new edges (now 0 with its neighbours)\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                int dcol = grid[ni][nj];\n                if (dcol != 0) {\n                    edge[0][dcol]++;\n                    edge[dcol][0]++;\n                }\n            }\n        }\n    };\n\n    // queue of candidate cells (initially all boundary cells)\n    queue<pair<int, int>> cand;\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if ((i == 0 || i == n - 1 || j == 0 || j == n - 1) && grid[i][j] > 0) {\n                cand.emplace(i, j);\n            }\n        }\n    }\n\n    // main erosion loop\n    while (!cand.empty()) {\n        auto [i, j] = cand.front();\n        cand.pop();\n        if (grid[i][j] == 0) continue;   // already removed\n        if (is_removable(i, j)) {\n            remove_cell(i, j);\n            // neighbours may become removable\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && grid[ni][nj] > 0) {\n                    cand.emplace(ni, nj);\n                }\n            }\n        }\n    }\n\n    // output\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << grid[i][j];\n            if (j + 1 < n) cout << ' ';\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint used = 0;\nint N, D, Q;\n\nstring do_query(int l, int r) {\n    cout << \"1 1 \" << l << \" \" << r << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nstring compare_groups(const vector<int>& a, const vector<int>& b) {\n    cout << a.size() << \" \" << b.size();\n    for (int x : a) cout << \" \" << x;\n    for (int x : b) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\n// Estimate minimum comparisons needed to sort N items\nint estimate_sort_comparisons(int n) {\n    // Use information-theoretic bound: log3(n!) / log3(2) \u2248 log2(n!)/log2(3)\n    double log2_fact = 0.0;\n    for (int i = 2; i <= n; i++) {\n        log2_fact += log2(i);\n    }\n    return static_cast<int>(ceil(log2_fact / log2(3.0)));\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    // Initialize random generator for shuffling\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    // Create initial order and shuffle\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    \n    vector<int> sorted;\n    sorted.reserve(N);\n    \n    // Calculate requirements\n    int greedy_comparisons = (N - D) * (D - 1);\n    int min_full_sort = estimate_sort_comparisons(N);\n    \n    // Strategy selection\n    bool use_greedy = false;\n    int sort_comparisons_limit = Q;\n    int refinement_queries = 0;\n    \n    if (Q >= min_full_sort + greedy_comparisons + 50) {\n        // Enough for full sort + greedy + refinement\n        use_greedy = true;\n        sort_comparisons_limit = min_full_sort;\n        refinement_queries = Q - (min_full_sort + greedy_comparisons);\n    } else if (Q >= min_full_sort + greedy_comparisons) {\n        // Enough for full sort + greedy (no refinement)\n        use_greedy = true;\n        sort_comparisons_limit = min_full_sort;\n    } else if (Q >= greedy_comparisons + 300 && N <= 80) {\n        // For smaller N, we can get by with fewer sorting comparisons\n        use_greedy = true;\n        sort_comparisons_limit = Q - greedy_comparisons;\n    } else {\n        // Not enough for greedy, use snake order\n        use_greedy = false;\n        sort_comparisons_limit = Q;\n    }\n    \n    // Binary insertion sort with limited comparisons\n    for (int x : order) {\n        if (used >= sort_comparisons_limit) {\n            sorted.push_back(x);\n            continue;\n        }\n        \n        int low = 0, high = sorted.size();\n        while (low < high && used < sort_comparisons_limit) {\n            int mid = (low + high) / 2;\n            string res = do_query(x, sorted[mid]);\n            \n            bool mid_is_heavier;\n            if (res == \">\") {\n                mid_is_heavier = true;\n            } else if (res == \"<\") {\n                mid_is_heavier = false;\n            } else {\n                // Tie-break by index\n                mid_is_heavier = (sorted[mid] < x);\n            }\n            \n            if (mid_is_heavier) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        sorted.insert(sorted.begin() + low, x);\n    }\n    \n    vector<int> group(N);\n    \n    if (use_greedy) {\n        // Greedy assignment: assign to smallest group using comparisons\n        vector<vector<int>> groups(D);\n        \n        // First assign the heaviest D items to different groups\n        for (int i = 0; i < D && i < sorted.size(); i++) {\n            groups[i].push_back(sorted[i]);\n        }\n        \n        // Then assign remaining items to smallest group\n        for (int i = D; i < sorted.size(); i++) {\n            int item = sorted[i];\n            \n            // Find smallest group\n            int min_group = 0;\n            for (int g = 1; g < D; g++) {\n                if (groups[min_group].empty()) {\n                    min_group = g;\n                    continue;\n                }\n                if (groups[g].empty()) {\n                    min_group = g;\n                    continue;\n                }\n                \n                string res = compare_groups(groups[min_group], groups[g]);\n                if (res == \">\") {\n                    min_group = g;\n                } else if (res == \"=\") {\n                    // Keep current min_group if equal\n                    continue;\n                }\n            }\n            \n            groups[min_group].push_back(item);\n        }\n        \n        // Convert groups to assignment array\n        for (int g = 0; g < D; g++) {\n            for (int item : groups[g]) {\n                group[item] = g;\n            }\n        }\n    } else {\n        // Snake order assignment (fallback)\n        int cur_group = 0;\n        int step = 1;\n        for (int idx : sorted) {\n            group[idx] = cur_group;\n            cur_group += step;\n            if (cur_group == D) {\n                cur_group = D - 1;\n                step = -1;\n            } else if (cur_group == -1) {\n                cur_group = 0;\n                step = 1;\n            }\n        }\n    }\n    \n    // Use any remaining queries for refinement (if we have them)\n    // Simple refinement: compare all pairs of groups and log the results\n    // This doesn't change the assignment but uses up queries\n    while (used < Q) {\n        do_query(0, 1);\n    }\n    \n    // Output the division\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << group[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        int cnt = n / m;\n        stacks[i].resize(cnt);\n        for (int j = 0; j < cnt; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    vector<pair<int, int>> ops;\n    int next_box = 1;\n\n    while (next_box <= n) {\n        // locate the current smallest box\n        int s = -1, idx = -1;\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == next_box) {\n                    s = i;\n                    idx = j;\n                    break;\n                }\n            }\n            if (s != -1) break;\n        }\n\n        if (idx == (int)stacks[s].size() - 1) {\n            // already on top -> carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        } else {\n            // need to move the segment above it\n            int w = stacks[s][idx + 1]; // the box directly above\n\n            // choose destination stack\n            int d = -1;\n            // prefer an empty stack\n            for (int i = 0; i < m; ++i) {\n                if (i != s && stacks[i].empty()) {\n                    d = i;\n                    break;\n                }\n            }\n            if (d == -1) {\n                // choose the stack with the largest top\n                int max_top = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i != s && !stacks[i].empty()) {\n                        int top_val = stacks[i].back();\n                        if (top_val > max_top) {\n                            max_top = top_val;\n                            d = i;\n                        }\n                    }\n                }\n            }\n            // fallback (should never happen because m >= 2)\n            if (d == -1) {\n                for (int i = 0; i < m; ++i) {\n                    if (i != s) {\n                        d = i;\n                        break;\n                    }\n                }\n            }\n\n            // operation 1: move w and everything above it to stack d\n            ops.emplace_back(w, d + 1); // output 1\u2011based index\n\n            // perform the move\n            vector<int> segment(stacks[s].begin() + idx + 1, stacks[s].end());\n            stacks[s].resize(idx + 1);          // keep only boxes up to and including next_box\n            stacks[d].insert(stacks[d].end(), segment.begin(), segment.end());\n\n            // now next_box is on top of stack s -> carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        }\n    }\n\n    // output the sequence\n    for (auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_NODES = MAX_N * MAX_N;\nconst int DIRS = 4;\nconst int di[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dj[DIRS] = {0, 0, -1, 1};\nconst char dir_char[DIRS] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<array<int, 4>> neighbors; // neighbors[node][dir] = neighbor index or -1\nvector<vector<int>> dist;         // dist[s][t]\nvector<vector<int>> next_move;    // next_move[s][t] = direction from s to t\n\n// Build graph from walls\nvoid build_graph() {\n    int total = N * N;\n    neighbors.assign(total, {-1, -1, -1, -1});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node = i * N + j;\n            // down\n            if (i < N-1 && h[i][j] == '0') {\n                int ni = i+1, nj = j;\n                int nnode = ni * N + nj;\n                neighbors[node][1] = nnode; // D\n                neighbors[nnode][0] = node; // U\n            }\n            // right\n            if (j < N-1 && v[i][j] == '0') {\n                int ni = i, nj = j+1;\n                int nnode = ni * N + nj;\n                neighbors[node][3] = nnode; // R\n                neighbors[nnode][2] = node; // L\n            }\n        }\n    }\n}\n\n// Precompute all-pairs shortest paths and next moves\nvoid precompute_paths() {\n    int total = N * N;\n    dist.assign(total, vector<int>(total, -1));\n    next_move.assign(total, vector<int>(total, -1));\n    for (int s = 0; s < total; ++s) {\n        queue<int> q;\n        q.push(s);\n        dist[s][s] = 0;\n        next_move[s][s] = -1;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int v = neighbors[u][dir];\n                if (v == -1) continue;\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    if (u == s) {\n                        next_move[s][v] = dir;\n                    } else {\n                        next_move[s][v] = next_move[s][u];\n                    }\n                    q.push(v);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(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    build_graph();\n    precompute_paths();\n\n    int total_nodes = N * N;\n    int home = 0; // (0,0)\n\n    // Phase 1: visit all squares at least once\n    string moves;\n    vector<int> m(total_nodes, 0); // visit counts\n    vector<bool> visited(total_nodes, false);\n    int visited_count = 0;\n    int current = home;\n\n    // First move: go to neighbor with highest d\n    int best_dir = -1;\n    int best_d = -1;\n    for (int dir = 0; dir < DIRS; ++dir) {\n        int nb = neighbors[current][dir];\n        if (nb == -1) continue;\n        int i = nb / N, j = nb % N;\n        if (d[i][j] > best_d) {\n            best_d = d[i][j];\n            best_dir = dir;\n        }\n    }\n    // If no neighbor (should not happen), take any\n    if (best_dir == -1) {\n        for (int dir = 0; dir < DIRS; ++dir) {\n            if (neighbors[current][dir] != -1) {\n                best_dir = dir;\n                break;\n            }\n        }\n    }\n    moves += dir_char[best_dir];\n    current = neighbors[current][best_dir];\n    m[current]++;\n    visited[current] = true;\n    visited_count++;\n\n    // Visit remaining squares using nearest unvisited heuristic\n    while (visited_count < total_nodes) {\n        int best_u = -1;\n        int best_dist = 1e9;\n        for (int u = 0; u < total_nodes; ++u) {\n            if (!visited[u]) {\n                int d = dist[current][u];\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_u = u;\n                }\n            }\n        }\n        while (current != best_u) {\n            int dir = next_move[current][best_u];\n            moves += dir_char[dir];\n            current = neighbors[current][dir];\n            m[current]++;\n            if (!visited[current]) {\n                visited[current] = true;\n                visited_count++;\n            }\n        }\n    }\n\n    // Return home\n    while (current != home) {\n        int dir = next_move[current][home];\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        if (!visited[current]) {\n            visited[current] = true;\n            visited_count++;\n        }\n    }\n\n    // Phase 2: greedy walk biased towards high d\n    const int L_max = 100000;\n    int current_length = moves.size();\n    while (current_length < L_max) {\n        int remaining = L_max - current_length;\n        int dist_home = dist[current][home];\n        if (remaining == dist_home) break;\n\n        double best_score = -1.0;\n        int best_dir = -1;\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb == -1) continue;\n            int new_dist_home = dist[nb][home];\n            if (remaining - 1 >= new_dist_home) {\n                int i = nb / N, j = nb % N;\n                double score = d[i][j] / (m[nb] + 1.0);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n        }\n        if (best_dir == -1) break; // no safe move, go home\n\n        moves += dir_char[best_dir];\n        current = neighbors[current][best_dir];\n        m[current]++;\n        current_length++;\n    }\n\n    // Final return home\n    while (current != home) {\n        int dir = next_move[current][home];\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        current_length++;\n    }\n\n    // Output\n    cout << moves << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int M_MAX = 200;\nusing Bits = bitset<M_MAX>;\n\n// Rolling hash parameters\nconst uint64_t BASE = 91138233;\nconst int MAX_LEN = 2000;\nvector<uint64_t> POW(MAX_LEN + 1);\n\nstruct MyString {\n    string s;\n    Bits cov;\n    vector<uint64_t> pref;\n    int len;\n\n    MyString(string s_, Bits cov_) : s(move(s_)), cov(cov_), len(s.size()) {\n        pref.resize(len + 1);\n        pref[0] = 0;\n        for (int i = 0; i < len; ++i) {\n            pref[i + 1] = pref[i] * BASE + (s[i] - 'A' + 1);\n        }\n    }\n\n    uint64_t get_hash(int l, int r) const {\n        return pref[r + 1] - pref[l] * POW[r - l + 1];\n    }\n};\n\n// Helper: compute which patterns appear in a string\nunordered_map<string, int> pat_to_idx_global;\nBits compute_cov(const string& s) {\n    Bits bs;\n    int L = s.size();\n    for (int i = 0; i <= L - 5; ++i) {\n        string sub = s.substr(i, 5);\n        auto it = pat_to_idx_global.find(sub);\n        if (it != pat_to_idx_global.end()) {\n            bs.set(it->second);\n        }\n    }\n    return bs;\n}\n\n// Helper: maximum suffix-prefix overlap\nint overlap(const MyString& a, const MyString& b) {\n    int lo = 0, hi = min(a.len, b.len);\n    while (lo < hi) {\n        int mid = (lo + hi + 1) / 2;\n        uint64_t ha = a.get_hash(a.len - mid, a.len - 1);\n        uint64_t hb = b.get_hash(0, mid - 1);\n        if (ha == hb)\n            lo = mid;\n        else\n            hi = mid - 1;\n    }\n    return lo;\n}\n\n// Pair merging with random tie-breaking\nstring pair_merge_randomized(vector<MyString> initial, mt19937& rng) {\n    vector<MyString> cur = initial;\n    \n    while (cur.size() > 1) {\n        // Remove strings that are subsets of others\n        bool removed = false;\n        for (size_t i = 0; i < cur.size() && !removed; ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                if ((cur[i].cov & cur[j].cov) == cur[j].cov) {\n                    cur.erase(cur.begin() + j);\n                    removed = true;\n                    break;\n                }\n                if ((cur[i].cov & cur[j].cov) == cur[i].cov) {\n                    cur.erase(cur.begin() + i);\n                    removed = true;\n                    break;\n                }\n            }\n        }\n        if (removed) continue;\n\n        // Find all pairs with maximum overlap\n        int best_ov = -1;\n        vector<tuple<size_t, size_t, bool>> candidates; // i, j, rev\n        \n        for (size_t i = 0; i < cur.size(); ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                \n                int ov = overlap(cur[i], cur[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    candidates.clear();\n                    candidates.emplace_back(i, j, false);\n                } else if (ov == best_ov) {\n                    candidates.emplace_back(i, j, false);\n                }\n                \n                ov = overlap(cur[j], cur[i]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    candidates.clear();\n                    candidates.emplace_back(i, j, true);\n                } else if (ov == best_ov) {\n                    candidates.emplace_back(i, j, true);\n                }\n            }\n        }\n        \n        // Randomly select one candidate\n        auto [best_i, best_j, best_rev] = candidates[rng() % candidates.size()];\n        \n        // Merge\n        string new_s;\n        if (!best_rev) {\n            new_s = cur[best_i].s + cur[best_j].s.substr(best_ov);\n        } else {\n            new_s = cur[best_j].s + cur[best_i].s.substr(best_ov);\n        }\n        \n        Bits new_cov = compute_cov(new_s);\n        \n        // Remove the two strings (larger index first)\n        size_t idx1 = best_i, idx2 = best_j;\n        if (idx1 > idx2) swap(idx1, idx2);\n        cur.erase(cur.begin() + idx2);\n        cur.erase(cur.begin() + idx1);\n        cur.emplace_back(move(new_s), new_cov);\n        \n        // Early exit if we have full coverage\n        if (new_cov.all()) {\n            cur = {cur.back()};\n            break;\n        }\n    }\n    \n    return cur[0].s;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Precompute powers\n    POW[0] = 1;\n    for (int i = 1; i <= MAX_LEN; ++i) {\n        POW[i] = POW[i - 1] * BASE;\n    }\n\n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<string> patterns(M);\n    for (int k = 0; k < M; ++k) {\n        cin >> patterns[k];\n        pat_to_idx_global[patterns[k]] = k;\n    }\n\n    // Keyboard data\n    vector<vector<int>> pos_for_char(26);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            pos_for_char[c - 'A'].push_back(i * N + j);\n        }\n    }\n\n    const int CELLS = N * N;\n    vector<vector<int>> dist(CELLS, vector<int>(CELLS));\n    for (int id1 = 0; id1 < CELLS; ++id1) {\n        int x1 = id1 / N, y1 = id1 % N;\n        for (int id2 = 0; id2 < CELLS; ++id2) {\n            int x2 = id2 / N, y2 = id2 % N;\n            dist[id1][id2] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // Create initial MyString objects\n    vector<MyString> initial;\n    for (int k = 0; k < M; ++k) {\n        Bits b;\n        b.set(k);\n        initial.emplace_back(patterns[k], b);\n    }\n\n    // Multi-start randomized pair merging\n    random_device rd;\n    mt19937 rng(rd());\n    const int NUM_TRIALS = 10;\n    string best_string;\n    int best_len = INT_MAX;\n    \n    for (int trial = 0; trial < NUM_TRIALS; ++trial) {\n        // Shuffle initial patterns\n        shuffle(initial.begin(), initial.end(), rng);\n        string candidate = pair_merge_randomized(initial, rng);\n        if (candidate.size() < best_len) {\n            best_len = candidate.size();\n            best_string = candidate;\n        }\n    }\n\n    // DP for optimal key sequence\n    int L = best_string.size();\n    struct State {\n        int id;\n        int cost;\n        int prev_idx;\n    };\n    vector<vector<State>> states(L);\n\n    int start_id = si * N + sj;\n    for (int id : pos_for_char[best_string[0] - 'A']) {\n        states[0].push_back({id, dist[start_id][id] + 1, -1});\n    }\n\n    for (int i = 1; i < L; ++i) {\n        char c = best_string[i];\n        vector<int> cur_ids = pos_for_char[c - 'A'];\n        vector<State> cur_states;\n        for (int id : cur_ids) {\n            int best_cost = INT_MAX;\n            int best_prev = -1;\n            for (size_t idx = 0; idx < states[i - 1].size(); ++idx) {\n                const State& prev = states[i - 1][idx];\n                int cand = prev.cost + dist[prev.id][id] + 1;\n                if (cand < best_cost) {\n                    best_cost = cand;\n                    best_prev = idx;\n                }\n            }\n            cur_states.push_back({id, best_cost, best_prev});\n        }\n        states[i] = move(cur_states);\n    }\n\n    // Find best final state\n    int best_idx = 0;\n    int best_cost = states[L - 1][0].cost;\n    for (size_t i = 1; i < states[L - 1].size(); ++i) {\n        if (states[L - 1][i].cost < best_cost) {\n            best_cost = states[L - 1][i].cost;\n            best_idx = i;\n        }\n    }\n\n    // Backtrack to get path\n    vector<int> path_ids(L);\n    int idx = best_idx;\n    for (int i = L - 1; i >= 0; --i) {\n        path_ids[i] = states[i][idx].id;\n        idx = states[i][idx].prev_idx;\n    }\n\n    // Output\n    for (int id : path_ids) {\n        int x = id / N, y = id % N;\n        cout << x << ' ' << y << '\\n';\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    // Read shapes (not used in this approach)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        for (int s = 0; s < d; ++s) {\n            int i, j;\n            cin >> i >> j;\n        }\n    }\n\n    vector<pair<int, int>> positives;\n    vector<vector<bool>> drilled(N, vector<bool>(N, false));\n    queue<pair<int, int>> q;\n\n    // Helper function to drill a square\n    auto drill = [&](int i, int j) {\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        int val;\n        cin >> val;\n        return val;\n    };\n\n    // Initial sparse drilling: checkerboard pattern\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if ((i + j) % 2 == 0) {\n                int val = drill(i, j);\n                drilled[i][j] = true;\n                if (val > 0) {\n                    positives.emplace_back(i, j);\n                    // Add neighbors to queue\n                    if (i + 1 < N) q.emplace(i + 1, j);\n                    if (i - 1 >= 0) q.emplace(i - 1, j);\n                    if (j + 1 < N) q.emplace(i, j + 1);\n                    if (j - 1 >= 0) q.emplace(i, j - 1);\n                }\n            }\n        }\n    }\n\n    // BFS from queued squares\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (drilled[i][j]) continue;\n        \n        int val = drill(i, j);\n        drilled[i][j] = true;\n        if (val > 0) {\n            positives.emplace_back(i, j);\n            // Add neighbors\n            if (i + 1 < N && !drilled[i + 1][j]) q.emplace(i + 1, j);\n            if (i - 1 >= 0 && !drilled[i - 1][j]) q.emplace(i - 1, j);\n            if (j + 1 < N && !drilled[i][j + 1]) q.emplace(i, j + 1);\n            if (j - 1 >= 0 && !drilled[i][j - 1]) q.emplace(i, j - 1);\n        }\n    }\n\n    // Output final guess\n    cout << \"a \" << positives.size();\n    for (auto [i, j] : positives) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    cout.flush();\n    \n    int resp;\n    cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int area;\n};\n\n// tries to pack rectangles with desired areas B (sorted descending) using common row height H\n// returns true and fills rects if successful\nbool pack(int W, int H, const vector<int>& B, vector<Rect>& rects) {\n    int N = B.size();\n    vector<int> w(N);\n    for (int i = 0; i < N; ++i) {\n        w[i] = (B[i] + H - 1) / H;          // width needed for area at least B[i]\n        if (w[i] > W) return false;         // too wide to fit\n    }\n    // indices sorted by width descending (first-fit decreasing)\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    vector<int> row_used;                     // used width in each row\n    vector<vector<pair<int, int>>> row_items; // each row: (rectangle index, start_x)\n\n    for (int i : idx) {\n        int placed = -1;\n        for (int r = 0; r < (int)row_used.size(); ++r) {\n            if (row_used[r] + w[i] <= W) {\n                placed = r;\n                break;\n            }\n        }\n        if (placed == -1) {                   // start new row\n            row_used.push_back(w[i]);\n            row_items.push_back({{i, 0}});\n        } else {\n            int start_x = row_used[placed];\n            row_used[placed] += w[i];\n            row_items[placed].emplace_back(i, start_x);\n        }\n    }\n\n    int rows = row_used.size();\n    if (rows * H > W) return false;           // total height exceeds W\n\n    rects.assign(N, Rect());\n    for (int r = 0; r < rows; ++r) {\n        int y0 = r * H;\n        int y1 = y0 + H;\n        for (auto& p : row_items[r]) {\n            int id = p.first;\n            int x0 = p.second;\n            rects[id].x0 = x0;\n            rects[id].x1 = x0 + w[id];\n            rects[id].y0 = y0;\n            rects[id].y1 = y1;\n            rects[id].area = w[id] * H;\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    cin >> W >> D >> N;\n\n    vector<vector<int>> a_original(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a_original[d][k];\n\n    // ----- build descending demands per day -----\n    vector<vector<int>> a_desc(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        a_desc[d] = a_original[d];\n        sort(a_desc[d].begin(), a_desc[d].end(), greater<int>());\n    }\n\n    // ----- for each position i (i-th largest) collect values over days -----\n    vector<vector<int>> slot_vals(N, vector<int>(D));\n    for (int i = 0; i < N; ++i) {\n        for (int d = 0; d < D; ++d)\n            slot_vals[i][d] = a_desc[d][i];\n        sort(slot_vals[i].begin(), slot_vals[i].end(), greater<int>());\n    }\n\n    // ----- water filling to obtain optimal target areas b[i] -----\n    vector<int> b(N, 0);\n    vector<int> ptr(N, D);                // number of values > current b[i]\n    using P = pair<int, int>;\n    priority_queue<P> pq;                 // max-heap by f = ptr\n    for (int i = 0; i < N; ++i)\n        pq.emplace(ptr[i], i);\n\n    const int S = W * W;\n    int total_used = 0;\n    while (total_used < S && !pq.empty()) {\n        auto [f, i] = pq.top();\n        pq.pop();\n        if (f != ptr[i]) continue;        // outdated entry\n        if (f == 0) break;                // no further improvement possible\n        // add one unit to rectangle i\n        b[i]++;\n        total_used++;\n        // update ptr[i]\n        while (ptr[i] > 0 && slot_vals[i][ptr[i] - 1] <= b[i])\n            ptr[i]--;\n        pq.emplace(ptr[i], i);\n    }\n\n    // b now contains the desired areas; sort them descending\n    vector<int> B = b;\n    sort(B.begin(), B.end(), greater<int>());\n\n    // ----- pack rectangles into the W x W square -----\n    vector<Rect> rects;\n    int H_min = 0;\n    for (int bi : B)\n        H_min = max(H_min, (bi + W - 1) / W);   // smallest H such that width <= W\n\n    bool packed = false;\n    auto pack_lambda = [&](int H, const vector<int>& B, vector<Rect>& rects) -> bool {\n        return pack(W, H, B, rects);\n    };\n    for (int H = H_min; H <= W; ++H) {\n        if (pack_lambda(H, B, rects)) {\n            packed = true;\n            break;\n        }\n    }\n    if (!packed) {   // fallback: vertical strips of almost equal width\n        int Nrect = B.size();\n        vector<int> widths(Nrect, W / Nrect);\n        int rem = W % Nrect;\n        for (int i = 0; i < rem; ++i) widths[i]++;\n        rects.resize(Nrect);\n        int x = 0;\n        for (int i = 0; i < Nrect; ++i) {\n            rects[i].x0 = x;\n            rects[i].x1 = x + widths[i];\n            rects[i].y0 = 0;\n            rects[i].y1 = W;\n            rects[i].area = widths[i] * W;\n            x += widths[i];\n        }\n    }\n\n    // ----- order rectangles by area (largest first) -----\n    vector<int> rect_order(N);\n    iota(rect_order.begin(), rect_order.end(), 0);\n    sort(rect_order.begin(), rect_order.end(),\n         [&](int i, int j) { return rects[i].area > rects[j].area; });\n\n    // ----- assign rectangles to reservations each day -----\n    vector<vector<int>> assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int, int>> dem;   // (demand, original index)\n        for (int k = 0; k < N; ++k)\n            dem.emplace_back(a_original[d][k], k);\n        sort(dem.begin(), dem.end(), greater<pair<int, int>>());\n        for (int t = 0; t < N; ++t) {\n            int orig_k = dem[t].second;\n            int ridx = rect_order[t];\n            assign[d][orig_k] = ridx;\n        }\n    }\n\n    // ----- output -----\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int r = assign[d][k];\n            cout << rects[r].x0 << \" \" << rects[r].y0 << \" \"\n                 << rects[r].x1 << \" \" << rects[r].y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll MOD = 998244353;\n\nll mod(ll x) {\n    return ((x % MOD) + MOD) % MOD;\n}\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<vector<ll>> a(N, vector<ll>(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    vector<vector<vector<ll>>> s(M, vector<vector<ll>>(3, vector<ll>(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    // Greedy initial solution\n    vector<vector<ll>> board = a;\n    vector<tuple<int, int, int>> ops;\n    for (int step = 0; step < K; ++step) {\n        ll best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll gain = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int i = p + di, j = q + dj;\n                            ll old_val = board[i][j];\n                            ll add = s[m][di][dj];\n                            ll new_val = old_val + add;\n                            gain += mod(new_val) - mod(old_val);\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int i = best_p + di, j = best_q + dj;\n                board[i][j] += s[best_m][di][dj];\n            }\n        }\n        ops.emplace_back(best_m, best_p, best_q);\n    }\n\n    // Compute current score\n    ll current_score = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_score += mod(board[i][j]);\n        }\n    }\n    ll best_score = current_score;\n    auto best_board = board;\n    auto best_ops = ops;\n\n    // Simulated Annealing\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_op(0, M - 1);\n    uniform_int_distribution<int> rand_pos(0, N - 3);\n\n    const int SA_ITER = 20000;\n    double T = 1e9;\n    const double cooling = 0.9999;\n\n    int L = ops.size();\n    for (int iter = 0; iter < SA_ITER; ++iter) {\n        if (L == 0 && K == 0) break;\n        int move_type;\n        if (L == 0) move_type = 0; // add\n        else if (L == K) move_type = uniform_int_distribution<int>(1, 2)(rng); // remove or replace\n        else move_type = uniform_int_distribution<int>(0, 2)(rng);\n\n        ll delta = 0;\n        if (move_type == 0) { // add\n            if (L >= K) continue;\n            int m = rand_op(rng);\n            int p = rand_pos(rng);\n            int q = rand_pos(rng);\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val + s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] += s[m][di][dj];\n                    }\n                }\n                ops.emplace_back(m, p, q);\n                L++;\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else if (move_type == 1) { // remove\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m, p, q] = ops[idx];\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val - s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] -= s[m][di][dj];\n                    }\n                }\n                ops.erase(ops.begin() + idx);\n                L--;\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else { // replace\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m_old, p_old, q_old] = ops[idx];\n            int m_new = rand_op(rng);\n            int p_new = rand_pos(rng);\n            int q_new = rand_pos(rng);\n            // Collect union of cells\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p_old + di, q_old + dj});\n                    cells.insert({p_new + di, q_new + dj});\n                }\n            }\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                if (i >= p_old && i < p_old + 3 && j >= q_old && j < q_old + 3) {\n                    int di = i - p_old, dj = j - q_old;\n                    new_val -= s[m_old][di][dj];\n                }\n                if (i >= p_new && i < p_new + 3 && j >= q_new && j < q_new + 3) {\n                    int di = i - p_new, dj = j - q_new;\n                    new_val += s[m_new][di][dj];\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_old + di, j = q_old + dj;\n                        board[i][j] -= s[m_old][di][dj];\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_new + di, j = q_new + dj;\n                        board[i][j] += s[m_new][di][dj];\n                    }\n                }\n                ops[idx] = {m_new, p_new, q_new};\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        }\n        T *= cooling;\n    }\n\n    // Output the best found solution\n    cout << best_ops.size() << \"\\n\";\n    for (auto [m, p, q] : best_ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    const int N = 5;\n    int A[N][N];\n    int grid[N][N];\n    pair<int, int> pos_of[25];          // position of each container on the grid, (-1,-1) if not present\n    int next_idx[N] = {0};              // how many containers have been placed from each gate\n    bool dispatched[25] = {false};\n    int next_dispatch = 0;              // not used in decisions but kept for completeness\n\n    // crane state\n    int crane_r = 0, crane_c = 0;\n    int crane_hold = -1;                // -1 means not holding\n\n    // read input\n    int dummy; cin >> dummy;            // N is always 5, but we read it\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // initialise grid and pos_of\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = -1;\n    for (int b = 0; b < 25; ++b)\n        pos_of[b] = {-1, -1};\n\n    vector<char> actions;               // actions of the large crane\n\n    // helper lambdas\n    auto move_towards = [&](int tr, int tc) -> char {\n        if (crane_r != tr)\n            return (tr < crane_r) ? 'U' : 'D';\n        else\n            return (tc < crane_c) ? 'L' : 'R';\n    };\n\n    auto decide = [&]() -> char {\n        if (crane_hold != -1) {\n            // holding a container -> go to its dispatch gate and release\n            int tr = crane_hold / N;\n            int tc = N - 1;\n            if (crane_r == tr && crane_c == tc)\n                return 'Q';\n            return move_towards(tr, tc);\n        } else {\n            // find the best container to pick up (greedy: minimize travel to pick up + travel to dispatch)\n            int best_b = -1;\n            int best_cost = 1e9;\n            int best_r = -1, best_c = -1;\n            for (int b = 0; b < N*N; ++b) {\n                if (pos_of[b].first != -1) { // container is on the grid\n                    int r = pos_of[b].first, c = pos_of[b].second;\n                    int dist_to_container = abs(crane_r - r) + abs(crane_c - c);\n                    int dist_to_dispatch = abs(r - b/N) + abs(c - (N-1));\n                    int total = dist_to_container + dist_to_dispatch;\n                    if (total < best_cost) {\n                        best_cost = total;\n                        best_b = b;\n                        best_r = r;\n                        best_c = c;\n                    }\n                }\n            }\n            if (best_b != -1) {\n                if (crane_r == best_r && crane_c == best_c)\n                    return 'P';\n                return move_towards(best_r, best_c);\n            } else {\n                // no container on grid, wait\n                return '.';\n            }\n        }\n    };\n\n    auto apply = [&](char act) {\n        if (act == 'P') {\n            // pick up\n            crane_hold = grid[crane_r][crane_c];\n            grid[crane_r][crane_c] = -1;\n            pos_of[crane_hold] = {-1, -1};\n        } else if (act == 'Q') {\n            // release\n            int cont = crane_hold;\n            grid[crane_r][crane_c] = cont;\n            pos_of[cont] = {crane_r, crane_c};\n            crane_hold = -1;\n        } else if (act == 'U') {\n            --crane_r;\n        } else if (act == 'D') {\n            ++crane_r;\n        } else if (act == 'L') {\n            --crane_c;\n        } else if (act == 'R') {\n            ++crane_c;\n        } // '.' does nothing\n    };\n\n    // simulation loop\n    const int MAX_TURN = 10000;\n    for (int turn = 1; turn <= MAX_TURN; ++turn) {\n        // ----- step 1 : receiving -----\n        for (int i = 0; i < N; ++i) {\n            if (next_idx[i] < N && grid[i][0] == -1) {\n                // condition: no crane holding a container at this square\n                if (crane_r == i && crane_c == 0 && crane_hold != -1)\n                    continue;   // blocked\n                int cont = A[i][next_idx[i]];\n                grid[i][0] = cont;\n                pos_of[cont] = {i, 0};\n                ++next_idx[i];\n            }\n        }\n\n        // ----- step 2 : actions -----\n        char act = decide();\n        actions.push_back(act);\n        apply(act);\n\n        // ----- step 3 : dispatch -----\n        for (int i = 0; i < N; ++i) {\n            int cont = grid[i][N-1];\n            if (cont != -1) {\n                dispatched[cont] = true;\n                grid[i][N-1] = -1;\n                pos_of[cont] = {-1, -1};\n            }\n        }\n\n        // update next_dispatch (not used in decisions but kept for completeness)\n        while (next_dispatch < N*N && dispatched[next_dispatch])\n            ++next_dispatch;\n\n        // check completion\n        bool all_done = true;\n        for (int b = 0; b < N*N; ++b)\n            if (!dispatched[b]) { all_done = false; break; }\n        if (all_done)\n            break;\n    }\n\n    int T = actions.size();\n    // output for large crane (initially at (0,0))\n    string S0(actions.begin(), actions.end());\n    cout << S0 << endl;\n    // output for the four small cranes: bomb at first turn, then idle\n    for (int i = 1; i < N; ++i) {\n        string Si = 'B' + string(T-1, '.');\n        cout << Si << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<array<int, 3>> supplies, demands;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0)\n                supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0)\n                demands.push_back({i, j, -h[i][j]});\n        }\n    }\n\n    vector<string> ops;\n    int cur_r = 0, cur_c = 0, load = 0;\n\n    auto move_to = [&](int tr, int tc) {\n        while (cur_r > tr) {\n            ops.push_back(\"U\");\n            --cur_r;\n        }\n        while (cur_r < tr) {\n            ops.push_back(\"D\");\n            ++cur_r;\n        }\n        while (cur_c > tc) {\n            ops.push_back(\"L\");\n            --cur_c;\n        }\n        while (cur_c < tc) {\n            ops.push_back(\"R\");\n            ++cur_c;\n        }\n    };\n\n    // Helper function to compute distance\n    auto dist = [&](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n\n    while (!supplies.empty() || !demands.empty()) {\n        if (load == 0) {\n            // Choose supply with best combination of distance and amount\n            int best_idx = -1;\n            double best_score = 1e18;\n            for (int i = 0; i < (int)supplies.size(); ++i) {\n                auto& s = supplies[i];\n                int d = dist(cur_r, cur_c, s[0], s[1]);\n                int amt = s[2];\n                // Score: distance * 100 - amount * 10 (encourage large amounts and short distances)\n                double score = d * 100.0 - amt * 10.0;\n                if (best_idx == -1 || score < best_score) {\n                    best_idx = i;\n                    best_score = score;\n                }\n            }\n            auto& s = supplies[best_idx];\n            move_to(s[0], s[1]);\n            ops.push_back(\"+\" + to_string(s[2]));\n            load += s[2];\n            supplies.erase(supplies.begin() + best_idx);\n        } else {\n            vector<int> feasible;\n            for (int i = 0; i < (int)demands.size(); ++i) {\n                if (demands[i][2] <= load)\n                    feasible.push_back(i);\n            }\n            \n            if (!feasible.empty()) {\n                // Choose demand that minimizes cost: distance * (100 + load) - amount * benefit\n                int best_idx = -1;\n                double best_cost = 1e18;\n                for (int idx : feasible) {\n                    auto& d = demands[idx];\n                    int distance = dist(cur_r, cur_c, d[0], d[1]);\n                    int amount = d[2];\n                    // Cost of moving to demand: distance * (100 + load)\n                    // Benefit of unloading: amount * 50 (empirical value)\n                    double cost = distance * (100.0 + load) - amount * 50.0;\n                    if (best_idx == -1 || cost < best_cost) {\n                        best_idx = idx;\n                        best_cost = cost;\n                    }\n                }\n                auto& d = demands[best_idx];\n                move_to(d[0], d[1]);\n                ops.push_back(\"-\" + to_string(d[2]));\n                load -= d[2];\n                demands.erase(demands.begin() + best_idx);\n            } else {\n                // No feasible demand - go to supply that best balances distance and amount\n                int best_idx = -1;\n                double best_score = 1e18;\n                for (int i = 0; i < (int)supplies.size(); ++i) {\n                    auto& s = supplies[i];\n                    int d = dist(cur_r, cur_c, s[0], s[1]);\n                    int amt = s[2];\n                    // Score: distance * (100 + load) - amount * 20\n                    double score = d * (100.0 + load) - amt * 20.0;\n                    if (best_idx == -1 || score < best_score) {\n                        best_idx = i;\n                        best_score = score;\n                    }\n                }\n                auto& s = supplies[best_idx];\n                move_to(s[0], s[1]);\n                ops.push_back(\"+\" + to_string(s[2]));\n                load += s[2];\n                supplies.erase(supplies.begin() + best_idx);\n            }\n        }\n    }\n\n    for (string& op : ops)\n        cout << op << endl;\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <numeric>\n#include <cmath>\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);  // 60\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    for (int t = 0; t < T; t++) {\n        // Compute sum for each seed\n        vector<int> sum(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            int s = 0;\n            for (int j = 0; j < M; j++) {\n                s += seeds[i][j];\n            }\n            sum[i] = s;\n        }\n\n        // Find seed with max value for each criterion\n        vector<int> max_val(M, -1);\n        vector<int> max_idx(M, -1);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                if (seeds[i][l] > max_val[l]) {\n                    max_val[l] = seeds[i][l];\n                    max_idx[l] = i;\n                }\n            }\n        }\n\n        // Set of important seeds (max per criterion)\n        set<int> important;\n        for (int l = 0; l < M; l++) {\n            important.insert(max_idx[l]);\n        }\n\n        // Sort all seeds by sum descending\n        vector<pair<int, int>> sum_idx;\n        for (int i = 0; i < seed_count; i++) {\n            sum_idx.emplace_back(sum[i], i);\n        }\n        sort(sum_idx.begin(), sum_idx.end(), greater<pair<int, int>>());\n\n        // Select seeds to plant\n        vector<int> selected_orig;  // original indices of selected seeds\n        for (int idx : important) {\n            selected_orig.push_back(idx);\n        }\n        for (auto& p : sum_idx) {\n            if (selected_orig.size() >= 36) break;\n            int idx = p.second;\n            if (important.find(idx) == important.end()) {\n                selected_orig.push_back(idx);\n            }\n        }\n\n        int K = selected_orig.size();  // should be 36\n        // Compute potential matrix for selected seeds\n        vector<vector<int>> pot(K, vector<int>(K, 0));\n        for (int i = 0; i < K; i++) {\n            for (int j = 0; j < K; j++) {\n                if (i == j) continue;\n                int total = 0;\n                for (int l = 0; l < M; l++) {\n                    total += max(seeds[selected_orig[i]][l], seeds[selected_orig[j]][l]);\n                }\n                pot[i][j] = total;\n            }\n        }\n\n        // Compute sums for selected seeds\n        vector<int> selected_sum(K);\n        for (int i = 0; i < K; i++) {\n            selected_sum[i] = sum[selected_orig[i]];\n        }\n\n        // Compute average L1 distance for each seed\n        vector<double> avg_dist(K, 0.0);\n        for (int i = 0; i < K; i++) {\n            double total_l1 = 0.0;\n            for (int j = 0; j < K; j++) {\n                if (i == j) continue;\n                // L1 = 2*pot - sum_i - sum_j\n                total_l1 += 2 * pot[i][j] - selected_sum[i] - selected_sum[j];\n            }\n            avg_dist[i] = total_l1 / (K - 1);\n        }\n\n        // Order to place seeds: descending by average L1 distance\n        vector<int> order(K);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) { return avg_dist[a] > avg_dist[b]; });\n\n        // Grid assignment: grid[i][j] = index in selected_orig (0..K-1)\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n\n        // Greedy placement\n        for (int idx : order) {\n            int best_score = -1;\n            int best_i = -1, best_j = -1;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) continue;\n                    int score = 0;\n                    // Check up, down, left, right\n                    if (i > 0 && grid[i-1][j] != -1) {\n                        score += pot[idx][grid[i-1][j]];\n                    }\n                    if (i < N-1 && grid[i+1][j] != -1) {\n                        score += pot[idx][grid[i+1][j]];\n                    }\n                    if (j > 0 && grid[i][j-1] != -1) {\n                        score += pot[idx][grid[i][j-1]];\n                    }\n                    if (j < N-1 && grid[i][j+1] != -1) {\n                        score += pot[idx][grid[i][j+1]];\n                    }\n                    if (score > best_score) {\n                        best_score = score;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n            // Place seed idx at (best_i, best_j)\n            grid[best_i][best_j] = idx;\n        }\n\n        // Hill climbing: improve total potential sum over edges\n        auto compute_total_potential = [&]() {\n            int total = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    int s1 = grid[i][j];\n                    if (i+1 < N) {\n                        int s2 = grid[i+1][j];\n                        total += pot[s1][s2];\n                    }\n                    if (j+1 < N) {\n                        int s2 = grid[i][j+1];\n                        total += pot[s1][s2];\n                    }\n                }\n            }\n            return total;\n        };\n\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i1 = 0; i1 < N; i1++) {\n                for (int j1 = 0; j1 < N; j1++) {\n                    for (int i2 = i1; i2 < N; i2++) {\n                        for (int j2 = (i2 == i1 ? j1+1 : 0); j2 < N; j2++) {\n                            if (grid[i1][j1] == grid[i2][j2]) continue;\n                            // Try swapping\n                            int s1 = grid[i1][j1];\n                            int s2 = grid[i2][j2];\n                            // Compute current contribution of s1 and s2\n                            int cur = 0;\n                            // neighbors of (i1,j1)\n                            if (i1 > 0 && grid[i1-1][j1] != -1) cur += pot[s1][grid[i1-1][j1]];\n                            if (i1 < N-1 && grid[i1+1][j1] != -1) cur += pot[s1][grid[i1+1][j1]];\n                            if (j1 > 0 && grid[i1][j1-1] != -1) cur += pot[s1][grid[i1][j1-1]];\n                            if (j1 < N-1 && grid[i1][j1+1] != -1) cur += pot[s1][grid[i1][j1+1]];\n                            // neighbors of (i2,j2)\n                            if (i2 > 0 && grid[i2-1][j2] != -1) cur += pot[s2][grid[i2-1][j2]];\n                            if (i2 < N-1 && grid[i2+1][j2] != -1) cur += pot[s2][grid[i2+1][j2]];\n                            if (j2 > 0 && grid[i2][j2-1] != -1) cur += pot[s2][grid[i2][j2-1]];\n                            if (j2 < N-1 && grid[i2][j2+1] != -1) cur += pot[s2][grid[i2][j2+1]];\n                            // Subtract double count if adjacent\n                            if (abs(i1-i2) + abs(j1-j2) == 1) {\n                                cur -= pot[s1][s2]; // counted twice\n                            }\n\n                            // Temporarily swap\n                            swap(grid[i1][j1], grid[i2][j2]);\n                            int s1_new = grid[i1][j1];\n                            int s2_new = grid[i2][j2];\n\n                            int new_contrib = 0;\n                            // neighbors of (i1,j1)\n                            if (i1 > 0 && grid[i1-1][j1] != -1) new_contrib += pot[s1_new][grid[i1-1][j1]];\n                            if (i1 < N-1 && grid[i1+1][j1] != -1) new_contrib += pot[s1_new][grid[i1+1][j1]];\n                            if (j1 > 0 && grid[i1][j1-1] != -1) new_contrib += pot[s1_new][grid[i1][j1-1]];\n                            if (j1 < N-1 && grid[i1][j1+1] != -1) new_contrib += pot[s1_new][grid[i1][j1+1]];\n                            // neighbors of (i2,j2)\n                            if (i2 > 0 && grid[i2-1][j2] != -1) new_contrib += pot[s2_new][grid[i2-1][j2]];\n                            if (i2 < N-1 && grid[i2+1][j2] != -1) new_contrib += pot[s2_new][grid[i2+1][j2]];\n                            if (j2 > 0 && grid[i2][j2-1] != -1) new_contrib += pot[s2_new][grid[i2][j2-1]];\n                            if (j2 < N-1 && grid[i2][j2+1] != -1) new_contrib += pot[s2_new][grid[i2][j2+1]];\n                            if (abs(i1-i2) + abs(j1-j2) == 1) {\n                                new_contrib -= pot[s1_new][s2_new];\n                            }\n\n                            if (new_contrib > cur) {\n                                improved = true;\n                                // keep swap\n                            } else {\n                                // swap back\n                                swap(grid[i1][j1], grid[i2][j2]);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << selected_orig[grid[i][j]];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read next generation if not last turn\n        if (t < T - 1) {\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\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n#include <cstdlib>\n#include <cassert>\n#include <climits>\n\nusing namespace std;\n\n// Directions: 0:right, 1:down, 2:left, 3:up\nconst int dr[4] = {0, 1, 0, -1};\nconst int dc[4] = {1, 0, -1, 0};\n\nint N, M, V;\nint V_prime;          // number of vertices used\nint K;                // number of leaves = V_prime-1\nvector<int> len;      // length of each leaf (1-indexed, len[i] for leaf i)\nint root_r, root_c;   // current root position\nvector<int> dir;      // direction of each leaf (1-indexed)\nvector<bool> holding; // whether leaf i holds a takoyaki\nbool src_rem[30][30]; // remaining source squares\nbool tgt_rem[30][30]; // remaining target squares\nint src_cnt, tgt_cnt; // counts\n\n// Helper functions\ninline bool in_grid(int r, int c) {\n    return 0 <= r && r < N && 0 <= c && c < N;\n}\n\n// Output one turn\nvoid output_turn(char move, const vector<char>& rot, const vector<char>& act) {\n    string S(2 * V_prime, '.');\n    S[0] = move;\n    for (int i = 1; i <= K; ++i) {\n        S[i] = rot[i];\n    }\n    for (int i = 0; i <= K; ++i) {\n        if (act[i] == 'P') {\n            S[V_prime + i] = 'P';\n        }\n    }\n    cout << S << '\\n';\n}\n\n// Move root to (tr,tc) while rotating leaf `leaf` to direction `des_dir`.\n// Performs one step per turn, rotating the leaf as much as possible.\nvoid move_root_to(int tr, int tc, int leaf, int des_dir) {\n    while (root_r != tr || root_c != tc) {\n        // Determine movement direction\n        char move_char;\n        if (tr > root_r) move_char = 'D';\n        else if (tr < root_r) move_char = 'U';\n        else if (tc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Rotation for the leaf we are controlling\n        char rot_leaf = '.';\n        if (leaf != -1 && dir[leaf] != des_dir) {\n            int diff = (des_dir - dir[leaf] + 4) % 4;\n            if (diff == 1) {\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            } else if (diff == 3) {\n                rot_leaf = 'L';\n                dir[leaf] = (dir[leaf] + 3) % 4;\n            } else { // diff == 2, rotate arbitrarily (choose R)\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            }\n        }\n\n        vector<char> rot(K+1, '.');\n        if (leaf != -1) rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.'); // no pick/drop during movement\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        if (move_char == 'U') root_r--;\n        else if (move_char == 'D') root_r++;\n        else if (move_char == 'L') root_c--;\n        else if (move_char == 'R') root_c++;\n    }\n\n    // After reaching the target, finish rotation if needed\n    while (leaf != -1 && dir[leaf] != des_dir) {\n        char rot_leaf = '.';\n        int diff = (des_dir - dir[leaf] + 4) % 4;\n        if (diff == 1) {\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        } else if (diff == 3) {\n            rot_leaf = 'L';\n            dir[leaf] = (dir[leaf] + 3) % 4;\n        } else { // diff == 2\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        }\n        vector<char> rot(K+1, '.');\n        rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.');\n        output_turn('.', rot, act);\n    }\n}\n\n// Output a turn with only a pick/drop for a given leaf (no movement, no other rotations)\nvoid output_action(int leaf, char action) {\n    vector<char> rot(K+1, '.');\n    vector<char> act(K+1, '.');\n    act[leaf] = action;\n    output_turn('.', rot, act);\n}\n\n// Find any remaining target square that leaf i can reach, together with a suitable direction.\ntuple<int,int,int> find_target_for_leaf(int i) {\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (tgt_rem[r][c]) {\n                for (int d = 0; d < 4; ++d) {\n                    int nr = r - dr[d] * len[i];\n                    int nc = c - dc[d] * len[i];\n                    if (in_grid(nr, nc)) {\n                        return make_tuple(r, c, d);\n                    }\n                }\n            }\n        }\n    }\n    // should never happen\n    return make_tuple(-1, -1, -1);\n}\n\n// Find any remaining source square\npair<int,int> find_source() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (src_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Find any remaining target square\npair<int,int> find_target() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (tgt_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Try to stay in place to rotate a leaf 180\u00b0 and drop if possible.\n// Returns true if we performed stay turns.\nbool try_stay_and_drop() {\n    for (int i = 1; i <= K; ++i) {\n        if (!holding[i]) continue;\n        for (int d = 0; d < 4; ++d) {\n            int pr = root_r + dr[d] * len[i];\n            int pc = root_c + dc[d] * len[i];\n            if (!in_grid(pr, pc) || !tgt_rem[pr][pc]) continue;\n            int delta = (d - dir[i] + 4) % 4;\n            if (delta == 2) { // 180\u00b0 rotation needed\n                // We'll rotate twice (choose R,R) and drop on the second turn.\n                // First turn: rotate 90\u00b0 (R)\n                vector<char> rot1(K+1, '.');\n                rot1[i] = 'R';\n                vector<char> act1(K+1, '.');\n                output_turn('.', rot1, act1);\n                dir[i] = (dir[i] + 1) % 4;\n                \n                // Second turn: rotate another 90\u00b0 (R) and drop\n                vector<char> rot2(K+1, '.');\n                rot2[i] = 'R';\n                vector<char> act2(K+1, '.');\n                act2[i] = 'P';\n                output_turn('.', rot2, act2);\n                dir[i] = (dir[i] + 1) % 4; // now equals d\n                holding[i] = false;\n                tgt_rem[pr][pc] = false;\n                --tgt_cnt;\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N >> M >> V;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Determine sources and targets (remove overlaps)\n    src_cnt = tgt_cnt = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool s = (s_grid[i][j] == '1');\n            bool t = (t_grid[i][j] == '1');\n            if (s && t) {\n                // already in place, ignore\n                src_rem[i][j] = false;\n                tgt_rem[i][j] = false;\n            } else if (s) {\n                src_rem[i][j] = true;\n                ++src_cnt;\n                tgt_rem[i][j] = false;\n            } else if (t) {\n                tgt_rem[i][j] = true;\n                ++tgt_cnt;\n                src_rem[i][j] = false;\n            } else {\n                src_rem[i][j] = tgt_rem[i][j] = false;\n            }\n        }\n    }\n\n    // Design the arm: star with root 0 and leaves 1..K, lengths = 1,2,...,K\n    V_prime = V;                // use all vertices\n    K = V_prime - 1;\n    len.resize(K+1);\n    for (int i = 1; i <= K; ++i) len[i] = i;   // guaranteed i <= N-1 because N>=15, K<=14\n\n    // Initial root position (choose (0,0))\n    root_r = 0; root_c = 0;\n\n    // Output arm design\n    cout << V_prime << '\\n';\n    for (int i = 1; i <= K; ++i) {\n        cout << \"0 \" << len[i] << '\\n';\n    }\n    cout << root_r << ' ' << root_c << '\\n';\n\n    // Initialize state\n    dir.assign(K+1, 0);          // all initially point right\n    holding.assign(K+1, false);\n\n    // Snake traversal: generate order of cells\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        } else {\n            for (int j = N-1; j >= 0; --j) cells.emplace_back(i, j);\n        }\n    }\n\n    // Perform moves along the snake\n    size_t idx = 0;\n    while (idx < cells.size() - 1) {\n        int nr = cells[idx+1].first;\n        int nc = cells[idx+1].second;\n\n        // Determine movement character\n        char move_char;\n        if (nr > root_r) move_char = 'D';\n        else if (nr < root_r) move_char = 'U';\n        else if (nc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Greedy assignment of picks/drops at the new position\n        vector<bool> used(K+1, false);\n        vector<int> desired_dir(K+1, -1);\n        vector<char> action(K+1, '.');\n\n        // Drops first\n        for (int i = 1; i <= K; ++i) {\n            if (holding[i] && !used[i]) {\n                // Try the three reachable directions (current, left, right)\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && tgt_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = false;\n                        tgt_rem[pr][pc] = false;\n                        --tgt_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Picks\n        for (int i = 1; i <= K; ++i) {\n            if (!holding[i] && !used[i]) {\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && src_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = true;\n                        src_rem[pr][pc] = false;\n                        --src_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Build rotation commands\n        vector<char> rot(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (desired_dir[i] != -1) {\n                int delta = (desired_dir[i] - dir[i] + 4) % 4;\n                if (delta == 0) rot[i] = '.';\n                else if (delta == 1) rot[i] = 'R';\n                else if (delta == 3) rot[i] = 'L';\n                // delta == 2 cannot happen because we only used reachable directions\n                dir[i] = desired_dir[i];\n            }\n        }\n\n        // Build action vector (root action always '.')\n        vector<char> act(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (action[i] == 'P') act[i] = 'P';\n        }\n\n        // Output the turn (move to next cell)\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        root_r = nr;\n        root_c = nc;\n        ++idx;\n\n        // After moving, try to stay and drop if beneficial\n        if (try_stay_and_drop()) {\n            // We stayed in place for two turns, root position unchanged.\n            // Continue with the snake from the same position.\n            // Note: we have already incremented idx, so we are at the next cell.\n            // But we haven't moved? Actually we moved to (nr,nc) before staying.\n            // So we are at (nr,nc). That's fine.\n        }\n    }\n\n    // If all takoyaki are already at targets, we are done\n    if (src_cnt == 0 && tgt_cnt == 0) {\n        return 0;\n    }\n\n    // ----- Cleanup phase -----\n    // Step 1: Drop any takoyaki still held by leaves\n    for (int i = 1; i <= K; ++i) {\n        while (holding[i]) {\n            auto [tr, tc, d] = find_target_for_leaf(i);\n            int nr = tr - dr[d] * len[i];\n            int nc = tc - dc[d] * len[i];\n            move_root_to(nr, nc, i, d);\n            output_action(i, 'P');\n            holding[i] = false;\n            tgt_rem[tr][tc] = false;\n            --tgt_cnt;\n        }\n    }\n\n    // Step 2: Move remaining sources to targets using optimal leaf selection\n    while (src_cnt > 0) {\n        // Find the source that can be picked with minimal travel distance\n        int best_dist = INT_MAX;\n        int best_sr = -1, best_sc = -1;\n        int best_leaf = -1, best_dir = -1;\n        int best_nr = -1, best_nc = -1;\n        \n        for (int sr = 0; sr < N; ++sr) {\n            for (int sc = 0; sc < N; ++sc) {\n                if (!src_rem[sr][sc]) continue;\n                for (int i = 1; i <= K; ++i) {\n                    if (holding[i]) continue; // leaf already holding\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = sr - dr[d] * len[i];\n                        int nc = sc - dc[d] * len[i];\n                        if (!in_grid(nr, nc)) continue;\n                        int dist = abs(nr - root_r) + abs(nc - root_c);\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_sr = sr; best_sc = sc;\n                            best_leaf = i; best_dir = d;\n                            best_nr = nr; best_nc = nc;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Should always find a pickable source\n        if (best_dist == INT_MAX) break;\n        \n        // Move to pick position and pick\n        move_root_to(best_nr, best_nc, best_leaf, best_dir);\n        output_action(best_leaf, 'P');\n        holding[best_leaf] = true;\n        src_rem[best_sr][best_sc] = false;\n        --src_cnt;\n        \n        // Now find the best target for this leaf\n        int best_drop_dist = INT_MAX;\n        int best_tr = -1, best_tc = -1;\n        int best_d2 = -1;\n        int best_nr2 = -1, best_nc2 = -1;\n        \n        for (int tr = 0; tr < N; ++tr) {\n            for (int tc = 0; tc < N; ++tc) {\n                if (!tgt_rem[tr][tc]) continue;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int nr2 = tr - dr[d2] * len[best_leaf];\n                    int nc2 = tc - dc[d2] * len[best_leaf];\n                    if (!in_grid(nr2, nc2)) continue;\n                    int dist2 = abs(nr2 - root_r) + abs(nc2 - root_c);\n                    if (dist2 < best_drop_dist) {\n                        best_drop_dist = dist2;\n                        best_tr = tr; best_tc = tc;\n                        best_d2 = d2;\n                        best_nr2 = nr2; best_nc2 = nc2;\n                    }\n                }\n            }\n        }\n        \n        if (best_drop_dist == INT_MAX) {\n            // Should not happen, but just in case: find any target\n            auto [tr, tc, d2] = find_target_for_leaf(best_leaf);\n            best_tr = tr; best_tc = tc; best_d2 = d2;\n            best_nr2 = tr - dr[d2] * len[best_leaf];\n            best_nc2 = tc - dc[d2] * len[best_leaf];\n        }\n        \n        // Move to drop position and drop\n        move_root_to(best_nr2, best_nc2, best_leaf, best_d2);\n        output_action(best_leaf, 'P');\n        holding[best_leaf] = false;\n        tgt_rem[best_tr][best_tc] = false;\n        --tgt_cnt;\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n};\n\nint compute_score(int x1, int x2, int y1, int y2, \n                  const vector<Point>& mack, const vector<Point>& sard) {\n    int a = 0, b = 0;\n    for (const auto& p : mack) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) a++;\n    }\n    for (const auto& p : sard) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) b++;\n    }\n    return max(0, a - b + 1);\n}\n\nvoid local_optimize(int& x1, int& x2, int& y1, int& y2,\n                    const vector<Point>& mack, const vector<Point>& sard,\n                    const vector<int>& xs, const vector<int>& ys) {\n    auto get_next_left = [&](int x) {\n        auto it = lower_bound(xs.begin(), xs.end(), x);\n        if (it == xs.begin()) return x;\n        return *(--it);\n    };\n    auto get_next_right = [&](int x) {\n        auto it = upper_bound(xs.begin(), xs.end(), x);\n        if (it == xs.end()) return x;\n        return *it;\n    };\n    auto get_next_bottom = [&](int y) {\n        auto it = lower_bound(ys.begin(), ys.end(), y);\n        if (it == ys.begin()) return y;\n        return *(--it);\n    };\n    auto get_next_top = [&](int y) {\n        auto it = upper_bound(ys.begin(), ys.end(), y);\n        if (it == ys.end()) return y;\n        return *it;\n    };\n\n    int current_score = compute_score(x1, x2, y1, y2, mack, sard);\n    for (int iter = 0; iter < 100; iter++) {\n        bool improved = false;\n        // Try left\n        int new_x1 = get_next_left(x1);\n        if (new_x1 < x1 && new_x1 < x2) {\n            int new_score = compute_score(new_x1, x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = new_x1;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        // Try right\n        int new_x2 = get_next_right(x2);\n        if (new_x2 > x2 && x1 < new_x2) {\n            int new_score = compute_score(x1, new_x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x2 = new_x2;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        // Try bottom\n        int new_y1 = get_next_bottom(y1);\n        if (new_y1 < y1 && new_y1 < y2) {\n            int new_score = compute_score(x1, x2, new_y1, y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = new_y1;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        // Try top\n        int new_y2 = get_next_top(y2);\n        if (new_y2 > y2 && y1 < new_y2) {\n            int new_score = compute_score(x1, x2, y1, new_y2, mack, sard);\n            if (new_score > current_score) {\n                y2 = new_y2;\n                current_score = new_score;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nvector<tuple<int, int, int, int, int>> process_cell_size(int cell_size,\n                                                         const vector<Point>& mack,\n                                                         const vector<Point>& sard) {\n    int num_cells_x = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    int num_cells_y = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    vector<vector<int>> mack_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<vector<int>> sard_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<pair<int, int>> mack_cells(mack.size());\n\n    for (size_t i = 0; i < mack.size(); i++) {\n        int cx = mack[i].x / cell_size;\n        int cy = mack[i].y / cell_size;\n        mack_count[cx][cy]++;\n        mack_cells[i] = {cx, cy};\n    }\n    for (size_t i = 0; i < sard.size(); i++) {\n        int cx = sard[i].x / cell_size;\n        int cy = sard[i].y / cell_size;\n        sard_count[cx][cy]++;\n    }\n\n    vector<vector<int>> weight(num_cells_x, vector<int>(num_cells_y, 0));\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            weight[i][j] = mack_count[i][j] - sard_count[i][j];\n        }\n    }\n\n    vector<vector<bool>> visited(num_cells_x, vector<bool>(num_cells_y, false));\n    vector<vector<pair<int, int>>> components;\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0 && !visited[i][j]) {\n                vector<pair<int, int>> comp;\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();\n                    q.pop();\n                    comp.push_back({x, y});\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 < num_cells_x && ny >= 0 && ny < num_cells_y &&\n                            weight[nx][ny] > 0 && !visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                components.push_back(comp);\n            }\n        }\n    }\n\n    auto count_mack = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : mack) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) cnt++;\n        }\n        return cnt;\n    };\n\n    auto count_sard = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : sard) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) cnt++;\n        }\n        return cnt;\n    };\n\n    vector<tuple<int, int, int, int, int>> candidates;\n\n    // Cell rectangles\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0) {\n                int x1 = i * cell_size;\n                int x2 = min(MAX_COORD, (i + 1) * cell_size);\n                int y1 = j * cell_size;\n                int y2 = min(MAX_COORD, (j + 1) * cell_size);\n                if (x1 < x2 && y1 < y2) {\n                    int a = count_mack(x1, x2, y1, y2);\n                    int b = count_sard(x1, x2, y1, y2);\n                    int score = max(0, a - b + 1);\n                    candidates.push_back({x1, x2, y1, y2, score});\n                }\n            }\n        }\n    }\n\n    // Component bounding boxes\n    for (const auto& comp : components) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (size_t i = 0; i < mack.size(); i++) {\n            int cx = mack_cells[i].first, cy = mack_cells[i].second;\n            bool found = false;\n            for (const auto& cell : comp) {\n                if (cell.first == cx && cell.second == cy) {\n                    found = true;\n                    break;\n                }\n            }\n            if (found) {\n                min_x = min(min_x, mack[i].x);\n                max_x = max(max_x, mack[i].x);\n                min_y = min(min_y, mack[i].y);\n                max_y = max(max_y, mack[i].y);\n            }\n        }\n        if (min_x == max_x) {\n            min_x = max(0, min_x - 1);\n            max_x = min(MAX_COORD, max_x + 1);\n        }\n        if (min_y == max_y) {\n            min_y = max(0, min_y - 1);\n            max_y = min(MAX_COORD, max_y + 1);\n        }\n        if (min_x < max_x && min_y < max_y) {\n            int a = count_mack(min_x, max_x, min_y, max_y);\n            int b = count_sard(min_x, max_x, min_y, max_y);\n            int score = max(0, a - b + 1);\n            candidates.push_back({min_x, max_x, min_y, max_y, score});\n        }\n    }\n\n    // Union of all positive cells\n    {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (size_t i = 0; i < mack.size(); i++) {\n            int cx = mack_cells[i].first, cy = mack_cells[i].second;\n            if (weight[cx][cy] > 0) {\n                min_x = min(min_x, mack[i].x);\n                max_x = max(max_x, mack[i].x);\n                min_y = min(min_y, mack[i].y);\n                max_y = max(max_y, mack[i].y);\n            }\n        }\n        if (min_x <= max_x && min_y <= max_y) {\n            if (min_x == max_x) {\n                min_x = max(0, min_x - 1);\n                max_x = min(MAX_COORD, max_x + 1);\n            }\n            if (min_y == max_y) {\n                min_y = max(0, min_y - 1);\n                max_y = min(MAX_COORD, max_y + 1);\n            }\n            if (min_x < max_x && min_y < max_y) {\n                int a = count_mack(min_x, max_x, min_y, max_y);\n                int b = count_sard(min_x, max_x, min_y, max_y);\n                int score = max(0, a - b + 1);\n                candidates.push_back({min_x, max_x, min_y, max_y, score});\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mack(N), sard(N);\n    for (int i = 0; i < N; i++) {\n        cin >> mack[i].x >> mack[i].y;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sard[i].x >> sard[i].y;\n    }\n\n    // Precompute sorted unique coordinates for local optimization\n    vector<int> xs, ys;\n    for (const auto& p : mack) {\n        xs.push_back(p.x);\n        ys.push_back(p.y);\n    }\n    for (const auto& p : sard) {\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    vector<int> cell_sizes = {2000, 5000, 10000};\n    vector<tuple<int, int, int, int, int>> all_candidates;\n\n    for (int cell_size : cell_sizes) {\n        auto candidates = process_cell_size(cell_size, mack, sard);\n        all_candidates.insert(all_candidates.end(), candidates.begin(), candidates.end());\n    }\n\n    // Find best candidate\n    int best_score = -1;\n    int best_x1, best_x2, best_y1, best_y2;\n    for (const auto& cand : all_candidates) {\n        auto [x1, x2, y1, y2, score] = cand;\n        if (score > best_score) {\n            best_score = score;\n            best_x1 = x1;\n            best_x2 = x2;\n            best_y1 = y1;\n            best_y2 = y2;\n        }\n    }\n\n    // Apply local optimization to the best candidate\n    if (best_score != -1) {\n        local_optimize(best_x1, best_x2, best_y1, best_y2, mack, sard, xs, ys);\n        best_score = compute_score(best_x1, best_x2, best_y1, best_y2, mack, sard);\n    }\n\n    // Fallback if no candidate found\n    if (best_score == -1) {\n        best_x1 = 0;\n        best_x2 = 1;\n        best_y1 = 0;\n        best_y2 = 1;\n        best_score = 1;\n    }\n\n    // Output as rectangle (4 vertices)\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n\nusing namespace std;\n\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference rectangle, -1 for boundary\n};\n\n// Row-based packing (uses L direction) with skipping\nvector<Placement> generate_row_packing(const vector<int>& w, const vector<int>& h,\n                                       mt19937& rng, double alpha, double noise, double skip_threshold) {\n    int n = w.size();\n    vector<Placement> res;\n    bool shelf_exists = false;\n    int shelf_ref = -1;          // b for the current shelf\n    long long shelf_top = 0;     // y coordinate of the shelf\n    long long shelf_x = 0;       // next x in this shelf\n    long long shelf_max_h = 0;   // max height in this shelf\n    long long overall_width = 0;\n    long long overall_height = 0;\n    int max_bottom_rect = -1;    // rectangle with maximum bottom (y+h)\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        double best_cost = 1e100;\n        int best_r = 0, best_option = 0; // option 0: current shelf, 1: new shelf\n        long long best_delta_w = 0, best_delta_h = 0;\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            // Option: place in current shelf\n            if (shelf_exists) {\n                long long new_width = max(overall_width, shelf_x + wc);\n                long long new_shelf_max_h = max(shelf_max_h, (long long)hc);\n                long long new_height = max(overall_height, shelf_top + new_shelf_max_h);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = delta_w + alpha * delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 0;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n\n            // Option: start a new shelf\n            {\n                long long new_width = max(overall_width, (long long)wc);\n                long long new_height = overall_height + hc;\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = delta_w + alpha * delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 1;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n        }\n\n        // Actual increase in W+H for the chosen placement\n        long long actual_increase = best_delta_w + best_delta_h;\n        // Penalty for skipping: w_i + h_i (using original dimensions, not rotated)\n        long long penalty = w[i] + h[i];\n\n        if (actual_increase > skip_threshold * penalty) {\n            // Skip this rectangle\n            continue;\n        }\n\n        int r = best_r;\n        int wc = (r == 0 ? w[i] : h[i]);\n        int hc = (r == 0 ? h[i] : w[i]);\n\n        if (best_option == 0) { // current shelf\n            int b = shelf_ref;\n            res.push_back({i, r, 'L', b});\n\n            long long x = shelf_x;\n            long long y = shelf_top;\n            shelf_x += wc;\n            shelf_max_h = max(shelf_max_h, (long long)hc);\n            overall_width = max(overall_width, shelf_x);\n            long long new_bottom = y + hc;\n            if (new_bottom > overall_height) {\n                overall_height = new_bottom;\n                max_bottom_rect = i;\n            }\n        } else { // new shelf\n            int b = (max_bottom_rect == -1) ? -1 : max_bottom_rect;\n            res.push_back({i, r, 'L', b});\n\n            long long x = 0;\n            long long y = overall_height;\n            shelf_ref = b;\n            shelf_top = y;\n            shelf_x = wc;\n            shelf_max_h = hc;\n            overall_width = max(overall_width, (long long)wc);\n            long long new_bottom = y + hc;\n            overall_height = new_bottom;\n            max_bottom_rect = i;\n            shelf_exists = true;\n        }\n    }\n    return res;\n}\n\n// Column-based packing (uses U direction) with skipping\nvector<Placement> generate_column_packing(const vector<int>& w, const vector<int>& h,\n                                          mt19937& rng, double alpha, double noise, double skip_threshold) {\n    int n = w.size();\n    vector<Placement> res;\n    bool col_exists = false;\n    int col_ref = -1;            // b for the current column\n    long long col_left = 0;      // x coordinate of the column\n    long long col_y = 0;         // next y in this column\n    long long col_max_w = 0;     // max width in this column\n    long long overall_width = 0;\n    long long overall_height = 0;\n    int max_right_rect = -1;     // rectangle with maximum right edge (x+w)\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        double best_cost = 1e100;\n        int best_r = 0, best_option = 0; // option 0: current column, 1: new column\n        long long best_delta_w = 0, best_delta_h = 0;\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            // Option: place in current column\n            if (col_exists) {\n                long long new_col_y = col_y + hc;\n                long long new_col_max_w = max(col_max_w, (long long)wc);\n                long long new_width = max(overall_width, col_left + new_col_max_w);\n                long long new_height = max(overall_height, new_col_y);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = alpha * delta_w + delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 0;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n\n            // Option: start a new column\n            {\n                long long new_width = overall_width + wc;\n                long long new_height = max(overall_height, (long long)hc);\n                long long delta_w = new_width - overall_width;\n                long long delta_h = new_height - overall_height;\n                double cost = alpha * delta_w + delta_h + dist(rng);\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_r = r;\n                    best_option = 1;\n                    best_delta_w = delta_w;\n                    best_delta_h = delta_h;\n                }\n            }\n        }\n\n        // Actual increase in W+H for the chosen placement\n        long long actual_increase = best_delta_w + best_delta_h;\n        // Penalty for skipping: w_i + h_i (using original dimensions, not rotated)\n        long long penalty = w[i] + h[i];\n\n        if (actual_increase > skip_threshold * penalty) {\n            // Skip this rectangle\n            continue;\n        }\n\n        int r = best_r;\n        int wc = (r == 0 ? w[i] : h[i]);\n        int hc = (r == 0 ? h[i] : w[i]);\n\n        if (best_option == 0) { // current column\n            int b = col_ref;\n            res.push_back({i, r, 'U', b});\n\n            long long x = col_left;\n            long long y = col_y;\n            col_y += hc;\n            col_max_w = max(col_max_w, (long long)wc);\n            long long old_overall_width = overall_width;\n            overall_width = max(overall_width, col_left + col_max_w);\n            overall_height = max(overall_height, col_y);\n            if (overall_width > old_overall_width) {\n                max_right_rect = i;\n            }\n        } else { // new column\n            int b = (max_right_rect == -1) ? -1 : max_right_rect;\n            res.push_back({i, r, 'U', b});\n\n            long long x = overall_width;\n            long long y = 0;\n            col_ref = b;\n            col_left = x;\n            col_y = hc;\n            col_max_w = wc;\n            overall_width = x + wc;\n            overall_height = max(overall_height, (long long)hc);\n            max_right_rect = i;\n            col_exists = true;\n        }\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<long long> sum_w(N), sum_h(N);\n    vector<int> cnt(N, 1); // start with the given noisy measurements\n    for (int i = 0; i < N; ++i) {\n        int wp, hp;\n        cin >> wp >> hp;\n        sum_w[i] = wp;\n        sum_h[i] = hp;\n    }\n\n    // Estimate true sizes from the given data (already one sample)\n    vector<int> est_w(N), est_h(N);\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n    }\n\n    // Order rectangles by estimated area to prioritize measurement\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return (long long)est_w[a] * est_h[a] > (long long)est_w[b] * est_h[b];\n    });\n\n    const int PACK_TURNS = 20; // number of packing attempts\n    int M = max(0, T - PACK_TURNS); // number of measurement turns\n\n    // ---------- Measurement phase ----------\n    for (int t = 0; t < M; ++t) {\n        int idx = order[t % N]; // cycle through rectangles, most important first\n        cout << \"1\\n\";\n        cout << idx << \" 0 U -1\\n\";\n        cout << flush;\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Update measurements\n        sum_w[idx] += Wp;\n        sum_h[idx] += Hp;\n        cnt[idx]++;\n        // Update estimates on the fly\n        est_w[idx] = (sum_w[idx] + cnt[idx]/2) / cnt[idx];\n        est_h[idx] = (sum_h[idx] + cnt[idx]/2) / cnt[idx];\n    }\n\n    // Recompute all estimates after measurement phase\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n        if (est_w[i] < 1) est_w[i] = 1;\n        if (est_h[i] < 1) est_h[i] = 1;\n    }\n\n    // ---------- Packing phase ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<double> alphas = {0.5, 0.8, 1.0, 1.2, 1.5, 2.0};\n    vector<double> skip_thresholds = {1.0, 1.2, 1.5, 2.0};\n    uniform_int_distribution<int> alpha_dist(0, alphas.size()-1);\n    uniform_int_distribution<int> skip_dist(0, skip_thresholds.size()-1);\n    uniform_int_distribution<int> type_dist(0, 1); // 0: row, 1: column\n    const double noise = 0.1;\n\n    for (int t = M; t < T; ++t) {\n        int type = type_dist(rng);\n        double alpha = alphas[alpha_dist(rng)];\n        double skip_threshold = skip_thresholds[skip_dist(rng)];\n\n        vector<Placement> placements;\n        if (type == 0) {\n            placements = generate_row_packing(est_w, est_h, rng, alpha, noise, skip_threshold);\n        } else {\n            placements = generate_column_packing(est_w, est_h, rng, alpha, noise, skip_threshold);\n        }\n\n        // Output the placement\n        cout << placements.size() << \"\\n\";\n        for (const auto& pl : placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << \"\\n\";\n        }\n        cout << flush;\n\n        // Read the measurement (ignored for further decisions)\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <tuple>\nusing namespace std;\n\n// Parameters for simulated annealing\nconst int MAX_ITER = 300000;\nconst double START_TEMP = 50.0;\nconst double COOLING = 0.99998;\nconst double START_PENALTY = 1.0;\nconst double END_PENALTY = 10000.0;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\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    // ---------- Greedy initial solution ----------\n    vector<int> depth(N, -1);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });\n\n    for (int v : order) {\n        if (depth[v] != -1) continue;\n        depth[v] = 0;\n        queue<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [u, d] = q.front(); q.pop();\n            if (d == H) continue;\n            for (int w : adj[u]) {\n                if (depth[w] == -1) {\n                    depth[w] = d + 1;\n                    q.emplace(w, d + 1);\n                }\n            }\n        }\n    }\n\n    // Compute initial support and unsatisfied count\n    vector<int> support(N, 0);\n    int unsatisfied_cnt = 0;\n    long long current_score = 0;\n    for (int v = 0; v < N; ++v) {\n        current_score += (long long)depth[v] * A[v];\n        if (depth[v] > 0) {\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v] - 1) {\n                    support[v]++;\n                }\n            }\n            if (support[v] == 0) unsatisfied_cnt++;\n        }\n    }\n\n    // Best feasible solution\n    long long best_score = current_score;\n    vector<int> best_depths = depth;\n\n    // ---------- Simulated Annealing ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_vertex(0, N - 1);\n    uniform_int_distribution<int> rand_depth(0, H);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    double temp = START_TEMP;\n    double penalty_weight = START_PENALTY;\n    const double penalty_inc = (END_PENALTY - START_PENALTY) / MAX_ITER;\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        int v = rand_vertex(rng);\n        int old_d = depth[v];\n        int new_d;\n\n        // Choose move type\n        double r = rand_real(rng);\n        if (r < 0.5) {\n            new_d = rand_depth(rng);\n        } else if (r < 0.8) { // try to increase\n            if (old_d < H) new_d = old_d + 1;\n            else new_d = rand_depth(rng);\n        } else { // try to decrease\n            if (old_d > 0) new_d = old_d - 1;\n            else new_d = rand_depth(rng);\n        }\n\n        if (old_d == new_d) {\n            temp *= COOLING;\n            penalty_weight += penalty_inc;\n            continue;\n        }\n\n        // Evaluate move\n        long long delta_score = (long long)(new_d - old_d) * A[v];\n        double delta_penalty = 0.0;\n        int delta_unsatisfied = 0;\n        vector<pair<int, int>> updates; // (vertex, new_support)\n\n        // Affected vertices: v and its neighbours\n        vector<int> affected = {v};\n        for (int u : adj[v]) affected.push_back(u);\n\n        for (int w : affected) {\n            int depth_w_old = depth[w];\n            int depth_w_new = (w == v) ? new_d : depth[w];\n            bool old_sat = (depth_w_old == 0) || (support[w] > 0);\n\n            // Compute new support for w\n            int new_support_w = 0;\n            for (int x : adj[w]) {\n                int depth_x = (x == v) ? new_d : depth[x];\n                if (depth_x == depth_w_new - 1) {\n                    new_support_w++;\n                }\n            }\n            bool new_sat = (depth_w_new == 0) || (new_support_w > 0);\n\n            delta_penalty += penalty_weight * ((new_sat ? 0 : A[w]) - (old_sat ? 0 : A[w]));\n            delta_unsatisfied += (new_sat ? 0 : 1) - (old_sat ? 0 : 1);\n            updates.emplace_back(w, new_support_w);\n        }\n\n        double delta_total = delta_score - delta_penalty;\n\n        if (delta_total > 0.0 || rand_real(rng) < exp(delta_total / temp)) {\n            // Accept move\n            depth[v] = new_d;\n            for (auto& [w, ns] : updates) {\n                support[w] = ns;\n            }\n            current_score += delta_score;\n            unsatisfied_cnt += delta_unsatisfied;\n\n            if (unsatisfied_cnt == 0 && current_score > best_score) {\n                best_score = current_score;\n                best_depths = depth;\n            }\n        }\n\n        temp *= COOLING;\n        penalty_weight += penalty_inc;\n    }\n\n    // ---------- Output ----------\n    // Use the best feasible solution found\n    depth = best_depths;\n\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (depth[v] == 0) continue;\n        for (int u : adj[v]) {\n            if (depth[u] == depth[v] - 1) {\n                parent[v] = u;\n                break;\n            }\n        }\n        // In a feasible solution such a neighbour must exist\n    }\n\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid apply_left_shift(vector<vector<char>>& board, int row, int l) {\n    int N = board.size();\n    vector<char> new_row(N, '.');\n    for (int j = l; j < N; ++j) {\n        if (board[row][j] != '.') new_row[j - l] = board[row][j];\n    }\n    board[row] = new_row;\n}\n\nvoid apply_right_shift(vector<vector<char>>& board, int row, int r) {\n    int N = board.size();\n    vector<char> new_row(N, '.');\n    for (int j = 0; j < N - r; ++j) {\n        if (board[row][j] != '.') new_row[j + r] = board[row][j];\n    }\n    board[row] = new_row;\n}\n\nvoid apply_up_shift(vector<vector<char>>& board, int col, int t) {\n    int N = board.size();\n    vector<char> new_col(N, '.');\n    for (int i = t; i < N; ++i) {\n        if (board[i][col] != '.') new_col[i - t] = board[i][col];\n    }\n    for (int i = 0; i < N; ++i) board[i][col] = new_col[i];\n}\n\nvoid apply_down_shift(vector<vector<char>>& board, int col, int b) {\n    int N = board.size();\n    vector<char> new_col(N, '.');\n    for (int i = 0; i < N - b; ++i) {\n        if (board[i][col] != '.') new_col[i + b] = board[i][col];\n    }\n    for (int i = 0; i < N; ++i) board[i][col] = new_col[i];\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    // initial board\n    vector<vector<char>> board(N, vector<char>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            board[i][j] = grid[i][j];\n\n    // precompute column data from initial board\n    int col_top[20], col_bottom[20];\n    bool has_top_oni[20] = {}, has_bottom_oni[20] = {};\n    int top_zone_size[20] = {}, bottom_zone_size[20] = {};\n\n    for (int j = 0; j < N; ++j) {\n        col_top[j] = N;\n        col_bottom[j] = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                col_top[j] = min(col_top[j], i);\n                col_bottom[j] = max(col_bottom[j], i);\n            }\n        }\n        // top zone\n        if (col_top[j] > 0) {\n            for (int i = 0; i < col_top[j]; ++i)\n                if (board[i][j] == 'x') { has_top_oni[j] = true; break; }\n            if (has_top_oni[j]) top_zone_size[j] = col_top[j];\n        }\n        // bottom zone\n        if (col_bottom[j] < N - 1) {\n            for (int i = col_bottom[j] + 1; i < N; ++i)\n                if (board[i][j] == 'x') { has_bottom_oni[j] = true; break; }\n            if (has_bottom_oni[j]) bottom_zone_size[j] = N - 1 - col_bottom[j];\n        }\n    }\n\n    // precompute row data from initial board\n    int row_left[20], row_right[20];\n    bool has_left_oni[20] = {}, has_right_oni[20] = {};\n    int left_zone_size[20] = {}, right_zone_size[20] = {};\n\n    for (int i = 0; i < N; ++i) {\n        row_left[i] = N;\n        row_right[i] = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                row_left[i] = min(row_left[i], j);\n                row_right[i] = max(row_right[i], j);\n            }\n        }\n        // left zone\n        if (row_left[i] > 0) {\n            for (int j = 0; j < row_left[i]; ++j)\n                if (board[i][j] == 'x') { has_left_oni[i] = true; break; }\n            if (has_left_oni[i]) left_zone_size[i] = row_left[i];\n        }\n        // right zone\n        if (row_right[i] < N - 1) {\n            for (int j = row_right[i] + 1; j < N; ++j)\n                if (board[i][j] == 'x') { has_right_oni[i] = true; break; }\n            if (has_right_oni[i]) right_zone_size[i] = N - 1 - row_right[i];\n        }\n    }\n\n    // compute total zone sizes\n    int sum_col_zones = 0, sum_row_zones = 0;\n    for (int j = 0; j < N; ++j) {\n        sum_col_zones += top_zone_size[j] + bottom_zone_size[j];\n    }\n    for (int i = 0; i < N; ++i) {\n        sum_row_zones += left_zone_size[i] + right_zone_size[i];\n    }\n\n    // estimate operations for two strategies\n    int estA = 2 * sum_col_zones + sum_row_zones; // columns double, rows single\n    int estB = 2 * sum_row_zones + sum_col_zones; // rows double, columns single\n\n    vector<string> ops;\n\n    if (estA <= estB) {\n        // Strategy A: columns double, rows single\n        // Phase 1: columns with double shifts\n        for (int j = 0; j < N; ++j) {\n            // top zone\n            if (has_top_oni[j]) {\n                int t = top_zone_size[j];\n                for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n                // remove oni in top zone\n                for (int i = 0; i < t; ++i)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n            // bottom zone\n            if (has_bottom_oni[j]) {\n                int b = bottom_zone_size[j];\n                for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n                // remove oni in bottom zone\n                for (int i = col_bottom[j] + 1; i < N; ++i)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n        }\n        // Phase 2: rows with single shifts (recompute zones)\n        for (int i = 0; i < N; ++i) {\n            // left zone\n            int left_f = N;\n            for (int j = 0; j < N; ++j)\n                if (board[i][j] == 'o') { left_f = j; break; }\n            if (left_f > 0) {\n                bool has_oni = false;\n                for (int j = 0; j < left_f; ++j)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int l = left_f;\n                    apply_left_shift(board, i, l);\n                    for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                }\n            }\n            // right zone\n            int right_f = -1;\n            for (int j = N - 1; j >= 0; --j)\n                if (board[i][j] == 'o') { right_f = j; break; }\n            if (right_f < N - 1) {\n                bool has_oni = false;\n                for (int j = right_f + 1; j < N; ++j)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int r = N - 1 - right_f;\n                    apply_right_shift(board, i, r);\n                    for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                }\n            }\n        }\n    } else {\n        // Strategy B: rows double, columns single\n        // Phase 1: rows with double shifts\n        for (int i = 0; i < N; ++i) {\n            // left zone\n            if (has_left_oni[i]) {\n                int l = left_zone_size[i];\n                for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n                // remove oni in left zone\n                for (int j = 0; j < l; ++j)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n            // right zone\n            if (has_right_oni[i]) {\n                int r = right_zone_size[i];\n                for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n                // remove oni in right zone\n                for (int j = row_right[i] + 1; j < N; ++j)\n                    if (board[i][j] == 'x') board[i][j] = '.';\n            }\n        }\n        // Phase 2: columns with single shifts (recompute zones)\n        for (int j = 0; j < N; ++j) {\n            // top zone\n            int top_f = N;\n            for (int i = 0; i < N; ++i)\n                if (board[i][j] == 'o') { top_f = i; break; }\n            if (top_f > 0) {\n                bool has_oni = false;\n                for (int i = 0; i < top_f; ++i)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int t = top_f;\n                    apply_up_shift(board, j, t);\n                    for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                }\n            }\n            // bottom zone\n            int bottom_f = -1;\n            for (int i = N - 1; i >= 0; --i)\n                if (board[i][j] == 'o') { bottom_f = i; break; }\n            if (bottom_f < N - 1) {\n                bool has_oni = false;\n                for (int i = bottom_f + 1; i < N; ++i)\n                    if (board[i][j] == 'x') { has_oni = true; break; }\n                if (has_oni) {\n                    int b = N - 1 - bottom_f;\n                    apply_down_shift(board, j, b);\n                    for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                }\n            }\n        }\n    }\n\n    // output operations\n    for (const string& op : ops) cout << op << '\\n';\n\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint best_a[N], best_b[N];\nint best_error;\n\n// Fast simulation\nint simulate(const int a[], const int b[]) {\n    int count[N] = {0};\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int next;\n        if (count[current] & 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\n// Get detailed counts for analysis\nvector<int> get_counts(const int a[], const int b[]) {\n    vector<int> count(N, 0);\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int next;\n        if (count[current] & 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    return count;\n}\n\n// Smart initialization: try to create a walk that approximates targets\nvoid smart_init() {\n    // Start with all pointing to 0\n    for (int i = 0; i < N; i++) {\n        a[i] = 0;\n        b[i] = 0;\n    }\n    \n    // Get initial counts\n    auto counts = get_counts(a, b);\n    \n    // Adjust edges to redirect flow from over-represented to under-represented employees\n    for (int iter = 0; iter < 50; iter++) {\n        // Find most over-represented employee\n        int max_over = -1, max_over_idx = -1;\n        for (int i = 0; i < N; i++) {\n            int over = counts[i] - T[i];\n            if (over > max_over) {\n                max_over = over;\n                max_over_idx = i;\n            }\n        }\n        \n        // Find most under-represented employee\n        int max_under = -1, max_under_idx = -1;\n        for (int i = 0; i < N; i++) {\n            int under = T[i] - counts[i];\n            if (under > max_under) {\n                max_under = under;\n                max_under_idx = i;\n            }\n        }\n        \n        if (max_over <= 0 || max_under <= 0) break;\n        \n        // Redirect some flow from over-represented to under-represented\n        // Choose an employee that frequently points to max_over_idx\n        for (int i = 0; i < N; i++) {\n            if (a[i] == max_over_idx && counts[i] > T[i]) {\n                a[i] = max_under_idx;\n                break;\n            }\n            if (b[i] == max_over_idx && counts[i] > T[i]) {\n                b[i] = max_under_idx;\n                break;\n            }\n        }\n        \n        // Recompute counts\n        counts = get_counts(a, b);\n    }\n}\n\n// Local search that focuses on worst-performing employees\nvoid focused_local_search() {\n    // Get current counts\n    auto counts = get_counts(a, b);\n    \n    // Find employees with largest errors\n    vector<pair<int, int>> errors;\n    for (int i = 0; i < N; i++) {\n        errors.push_back({abs(counts[i] - T[i]), i});\n    }\n    sort(errors.rbegin(), errors.rend());\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis_emp(0, N-1);\n    uniform_int_distribution<> dis_which(0, 1);\n    \n    // Focus on top 20 worst employees\n    for (int idx = 0; idx < min(20, N); idx++) {\n        int i = errors[idx].second;\n        \n        // Try different values for a[i] and b[i]\n        for (int trial = 0; trial < 10; trial++) {\n            int old_a = a[i];\n            int old_b = b[i];\n            \n            // Try changing a[i]\n            int new_val = dis_emp(gen);\n            a[i] = new_val;\n            int new_error = simulate(a, b);\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            } else {\n                a[i] = old_a;\n            }\n            \n            // Try changing b[i]\n            new_val = dis_emp(gen);\n            b[i] = new_val;\n            new_error = simulate(a, b);\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            } else {\n                b[i] = old_b;\n            }\n        }\n    }\n}\n\nvoid solve() {\n    // Start with smart initialization\n    smart_init();\n    int current_error = simulate(a, b);\n    best_error = current_error;\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n    \n    // Run focused local search first\n    focused_local_search();\n    \n    // Then run simulated annealing with remaining time\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis_emp(0, N-1);\n    uniform_int_distribution<> dis_which(0, 1);\n    uniform_real_distribution<> dis_real(0, 1);\n    \n    double temperature = 5.0;\n    double cooling_rate = 0.97;\n    int max_iter = 100;  // Conservative to stay within time\n    \n    for (int iter = 0; iter < max_iter; iter++) {\n        int new_a[N], new_b[N];\n        memcpy(new_a, a, sizeof(a));\n        memcpy(new_b, b, sizeof(b));\n        \n        // Occasionally focus on worst employees (50% of the time)\n        if (dis_real(gen) < 0.5) {\n            // Focus on worst employee\n            auto counts = get_counts(a, b);\n            int worst_idx = -1, worst_err = -1;\n            for (int i = 0; i < N; i++) {\n                int err = abs(counts[i] - T[i]);\n                if (err > worst_err) {\n                    worst_err = err;\n                    worst_idx = i;\n                }\n            }\n            \n            if (worst_idx != -1) {\n                int i = worst_idx;\n                if (dis_which(gen) == 0) {\n                    new_a[i] = dis_emp(gen);\n                } else {\n                    new_b[i] = dis_emp(gen);\n                }\n            }\n        } else {\n            // Random change\n            int i = dis_emp(gen);\n            if (dis_which(gen) == 0) {\n                new_a[i] = dis_emp(gen);\n            } else {\n                new_b[i] = dis_emp(gen);\n            }\n        }\n        \n        int new_error = simulate(new_a, new_b);\n        int diff = new_error - current_error;\n        \n        if (diff < 0 || dis_real(gen) < exp(-diff / temperature)) {\n            memcpy(a, new_a, sizeof(a));\n            memcpy(b, new_b, sizeof(b));\n            current_error = new_error;\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, new_a, sizeof(new_a));\n                memcpy(best_b, new_b, sizeof(new_b));\n            }\n        }\n        \n        temperature *= cooling_rate;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int n, l;\n    cin >> n >> l;\n    for (int i = 0; i < n; i++) {\n        cin >> T[i];\n    }\n    \n    solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n#include <functional>\n#include <set>\n#include <queue>\n\nusing namespace std;\n\n// Query function with limit checking\nvector<pair<int, int>> query(const vector<int>& cities, int &queries_used, int Q) {\n    if (queries_used >= Q) {\n        return {};\n    }\n    \n    int l = cities.size();\n    cout << \"? \" << l;\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    queries_used++;\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(min(a, b), max(a, b));\n    }\n    return edges;\n}\n\n// Calculate minimum possible distance between rectangles\ndouble min_rect_distance(int i, int j, const vector<int>& lx, const vector<int>& rx, \n                         const vector<int>& ly, const vector<int>& ry) {\n    // Calculate minimum possible distance between points in two rectangles\n    int dx = max({0, lx[i] - rx[j], lx[j] - rx[i]});\n    int dy = max({0, ly[i] - ry[j], ly[j] - ry[i]});\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Calculate maximum possible distance between rectangles\ndouble max_rect_distance(int i, int j, const vector<int>& lx, const vector<int>& rx, \n                         const vector<int>& ly, const vector<int>& ry) {\n    // Calculate maximum possible distance between points in two rectangles\n    int dx = max(rx[i] - lx[j], rx[j] - lx[i]);\n    int dy = max(ry[i] - ly[j], ry[j] - ly[i]);\n    return sqrt(dx * dx + dy * dy);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Create a more sophisticated grouping based on rectangle proximity\n    // We'll use a greedy clustering approach that minimizes maximum distance within groups\n    \n    // First, sort groups by size (largest first) for better clustering\n    vector<int> group_order(M);\n    for (int i = 0; i < M; i++) group_order[i] = i;\n    sort(group_order.begin(), group_order.end(), [&](int i, int j) {\n        return G[i] > G[j];\n    });\n    \n    // Initialize groups\n    vector<vector<int>> groups(M);\n    vector<bool> assigned(N, false);\n    \n    // For each group (starting with largest)\n    for (int gi : group_order) {\n        int needed = G[gi];\n        \n        // Find the best seed city (smallest rectangle, most precise)\n        int best_seed = -1;\n        double best_area = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double area = (rx[i] - lx[i]) * (ry[i] - ly[i]);\n                if (area < best_area) {\n                    best_area = area;\n                    best_seed = i;\n                }\n            }\n        }\n        \n        if (best_seed == -1) continue;\n        \n        // Start group with seed\n        groups[gi].push_back(best_seed);\n        assigned[best_seed] = true;\n        needed--;\n        \n        // Greedily add closest cities\n        while (needed > 0) {\n            int best_city = -1;\n            double best_min_dist = 1e18;\n            \n            for (int i = 0; i < N; i++) {\n                if (assigned[i]) continue;\n                \n                // Find minimum distance to any city in current group\n                double min_dist = 1e18;\n                for (int c : groups[gi]) {\n                    double d = min_rect_distance(i, c, lx, rx, ly, ry);\n                    min_dist = min(min_dist, d);\n                }\n                \n                if (min_dist < best_min_dist || \n                    (min_dist == best_min_dist && (rx[i] - lx[i]) * (ry[i] - ly[i]) < \n                     (rx[best_city] - lx[best_city]) * (ry[best_city] - ly[best_city]))) {\n                    best_min_dist = min_dist;\n                    best_city = i;\n                }\n            }\n            \n            if (best_city == -1) break;\n            \n            groups[gi].push_back(best_city);\n            assigned[best_city] = true;\n            needed--;\n        }\n    }\n    \n    // Store edges for each group\n    vector<vector<pair<int, int>>> group_edges(M);\n    int queries_used = 0;\n    \n    // Process each group with efficient query usage\n    for (int g = 0; g < M && queries_used < Q; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        // If group is small enough, query the entire group\n        if (sz <= L && queries_used < Q) {\n            auto edges = query(groups[g], queries_used, Q);\n            group_edges[g].insert(group_edges[g].end(), edges.begin(), edges.end());\n        } \n        // For larger groups, use adaptive windowing\n        else if (queries_used < Q) {\n            // Sort cities within group by x-coordinate for consistent windowing\n            vector<int> sorted_group = groups[g];\n            sort(sorted_group.begin(), sorted_group.end(), [&](int i, int j) {\n                return (lx[i] + rx[i]) < (lx[j] + rx[j]);\n            });\n            \n            // Use overlapping windows with size L\n            int start = 0;\n            while (start < sz - 1 && queries_used < Q) {\n                int end = min(start + L, sz);\n                vector<int> window(sorted_group.begin() + start, sorted_group.begin() + end);\n                \n                if (window.size() >= 2) {\n                    auto edges = query(window, queries_used, Q);\n                    group_edges[g].insert(group_edges[g].end(), edges.begin(), edges.end());\n                }\n                \n                // Move forward by L-1 to maximize coverage\n                start = end - 1;\n            }\n            \n            // If we still need more edges, add some based on proximity\n            if (group_edges[g].size() < sz - 1) {\n                // Add edges between consecutive cities in sorted order\n                for (int i = 0; i < sz - 1 && group_edges[g].size() < sz - 1; i++) {\n                    pair<int, int> e = {min(sorted_group[i], sorted_group[i+1]), \n                                       max(sorted_group[i], sorted_group[i+1])};\n                    // Check if edge already exists\n                    bool exists = false;\n                    for (auto& edge : group_edges[g]) {\n                        if (edge == e) {\n                            exists = true;\n                            break;\n                        }\n                    }\n                    if (!exists) {\n                        group_edges[g].push_back(e);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        // Output cities in group\n        for (int j = 0; j < (int)groups[g].size(); j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[g][j];\n        }\n        cout << endl;\n        \n        // Output edges (exactly G[g]-1 edges for connectivity)\n        if (group_edges[g].size() >= groups[g].size() - 1) {\n            for (int j = 0; j < groups[g].size() - 1; j++) {\n                cout << group_edges[g][j].first << \" \" << group_edges[g][j].second << endl;\n            }\n        } else {\n            // Not enough edges, output what we have and fill with simple connections\n            set<pair<int, int>> used_edges;\n            for (auto& e : group_edges[g]) {\n                cout << e.first << \" \" << e.second << endl;\n                used_edges.insert(e);\n            }\n            \n            // Add additional edges to ensure connectivity\n            vector<int> sorted_cities = groups[g];\n            sort(sorted_cities.begin(), sorted_cities.end());\n            \n            for (int i = 0; i < sorted_cities.size() - 1 && \n                 used_edges.size() < groups[g].size() - 1; i++) {\n                pair<int, int> e = {sorted_cities[i], sorted_cities[i+1]};\n                if (used_edges.find(e) == used_edges.end()) {\n                    cout << e.first << \" \" << e.second << endl;\n                    used_edges.insert(e);\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    vector<string> actions;\n    int cx = targets[0].first, cy = targets[0].second;\n    const int MAX_ACTIONS = 800;\n\n    for (int k = 1; k < M; ++k) {\n        int tx = targets[k].first, ty = targets[k].second;\n        while ((cx != tx || cy != ty) && actions.size() < MAX_ACTIONS) {\n            if (cx == tx) {\n                if (ty == 0 && cy > 0) {\n                    actions.push_back(\"S L\");\n                    cy = 0;\n                } else if (ty == N - 1 && cy < N - 1) {\n                    actions.push_back(\"S R\");\n                    cy = N - 1;\n                } else {\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            } else if (cy == ty) {\n                if (tx == 0 && cx > 0) {\n                    actions.push_back(\"S U\");\n                    cx = 0;\n                } else if (tx == N - 1 && cx < N - 1) {\n                    actions.push_back(\"S D\");\n                    cx = N - 1;\n                } else {\n                    if (cx < tx) {\n                        actions.push_back(\"M D\");\n                        cx++;\n                    } else {\n                        actions.push_back(\"M U\");\n                        cx--;\n                    }\n                }\n            } else {\n                // Move vertically first\n                if (cx < tx) {\n                    actions.push_back(\"M D\");\n                    cx++;\n                } else if (cx > tx) {\n                    actions.push_back(\"M U\");\n                    cx--;\n                } else {\n                    // Should not happen, but fallback\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            }\n        }\n        if (actions.size() >= MAX_ACTIONS) {\n            break;\n        }\n    }\n\n    // Output actions\n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n\n    return 0;\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <functional>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nvector<Company> comps;\nvector<Rect> rects;\nint n;\n\nbool overlaps(const Rect& r1, const Rect& r2) {\n    return !(r1.c <= r2.a || r2.c <= r1.a || r1.d <= r2.b || r2.d <= r1.b);\n}\n\ndouble company_score(int i, const Rect& rect) {\n    int area = (rect.c - rect.a) * (rect.d - rect.b);\n    int r = comps[i].r;\n    if (area == 0) return 0;\n    double t = min(r, area) / (double)max(r, area);\n    return 1 - (1 - t) * (1 - t);\n}\n\nbool contains_point(int i, const Rect& rect) {\n    return rect.a <= comps[i].x && rect.c >= comps[i].x + 1 &&\n           rect.b <= comps[i].y && rect.d >= comps[i].y + 1;\n}\n\ndouble total_score() {\n    double sum = 0;\n    for (int i = 0; i < n; ++i) {\n        sum += company_score(i, rects[i]);\n    }\n    return sum;\n}\n\nvoid simulated_annealing() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    uniform_int_distribution<int> rect_dist(0, n - 1);\n    \n    double current_total = total_score();\n    vector<Rect> best_rects = rects;\n    double best_total = current_total;\n    \n    double temperature = 1.0;\n    double cooling_rate = 0.9995;\n    int max_iter = 200000;\n    int step = 20;\n    \n    for (int iter = 0; iter < max_iter; ++iter) {\n        if (temperature < 1e-6) break;\n        \n        int i = rect_dist(gen);\n        Rect old_rect = rects[i];\n        Rect new_rect = old_rect;\n        \n        // Choose a move type\n        uniform_int_distribution<int> move_dist(0, 4);\n        int move_type = move_dist(gen);\n        \n        if (move_type == 0) {\n            // Move left side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.a = max(0, old_rect.a + delta);\n            new_rect.a = min(new_rect.a, comps[i].x); // must be <= x_i\n            new_rect.a = min(new_rect.a, old_rect.c - 1); // must be < c\n        } else if (move_type == 1) {\n            // Move right side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.c = min(10000, old_rect.c + delta);\n            new_rect.c = max(new_rect.c, comps[i].x + 1); // must be >= x_i+1\n            new_rect.c = max(new_rect.c, old_rect.a + 1); // must be > a\n        } else if (move_type == 2) {\n            // Move bottom side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.b = max(0, old_rect.b + delta);\n            new_rect.b = min(new_rect.b, comps[i].y); // must be <= y_i\n            new_rect.b = min(new_rect.b, old_rect.d - 1); // must be < d\n        } else if (move_type == 3) {\n            // Move top side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.d = min(10000, old_rect.d + delta);\n            new_rect.d = max(new_rect.d, comps[i].y + 1); // must be >= y_i+1\n            new_rect.d = max(new_rect.d, old_rect.b + 1); // must be > b\n        } else {\n            // Shift entire rectangle\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int dx = delta_dist(gen);\n            int dy = delta_dist(gen);\n            new_rect.a = max(0, min(10000, old_rect.a + dx));\n            new_rect.c = max(0, min(10000, old_rect.c + dx));\n            new_rect.b = max(0, min(10000, old_rect.b + dy));\n            new_rect.d = max(0, min(10000, old_rect.d + dy));\n            // Ensure point containment\n            if (new_rect.a > comps[i].x) new_rect.a = comps[i].x;\n            if (new_rect.c < comps[i].x + 1) new_rect.c = comps[i].x + 1;\n            if (new_rect.b > comps[i].y) new_rect.b = comps[i].y;\n            if (new_rect.d < comps[i].y + 1) new_rect.d = comps[i].y + 1;\n            // Ensure a < c and b < d\n            if (new_rect.a >= new_rect.c) {\n                if (new_rect.a == comps[i].x) {\n                    new_rect.c = new_rect.a + 1;\n                } else {\n                    new_rect.a = new_rect.c - 1;\n                }\n            }\n            if (new_rect.b >= new_rect.d) {\n                if (new_rect.b == comps[i].y) {\n                    new_rect.d = new_rect.b + 1;\n                } else {\n                    new_rect.b = new_rect.d - 1;\n                }\n            }\n        }\n        \n        // Check validity\n        if (new_rect.a >= new_rect.c || new_rect.b >= new_rect.d) continue;\n        if (!contains_point(i, new_rect)) continue;\n        \n        // Check overlaps\n        bool overlap = false;\n        for (int j = 0; j < n; ++j) {\n            if (i == j) continue;\n            if (overlaps(new_rect, rects[j])) {\n                overlap = true;\n                break;\n            }\n        }\n        if (overlap) continue;\n        \n        // Compute new score\n        double old_score = company_score(i, old_rect);\n        double new_score = company_score(i, new_rect);\n        double delta_score = new_score - old_score;\n        \n        // Acceptance probability\n        if (delta_score > 0 || prob_dist(gen) < exp(delta_score / temperature)) {\n            rects[i] = new_rect;\n            current_total += delta_score;\n            \n            if (current_total > best_total) {\n                best_total = current_total;\n                best_rects = rects;\n            }\n        }\n        \n        temperature *= cooling_rate;\n        \n        // Gradually reduce step size\n        if (iter % 1000 == 0 && step > 1) {\n            step = max(1, step - 1);\n        }\n    }\n    \n    rects = best_rects;\n}\n\nvoid rec(vector<int>& idx, int x_min, int x_max, int y_min, int y_max) {\n    if (idx.empty()) return;\n    if (idx.size() == 1) {\n        int i = idx[0];\n        int W = x_max - x_min;\n        int H = y_max - y_min;\n        int r = comps[i].r;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - r);\n        for (int w = 1; w <= W; ++w) {\n            int h1 = max(1, min(H, (int)(r / w)));\n            int h2 = max(1, min(H, (int)ceil((double)r / w)));\n            int area1 = w * h1;\n            int diff1 = abs(area1 - r);\n            if (diff1 < best_diff) {\n                best_diff = diff1;\n                best_w = w;\n                best_h = h1;\n            }\n            int area2 = w * h2;\n            int diff2 = abs(area2 - r);\n            if (diff2 < best_diff) {\n                best_diff = diff2;\n                best_w = w;\n                best_h = h2;\n            }\n        }\n        int a = max(x_min, comps[i].x - (best_w - 1));\n        a = min(a, x_max - best_w);\n        int b = max(y_min, comps[i].y - (best_h - 1));\n        b = min(b, y_max - best_h);\n        int c = a + best_w;\n        int d = b + best_h;\n        rects[i] = {a, b, c, d};\n        return;\n    }\n\n    long long total_r = 0;\n    for (int i : idx) total_r += comps[i].r;\n\n    double best_diff = 1e18;\n    int best_dir = -1;\n    int best_c = -1;\n\n    // Try vertical split\n    vector<int> sorted_x = idx;\n    sort(sorted_x.begin(), sorted_x.end(), [&](int i, int j) { return comps[i].x < comps[j].x; });\n    if (comps[sorted_x.front()].x != comps[sorted_x.back()].x) {\n        vector<long long> prefix_x(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_x.size(); ++j) {\n            prefix_x[j + 1] = prefix_x[j] + comps[sorted_x[j]].r;\n        }\n        for (int p = 1; p < sorted_x.size(); ++p) {\n            long long left_sum = prefix_x[p];\n            double desired_width = (left_sum / (double)total_r) * (x_max - x_min);\n            double ideal_c = x_min + desired_width;\n            int c_min = comps[sorted_x[p - 1]].x + 1;\n            int c_max = comps[sorted_x[p]].x;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_width = c - x_min;\n            double diff = fabs(actual_width - desired_width);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 0;\n                best_c = c;\n            }\n        }\n    }\n\n    // Try horizontal split\n    vector<int> sorted_y = idx;\n    sort(sorted_y.begin(), sorted_y.end(), [&](int i, int j) { return comps[i].y < comps[j].y; });\n    if (comps[sorted_y.front()].y != comps[sorted_y.back()].y) {\n        vector<long long> prefix_y(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_y.size(); ++j) {\n            prefix_y[j + 1] = prefix_y[j] + comps[sorted_y[j]].r;\n        }\n        for (int p = 1; p < sorted_y.size(); ++p) {\n            long long left_sum = prefix_y[p];\n            double desired_height = (left_sum / (double)total_r) * (y_max - y_min);\n            double ideal_c = y_min + desired_height;\n            int c_min = comps[sorted_y[p - 1]].y + 1;\n            int c_max = comps[sorted_y[p]].y;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_height = c - y_min;\n            double diff = fabs(actual_height - desired_height);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 1;\n                best_c = c;\n            }\n        }\n    }\n\n    if (best_dir == 0) {\n        vector<int> left_idx, right_idx;\n        for (int i : idx) {\n            if (comps[i].x < best_c) left_idx.push_back(i);\n            else right_idx.push_back(i);\n        }\n        rec(left_idx, x_min, best_c, y_min, y_max);\n        rec(right_idx, best_c, x_max, y_min, y_max);\n    } else {\n        vector<int> bottom_idx, top_idx;\n        for (int i : idx) {\n            if (comps[i].y < best_c) bottom_idx.push_back(i);\n            else top_idx.push_back(i);\n        }\n        rec(bottom_idx, x_min, x_max, y_min, best_c);\n        rec(top_idx, x_min, x_max, best_c, y_max);\n    }\n}\n\nvoid compute_expansions(int i, int& L_max, int& R_max, int& D_max, int& U_max) {\n    int a = rects[i].a, b = rects[i].b, c = rects[i].c, d = rects[i].d;\n    L_max = a;\n    R_max = 10000 - c;\n    D_max = b;\n    U_max = 10000 - d;\n\n    for (int j = 0; j < rects.size(); ++j) {\n        if (i == j) continue;\n        int a2 = rects[j].a, b2 = rects[j].b, c2 = rects[j].c, d2 = rects[j].d;\n        if (!(d <= b2 || d2 <= b)) {\n            if (c2 <= a) {\n                L_max = min(L_max, a - c2);\n            }\n            if (a2 >= c) {\n                R_max = min(R_max, a2 - c);\n            }\n        }\n        if (!(c <= a2 || c2 <= a)) {\n            if (d2 <= b) {\n                D_max = min(D_max, b - d2);\n            }\n            if (b2 >= d) {\n                U_max = min(U_max, b2 - d);\n            }\n        }\n    }\n    L_max = max(0, L_max);\n    R_max = max(0, R_max);\n    D_max = max(0, D_max);\n    U_max = max(0, U_max);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    comps.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> comps[i].x >> comps[i].y >> comps[i].r;\n    }\n\n    rects.resize(n);\n    vector<int> all_idx(n);\n    for (int i = 0; i < n; ++i) all_idx[i] = i;\n    rec(all_idx, 0, 10000, 0, 10000);\n\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 g(seed);\n    \n    for (int pass = 0; pass < 50; ++pass) {\n        vector<pair<int, int>> deficit_idx;\n        for (int i = 0; i < n; ++i) {\n            int w = rects[i].c - rects[i].a;\n            int h = rects[i].d - rects[i].b;\n            int s = w * h;\n            int deficit = abs(s - comps[i].r);\n            deficit_idx.emplace_back(deficit, i);\n        }\n        sort(deficit_idx.begin(), deficit_idx.end(), greater<pair<int, int>>());\n        \n        bool changed = false;\n        for (auto& p : deficit_idx) {\n            int i = p.second;\n            int w = rects[i].c - rects[i].a;\n            int h = rects[i].d - rects[i].b;\n            int s = w * h;\n            int r = comps[i].r;\n            int x = comps[i].x, y = comps[i].y;\n            \n            if (s < r) {\n                // Try to expand\n                int L_max, R_max, D_max, U_max;\n                compute_expansions(i, L_max, R_max, D_max, U_max);\n                int w_max = w + L_max + R_max;\n                int h_max = h + D_max + U_max;\n                int best_w = w, best_h = h;\n                int best_diff = abs(s - r);\n                \n                int w_ideal = max(1, (int)sqrt(r));\n                int w_start = max(w, w_ideal - 200);\n                int w_end = min(w_max, w_ideal + 200);\n                if (w_start > w_end) {\n                    w_start = w;\n                    w_end = w_max;\n                }\n                \n                for (int w2 = w_start; w2 <= w_end; ++w2) {\n                    double h_ideal = (double)r / w2;\n                    int h1 = max(h, min(h_max, (int)floor(h_ideal)));\n                    int h2 = max(h, min(h_max, (int)ceil(h_ideal)));\n                    int area1 = w2 * h1;\n                    int diff1 = abs(area1 - r);\n                    if (diff1 < best_diff) {\n                        best_diff = diff1;\n                        best_w = w2;\n                        best_h = h1;\n                    }\n                    int area2 = w2 * h2;\n                    int diff2 = abs(area2 - r);\n                    if (diff2 < best_diff) {\n                        best_diff = diff2;\n                        best_w = w2;\n                        best_h = h2;\n                    }\n                }\n                \n                if (best_w == w && best_h == h) continue;\n                \n                int need_w = best_w - w;\n                int need_h = best_h - h;\n                int L = min(need_w, L_max);\n                int R = need_w - L;\n                if (R > R_max) {\n                    R = R_max;\n                    L = need_w - R;\n                }\n                int D = min(need_h, D_max);\n                int U = need_h - D;\n                if (U > U_max) {\n                    U = U_max;\n                    D = need_h - U;\n                }\n                \n                Rect candidate = {rects[i].a - L, rects[i].b - D, rects[i].c + R, rects[i].d + U};\n                bool overlap = false;\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(candidate, rects[j])) {\n                        overlap = true;\n                        break;\n                    }\n                }\n                if (overlap) continue;\n                \n                if (candidate.a <= x && candidate.c >= x + 1 && \n                    candidate.b <= y && candidate.d >= y + 1) {\n                    rects[i] = candidate;\n                    changed = true;\n                }\n            } else if (s > r) {\n                // Try to shrink\n                int L_shrink = x - rects[i].a;\n                int R_shrink = rects[i].c - (x + 1);\n                int D_shrink = y - rects[i].b;\n                int U_shrink = rects[i].d - (y + 1);\n                int w_min = max(1, w - L_shrink - R_shrink);\n                int h_min = max(1, h - D_shrink - U_shrink);\n                int best_w = w, best_h = h;\n                int best_diff = abs(s - r);\n                \n                int w_ideal = max(1, (int)sqrt(r));\n                int w_start = max(w_min, w_ideal - 200);\n                int w_end = min(w, w_ideal + 200);\n                if (w_start > w_end) {\n                    w_start = w_min;\n                    w_end = w;\n                }\n                \n                for (int w2 = w_start; w2 <= w_end; ++w2) {\n                    double h_ideal = (double)r / w2;\n                    int h1 = max(h_min, min(h, (int)floor(h_ideal)));\n                    int h2 = max(h_min, min(h, (int)ceil(h_ideal)));\n                    int area1 = w2 * h1;\n                    int diff1 = abs(area1 - r);\n                    if (diff1 < best_diff) {\n                        best_diff = diff1;\n                        best_w = w2;\n                        best_h = h1;\n                    }\n                    int area2 = w2 * h2;\n                    int diff2 = abs(area2 - r);\n                    if (diff2 < best_diff) {\n                        best_diff = diff2;\n                        best_w = w2;\n                        best_h = h2;\n                    }\n                }\n                \n                if (best_w == w && best_h == h) continue;\n                \n                int need_w = w - best_w;\n                int need_h = h - best_h;\n                int L = min(need_w, L_shrink);\n                int R = need_w - L;\n                if (R > R_shrink) {\n                    R = R_shrink;\n                    L = need_w - R;\n                }\n                int D = min(need_h, D_shrink);\n                int U = need_h - D;\n                if (U > U_shrink) {\n                    U = U_shrink;\n                    D = need_h - U;\n                }\n                \n                Rect candidate = {rects[i].a + L, rects[i].b + D, rects[i].c - R, rects[i].d - U};\n                if (candidate.a <= x && candidate.c >= x + 1 && \n                    candidate.b <= y && candidate.d >= y + 1) {\n                    rects[i] = candidate;\n                    changed = true;\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    // Apply simulated annealing\n    simulated_annealing();\n\n    for (int i = 0; i < n; ++i) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <utility>\n#include <tuple>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> t(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    vector<vector<int>> p(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    int M = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            M = max(M, t[i][j] + 1);\n\n    // Precompute maximum neighbor value for each square (for heuristic bonus)\n    vector<vector<int>> max_neighbor(N, vector<int>(N, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int best = 0;\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)\n                    best = max(best, p[ni][nj]);\n            }\n            max_neighbor[i][j] = best;\n        }\n    }\n\n    random_device rd;\n    mt19937 rng(rd());\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 1.95;\n\n    int best_score = p[si][sj];\n    string best_path;\n\n    vector<char> visited(M, 0);\n    visited[t[si][sj]] = 1;\n    int visited_count = 1;\n\n    // Helper to count unvisited neighbors\n    auto count_unvisited = [&](int i, int j) {\n        int cnt = 0;\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 && !visited[t[ni][nj]])\n                ++cnt;\n        }\n        return cnt;\n    };\n\n    // DFS state: position, score, list of candidate moves, index of next candidate\n    struct State {\n        int i, j;\n        int score;\n        vector<tuple<int, int, int>> candidates; // (ni, nj, weight)\n        int next_idx;\n    };\n\n    vector<State> stack;\n    string current_path;\n\n    // Initialize start state\n    vector<tuple<int, int, int>> start_candidates;\n    for (int d = 0; d < 4; ++d) {\n        int ni = si + di[d], nj = sj + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[t[ni][nj]]) {\n            int cnt = count_unvisited(ni, nj);\n            int weight = p[ni][nj] + 5 * cnt + max_neighbor[ni][nj] / 2;\n            start_candidates.emplace_back(ni, nj, weight);\n        }\n    }\n    // Shuffle then sort by weight descending for diversity\n    shuffle(start_candidates.begin(), start_candidates.end(), rng);\n    sort(start_candidates.begin(), start_candidates.end(),\n         [](const auto& a, const auto& b) { return get<2>(a) > get<2>(b); });\n\n    stack.push_back({si, sj, p[si][sj], start_candidates, 0});\n\n    while (!stack.empty() &&\n           chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < time_limit) {\n        State& top = stack.back();\n\n        if (top.next_idx >= (int)top.candidates.size()) {\n            // Backtrack\n            if (t[top.i][top.j] != t[si][sj]) // don't unmark start tile\n                visited[t[top.i][top.j]] = 0;\n            --visited_count;\n            stack.pop_back();\n            if (!current_path.empty())\n                current_path.pop_back();\n            continue;\n        }\n\n        // Try next candidate\n        auto [ni, nj, w] = top.candidates[top.next_idx++];\n        int tile = t[ni][nj];\n        visited[tile] = 1;\n        ++visited_count;\n        int new_score = top.score + p[ni][nj];\n\n        // Compute move character\n        char move;\n        if (ni == top.i - 1 && nj == top.j) move = 'U';\n        else if (ni == top.i + 1 && nj == top.j) move = 'D';\n        else if (ni == top.i && nj == top.j - 1) move = 'L';\n        else if (ni == top.i && nj == top.j + 1) move = 'R';\n        else assert(false);\n\n        current_path.push_back(move);\n\n        // Update best\n        if (new_score > best_score) {\n            best_score = new_score;\n            best_path = current_path;\n        }\n\n        // Prune if optimistic bound is not promising\n        int optimistic_bound = new_score + 99 * (M - visited_count);\n        if (optimistic_bound <= best_score) {\n            // Prune: backtrack immediately\n            visited[tile] = 0;\n            --visited_count;\n            current_path.pop_back();\n            continue;\n        }\n\n        // Generate candidates for next state\n        vector<tuple<int, int, int>> next_candidates;\n        for (int d = 0; d < 4; ++d) {\n            int nni = ni + di[d], nnj = nj + dj[d];\n            if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && !visited[t[nni][nnj]]) {\n                int cnt = count_unvisited(nni, nnj);\n                int weight = p[nni][nnj] + 5 * cnt + max_neighbor[nni][nnj] / 2;\n                next_candidates.emplace_back(nni, nnj, weight);\n            }\n        }\n\n        // Shuffle and sort candidates\n        shuffle(next_candidates.begin(), next_candidates.end(), rng);\n        sort(next_candidates.begin(), next_candidates.end(),\n             [](const auto& a, const auto& b) { return get<2>(a) > get<2>(b); });\n\n        stack.push_back({ni, nj, new_score, next_candidates, 0});\n    }\n\n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int ROWS = 30;\nconst int COLS = 30;\nconst int MAX_QUERIES = 1000;\n\n// Direction vectors: U, D, L, R\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Edge weight estimation\nvector<vector<double>> h_est(ROWS, vector<double>(COLS-1));\nvector<vector<double>> v_est(ROWS-1, vector<double>(COLS));\nvector<vector<int>> h_count(ROWS, vector<int>(COLS-1, 0));\nvector<vector<int>> v_count(ROWS-1, vector<int>(COLS, 0));\n\n// Track row and column base values\nvector<double> row_base(ROWS, 5000.0);\nvector<double> col_base(COLS, 5000.0);\nvector<int> row_count(ROWS, 0);\nvector<int> col_count(COLS, 0);\n\n// For \u03b5-greedy exploration\nrandom_device rd;\nmt19937 gen(rd());\nuniform_real_distribution<> dis(0.0, 1.0);\n\nvoid initialize_estimates() {\n    // Initialize with row/column bases\n    for (int i = 0; i < ROWS; i++) {\n        for (int j = 0; j < COLS-1; j++) {\n            h_est[i][j] = row_base[i] + (dis(gen) - 0.5) * 200.0; // Small random variation\n        }\n    }\n    for (int i = 0; i < ROWS-1; i++) {\n        for (int j = 0; j < COLS; j++) {\n            v_est[i][j] = col_base[j] + (dis(gen) - 0.5) * 200.0; // Small random variation\n        }\n    }\n}\n\npair<string, double> find_path(int si, int sj, int ti, int tj, bool explore = false) {\n    vector<vector<double>> dist(ROWS, vector<double>(COLS, 1e18));\n    vector<vector<pair<int,int>>> parent(ROWS, vector<pair<int,int>>(COLS, {-1,-1}));\n    vector<vector<int>> dir_used(ROWS, vector<int>(COLS, -1));\n    \n    dist[si][sj] = 0;\n    using Node = pair<double, pair<int,int>>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    pq.push({0.0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, node] = pq.top(); pq.pop();\n        auto [i, j] = node;\n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n        \n        // For exploration, sometimes take random edges\n        vector<int> dirs = {0, 1, 2, 3};\n        if (explore && dis(gen) < 0.3) {\n            shuffle(dirs.begin(), dirs.end(), gen);\n        }\n        \n        for (int dir : dirs) {\n            int ni = i + dr[dir];\n            int nj = j + dc[dir];\n            if (ni < 0 || ni >= ROWS || nj < 0 || nj >= COLS) continue;\n            \n            double w;\n            if (dir == 0) w = v_est[ni][nj]; // U\n            else if (dir == 1) w = v_est[i][j]; // D\n            else if (dir == 2) w = h_est[i][nj]; // L\n            else w = h_est[i][j]; // R\n            \n            // Add small random noise during exploration\n            if (explore && dis(gen) < 0.2) {\n                w *= (0.9 + 0.2 * dis(gen));\n            }\n            \n            if (dist[ni][nj] > d + w + 1e-9) {\n                dist[ni][nj] = d + w;\n                parent[ni][nj] = {i, j};\n                dir_used[ni][nj] = dir;\n                pq.push({dist[ni][nj], {ni, nj}});\n            }\n        }\n    }\n    \n    string path;\n    double est_len = 0;\n    int ci = ti, cj = tj;\n    \n    while (ci != si || cj != sj) {\n        int dir = dir_used[ci][cj];\n        path += dir_char[dir];\n        \n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        \n        if (dir == 0) { // U\n            est_len += v_est[ci][cj];\n        } else if (dir == 1) { // D\n            est_len += v_est[pi][pj];\n        } else if (dir == 2) { // L\n            est_len += h_est[ci][cj];\n        } else { // R\n            est_len += h_est[pi][pj];\n        }\n        \n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, est_len};\n}\n\nvoid update_weights(const string& path, int si, int sj, double observed, int query_num) {\n    int i = si, j = sj;\n    double est_len = 0;\n    vector<tuple<int,int,bool>> edges;\n    \n    for (char c : path) {\n        int dir;\n        if (c == 'U') dir = 0;\n        else if (c == 'D') dir = 1;\n        else if (c == 'L') dir = 2;\n        else dir = 3;\n        \n        int ni = i + dr[dir];\n        int nj = j + dc[dir];\n        \n        if (dir == 0) {\n            edges.emplace_back(ni, nj, false);\n            est_len += v_est[ni][nj];\n        } else if (dir == 1) {\n            edges.emplace_back(i, j, false);\n            est_len += v_est[i][j];\n        } else if (dir == 2) {\n            edges.emplace_back(i, nj, true);\n            est_len += h_est[i][nj];\n        } else {\n            edges.emplace_back(i, j, true);\n            est_len += h_est[i][j];\n        }\n        \n        i = ni;\n        j = nj;\n    }\n    \n    double error = observed - est_len;\n    int edge_count = edges.size();\n    if (edge_count == 0) return;\n    \n    // More aggressive learning rate that decays slowly\n    double base_lr = 0.8 * exp(-query_num / 800.0);\n    \n    for (auto [r, c, is_horiz] : edges) {\n        int count = is_horiz ? h_count[r][c] : v_count[r][c];\n        double lr = base_lr / (1.0 + 0.05 * count);\n        \n        // Update edge weight\n        double delta = lr * error / edge_count;\n        if (is_horiz) {\n            h_est[r][c] += delta;\n            h_est[r][c] = max(1000.0, min(9000.0, h_est[r][c]));\n            h_count[r][c]++;\n            \n            // Update row base estimate with stronger influence\n            row_base[r] = 0.85 * row_base[r] + 0.15 * h_est[r][c];\n            row_count[r]++;\n        } else {\n            v_est[r][c] += delta;\n            v_est[r][c] = max(1000.0, min(9000.0, v_est[r][c]));\n            v_count[r][c]++;\n            \n            // Update column base estimate with stronger influence\n            col_base[c] = 0.85 * col_base[c] + 0.15 * v_est[r][c];\n            col_count[c]++;\n        }\n    }\n    \n    // More frequent re-initialization of poorly learned edges\n    if (query_num % 50 == 49) {\n        for (int i = 0; i < ROWS; i++) {\n            for (int j = 0; j < COLS-1; j++) {\n                if (h_count[i][j] < 3) {\n                    h_est[i][j] = row_base[i] + (dis(gen) - 0.5) * 500.0;\n                }\n            }\n        }\n        for (int i = 0; i < ROWS-1; i++) {\n            for (int j = 0; j < COLS; j++) {\n                if (v_count[i][j] < 3) {\n                    v_est[i][j] = col_base[j] + (dis(gen) - 0.5) * 500.0;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_estimates();\n    \n    for (int q = 0; q < MAX_QUERIES; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        // \u03b5-greedy: explore with probability decaying over time\n        double explore_prob = 0.3 * exp(-q / 300.0);\n        bool explore = (dis(gen) < explore_prob);\n        \n        auto [path, est_len] = find_path(si, sj, ti, tj, explore);\n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_weights(path, si, sj, observed, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int ALPHABET = 8;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    int dummy;\n    cin >> dummy >> M;\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Sort strings by length descending\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return strs[a].size() > strs[b].size();\n    });\n    \n    // Initialize grid with random letters\n    char grid[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + rng() % ALPHABET;\n        }\n    }\n    \n    vector<bool> covered(M, false);\n    auto start_time = chrono::steady_clock::now();\n    \n    // Phase 1: Cover strings with minimal conflicts\n    for (int idx : order) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 1.0) {\n            break;\n        }\n        \n        const string& s = strs[idx];\n        int L = s.size();\n        \n        // Adaptive threshold: allow more mismatches for longer strings\n        int threshold = min(3, (L + 1) / 2);\n        \n        int best_i = -1, best_j = -1, best_dir = -1, best_conflicts = L + 1;\n        \n        // Find placement with fewest conflicts\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int dir = 0; dir < 2; ++dir) {\n                    int conflicts = 0;\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        if (grid[ni][nj] != s[p]) {\n                            conflicts++;\n                        }\n                    }\n                    if (conflicts < best_conflicts) {\n                        best_conflicts = conflicts;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = dir;\n                    }\n                }\n            }\n        }\n        \n        // If conflicts are low, place the string\n        if (best_conflicts <= threshold && best_i != -1) {\n            for (int p = 0; p < L; ++p) {\n                int ni, nj;\n                if (best_dir == 0) {\n                    ni = best_i;\n                    nj = (best_j + p) % N;\n                } else {\n                    ni = (best_i + p) % N;\n                    nj = best_j;\n                }\n                grid[ni][nj] = s[p];\n            }\n            covered[idx] = true;\n        }\n    }\n    \n    // Phase 2: Try to cover remaining strings with minimal disruption\n    // First, compute for each cell how many covered strings depend on it\n    vector<vector<int>> cell_importance(N, vector<int>(N, 0));\n    for (int idx = 0; idx < M; ++idx) {\n        if (!covered[idx]) continue;\n        \n        const string& s = strs[idx];\n        int L = s.size();\n        \n        // Find one valid placement for this covered string\n        bool found = false;\n        for (int i = 0; i < N && !found; ++i) {\n            for (int j = 0; j < N && !found; ++j) {\n                for (int dir = 0; dir < 2 && !found; ++dir) {\n                    bool valid = true;\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        if (grid[ni][nj] != s[p]) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                    if (valid) {\n                        // Mark cells used by this placement\n                        for (int p = 0; p < L; ++p) {\n                            int ni, nj;\n                            if (dir == 0) {\n                                ni = i;\n                                nj = (j + p) % N;\n                            } else {\n                                ni = (i + p) % N;\n                                nj = j;\n                            }\n                            cell_importance[ni][nj]++;\n                        }\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Now try to cover uncovered strings\n    for (int iteration = 0; iteration < 2; ++iteration) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.5) {\n            break;\n        }\n        \n        for (int idx = 0; idx < M; ++idx) {\n            if (covered[idx]) continue;\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) {\n                break;\n            }\n            \n            const string& s = strs[idx];\n            int L = s.size();\n            \n            int best_i = -1, best_j = -1, best_dir = -1, best_cost = 1000000;\n            \n            // Find placement with minimum disruption cost\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    for (int dir = 0; dir < 2; ++dir) {\n                        int cost = 0;\n                        bool possible = true;\n                        for (int p = 0; p < L; ++p) {\n                            int ni, nj;\n                            if (dir == 0) {\n                                ni = i;\n                                nj = (j + p) % N;\n                            } else {\n                                ni = (i + p) % N;\n                                nj = j;\n                            }\n                            if (grid[ni][nj] != s[p]) {\n                                cost += cell_importance[ni][nj];\n                                if (cost >= best_cost) {\n                                    possible = false;\n                                    break;\n                                }\n                            }\n                        }\n                        if (possible && cost < best_cost) {\n                            best_cost = cost;\n                            best_i = i;\n                            best_j = j;\n                            best_dir = dir;\n                        }\n                    }\n                }\n            }\n            \n            // Adaptive threshold based on string length\n            int threshold = 5 + L/2;\n            \n            if (best_cost <= threshold && best_i != -1) {\n                for (int p = 0; p < L; ++p) {\n                    int ni, nj;\n                    if (best_dir == 0) {\n                        ni = best_i;\n                        nj = (best_j + p) % N;\n                    } else {\n                        ni = (best_i + p) % N;\n                        nj = best_j;\n                    }\n                    grid[ni][nj] = s[p];\n                }\n                covered[idx] = true;\n                \n                // Update importance scores\n                for (int p = 0; p < L; ++p) {\n                    int ni, nj;\n                    if (best_dir == 0) {\n                        ni = best_i;\n                        nj = (best_j + p) % N;\n                    } else {\n                        ni = (best_i + p) % N;\n                        nj = best_j;\n                    }\n                    cell_importance[ni][nj]++;\n                }\n            }\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        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<int>> cost;               // -1 for obstacle, else digit 5-9\nvector<vector<int>> row_seg, col_seg;   // segment ids for each cell\nint R_cnt, C_cnt;                       // number of row/column segments\nvector<vector<pair<int, int>>> row_cells, col_cells; // cells in each segment\nvector<unordered_map<int, pair<int, int>>> cell_of;  // (r,c) -> (i,j)\n\n// Directions: up, down, left, right\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// Linear index for a cell\ninline int to_id(int i, int j) { return i * N + j; }\ninline pair<int, int> from_id(int id) { return {id / N, id % N}; }\n\n// ----------------------------------------------------------------------\n// Dijkstra from a source, returns distances and predecessors\nstruct DijkstraResult {\n    vector<vector<int>> dist;\n    vector<vector<int>> prev;   // previous cell as linear id\n    DijkstraResult() : dist(N, vector<int>(N, INF)), prev(N, vector<int>(N, -1)) {}\n};\n\nDijkstraResult run_dijkstra(int si, int sj) {\n    DijkstraResult res;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    res.dist[si][sj] = 0;\n    pq.push({0, to_id(si, sj)});\n    while (!pq.empty()) {\n        auto [d, id] = pq.top(); pq.pop();\n        auto [i, j] = from_id(id);\n        if (d != res.dist[i][j]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (cost[ni][nj] == -1) continue;   // obstacle\n            int nd = d + cost[ni][nj];\n            if (nd < res.dist[ni][nj]) {\n                res.dist[ni][nj] = nd;\n                res.prev[ni][nj] = id;\n                pq.push({nd, to_id(ni, nj)});\n            }\n        }\n    }\n    return res;\n}\n\n// ----------------------------------------------------------------------\n// Hopcroft\u2013Karp for bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> matchL, matchR, dist;\n    HopcroftKarp(int nL, int nR) : nL(nL), nR(nR), adj(nL), matchL(nL, -1), matchR(nR, -1), dist(nL) {}\n    void addEdge(int u, int v) { adj[u].push_back(v); }\n    bool bfs() {\n        queue<int> q;\n        for (int u = 0; u < nL; ++u) {\n            if (matchL[u] == -1) {\n                dist[u] = 0;\n                q.push(u);\n            } else dist[u] = INF;\n        }\n        bool found = false;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (matchR[v] == -1) found = true;\n                else if (dist[matchR[v]] == INF) {\n                    dist[matchR[v]] = dist[u] + 1;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n        return found;\n    }\n    bool dfs(int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 || (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = INF;\n        return false;\n    }\n    int maxMatching() {\n        int matching = 0;\n        while (bfs()) {\n            for (int u = 0; u < nL; ++u)\n                if (matchL[u] == -1 && dfs(u))\n                    ++matching;\n        }\n        return matching;\n    }\n};\n\n// ----------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input --------------------------------------------------------\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    cost.assign(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                cost[i][j] = grid[i][j] - '0';\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n\n    // ----- Row segments -------------------------------------------------\n    row_seg.assign(N, vector<int>(N, -1));\n    R_cnt = 0;\n    row_cells.clear();\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (cost[i][j] != -1) {\n                int start_j = j;\n                while (j < N && cost[i][j] != -1) {\n                    row_seg[i][j] = R_cnt;\n                    ++j;\n                }\n                row_cells.emplace_back();\n                for (int k = start_j; k < j; ++k)\n                    row_cells.back().emplace_back(i, k);\n                ++R_cnt;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ----- Column segments ----------------------------------------------\n    col_seg.assign(N, vector<int>(N, -1));\n    C_cnt = 0;\n    col_cells.clear();\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (cost[i][j] != -1) {\n                int start_i = i;\n                while (i < N && cost[i][j] != -1) {\n                    col_seg[i][j] = C_cnt;\n                    ++i;\n                }\n                col_cells.emplace_back();\n                for (int k = start_i; k < i; ++k)\n                    col_cells.back().emplace_back(k, j);\n                ++C_cnt;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ----- Build full bipartite graph (row segments vs column segments) -\n    HopcroftKarp hk_full(R_cnt, C_cnt);\n    cell_of.resize(R_cnt);\n    for (auto [i, j] : road_cells) {\n        int r = row_seg[i][j];\n        int c = col_seg[i][j];\n        hk_full.addEdge(r, c);\n        cell_of[r][c] = {i, j};\n    }\n\n    // ----- Maximum matching and minimum vertex cover --------------------\n    hk_full.maxMatching();\n\n    vector<bool> visL(R_cnt, false), visR(C_cnt, false);\n    function<void(int)> dfs_cover = [&](int u) {\n        visL[u] = true;\n        for (int v : hk_full.adj[u]) {\n            if (!visR[v] && hk_full.matchL[u] != v) {\n                visR[v] = true;\n                if (hk_full.matchR[v] != -1 && !visL[hk_full.matchR[v]])\n                    dfs_cover(hk_full.matchR[v]);\n            }\n        }\n    };\n    for (int u = 0; u < R_cnt; ++u)\n        if (hk_full.matchL[u] == -1)\n            dfs_cover(u);\n\n    vector<bool> inX(R_cnt, false), inY(C_cnt, false);\n    for (int u = 0; u < R_cnt; ++u) if (!visL[u]) inX[u] = true;\n    for (int v = 0; v < C_cnt; ++v) if (visR[v]) inY[v] = true;\n\n    // ----- Remove start's own segments ----------------------------------\n    int r_start = row_seg[si][sj];\n    int c_start = col_seg[si][sj];\n    if (r_start != -1) inX[r_start] = false;\n    if (c_start != -1) inY[c_start] = false;\n\n    // ----- Collect vertices that still need covering --------------------\n    vector<int> X_list, Y_list;\n    for (int u = 0; u < R_cnt; ++u) if (inX[u]) X_list.push_back(u);\n    for (int v = 0; v < C_cnt; ++v) if (inY[v]) Y_list.push_back(v);\n    int nX = X_list.size(), nY = Y_list.size();\n\n    // If nothing left to cover, we only need to start and return.\n    if (nX == 0 && nY == 0) {\n        // Trivial tour: go to an adjacent road cell and back.\n        for (int d = 0; d < 4; ++d) {\n            int ni = si + di[d], nj = sj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && cost[ni][nj] != -1) {\n                cout << dir_char[d];\n                // Opposite direction\n                if (d == 0) cout << 'D';\n                else if (d == 1) cout << 'U';\n                else if (d == 2) cout << 'R';\n                else cout << 'L';\n                cout << endl;\n                return 0;\n            }\n        }\n        // Should not happen (graph is connected), but fallback:\n        cout << endl;\n        return 0;\n    }\n\n    // ----- Build subgraph between X_list and Y_list --------------------\n    vector<int> X_index(R_cnt, -1), Y_index(C_cnt, -1);\n    for (int i = 0; i < nX; ++i) X_index[X_list[i]] = i;\n    for (int i = 0; i < nY; ++i) Y_index[Y_list[i]] = i;\n\n    HopcroftKarp hk_sub(nX, nY);\n    vector<unordered_map<int, pair<int, int>>> sub_cell_of(nX);\n    for (int r : X_list) {\n        int i = X_index[r];\n        for (auto &[c, coord] : cell_of[r]) {\n            if (inY[c]) {\n                int j = Y_index[c];\n                hk_sub.addEdge(i, j);\n                sub_cell_of[i][j] = {r, c};\n            }\n        }\n    }\n\n    // ----- Maximum matching in subgraph ---------------------------------\n    hk_sub.maxMatching();\n\n    // ----- Precompute distances from start (for picking close cells) ----\n    auto dist_start_res = run_dijkstra(si, sj);\n    auto &dist_start = dist_start_res.dist;\n\n    // ----- Construct set S of cells to visit ----------------------------\n    set<pair<int, int>> S_set;\n\n    // Cells from the matching\n    for (int i = 0; i < nX; ++i) {\n        int j = hk_sub.matchL[i];\n        if (j != -1) {\n            auto [r, c] = sub_cell_of[i][j];\n            S_set.insert(cell_of[r][c]);\n        }\n    }\n\n    // Unmatched row segments: pick closest cell to start\n    for (int i = 0; i < nX; ++i) {\n        if (hk_sub.matchL[i] == -1) {\n            int r = X_list[i];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : row_cells[r]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    // Unmatched column segments: pick closest cell to start\n    for (int j = 0; j < nY; ++j) {\n        if (hk_sub.matchR[j] == -1) {\n            int c = Y_list[j];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : col_cells[c]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    vector<pair<int, int>> points(S_set.begin(), S_set.end());\n    int K = points.size();\n\n    // ----- All-pairs shortest paths among points and start -------------\n    int total_nodes = K + 1;          // indices 0..K-1 : points, K : start\n    vector<vector<int>> dist_mat(total_nodes, vector<int>(total_nodes, INF));\n    vector<DijkstraResult> dijkstra_res(total_nodes);\n\n    for (int idx = 0; idx < total_nodes; ++idx) {\n        int i, j;\n        if (idx < K) {\n            i = points[idx].first, j = points[idx].second;\n        } else {\n            i = si, j = sj;\n        }\n        dijkstra_res[idx] = run_dijkstra(i, j);\n        auto &res = dijkstra_res[idx];\n        for (int other = 0; other < total_nodes; ++other) {\n            int oi, oj;\n            if (other < K) {\n                oi = points[other].first, oj = points[other].second;\n            } else {\n                oi = si, oj = sj;\n            }\n            dist_mat[idx][other] = res.dist[oi][oj];\n        }\n    }\n\n    // ----- Helper function for TSP cost --------------------------------\n    auto compute_order_cost = [&](const vector<int>& ord) {\n        if (ord.empty()) return 0;\n        int total = dist_mat[K][ord[0]];\n        for (size_t i = 0; i + 1 < ord.size(); ++i) {\n            total += dist_mat[ord[i]][ord[i+1]];\n        }\n        total += dist_mat[ord.back()][K];\n        return total;\n    };\n\n    // ----- Build initial tours using multiple heuristics ----------------\n    vector<int> best_order;\n    int best_cost = INF;\n    \n    // Heuristic 1: Nearest neighbor\n    {\n        vector<int> order;\n        vector<bool> visited(K, false);\n        int cur = K;  // start index\n        while ((int)order.size() < K) {\n            int nxt = -1;\n            int best = INF;\n            for (int j = 0; j < K; ++j) {\n                if (!visited[j] && dist_mat[cur][j] < best) {\n                    best = dist_mat[cur][j];\n                    nxt = j;\n                }\n            }\n            if (nxt == -1) break;\n            visited[nxt] = true;\n            order.push_back(nxt);\n            cur = nxt;\n        }\n        int cost = compute_order_cost(order);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_order = order;\n        }\n    }\n    \n    // Heuristic 2: Cheapest insertion\n    {\n        vector<int> order;\n        vector<bool> inserted(K, false);\n        \n        if (K > 0) {\n            // Start with the point that minimizes round trip from start\n            int first = -1;\n            int best_round = INF;\n            for (int i = 0; i < K; ++i) {\n                int round_cost = dist_mat[K][i] + dist_mat[i][K];\n                if (round_cost < best_round) {\n                    best_round = round_cost;\n                    first = i;\n                }\n            }\n            order.push_back(first);\n            inserted[first] = true;\n            \n            // Iteratively insert remaining points\n            while ((int)order.size() < K) {\n                int best_point = -1;\n                int best_pos = -1;\n                int best_increase = INF;\n                \n                for (int i = 0; i < K; ++i) {\n                    if (inserted[i]) continue;\n                    \n                    int m = order.size();\n                    // Try insertion at beginning\n                    int increase = dist_mat[K][i] + dist_mat[i][order[0]] - dist_mat[K][order[0]];\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_point = i;\n                        best_pos = 0;\n                    }\n                    \n                    // Try insertion between points\n                    for (int j = 1; j < m; ++j) {\n                        int a = order[j-1];\n                        int b = order[j];\n                        increase = dist_mat[a][i] + dist_mat[i][b] - dist_mat[a][b];\n                        if (increase < best_increase) {\n                            best_increase = increase;\n                            best_point = i;\n                            best_pos = j;\n                        }\n                    }\n                    \n                    // Try insertion at end\n                    increase = dist_mat[order.back()][i] + dist_mat[i][K] - dist_mat[order.back()][K];\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_point = i;\n                        best_pos = m;\n                    }\n                }\n                \n                order.insert(order.begin() + best_pos, best_point);\n                inserted[best_point] = true;\n            }\n        }\n        \n        int cost = compute_order_cost(order);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_order = order;\n        }\n    }\n\n    // ----- Powerful local search: 2-opt + Or-opt ------------------------\n    auto run_local_search = [&](vector<int> order) {\n        // 2-opt with first improvement\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < K-1; ++i) {\n                for (int j = i+1; j < K; ++j) {\n                    int a = (i == 0) ? K : order[i-1];\n                    int b = order[i];\n                    int c = order[j];\n                    int d = (j == K-1) ? K : order[j+1];\n                    \n                    int old_edges = dist_mat[a][b] + dist_mat[c][d];\n                    int new_edges = dist_mat[a][c] + dist_mat[b][d];\n                    \n                    int old_internal = 0;\n                    for (int k = i; k < j; ++k) {\n                        old_internal += dist_mat[order[k]][order[k+1]];\n                    }\n                    \n                    int new_internal = 0;\n                    for (int k = j; k > i; --k) {\n                        new_internal += dist_mat[order[k]][order[k-1]];\n                    }\n                    \n                    int delta = (new_edges + new_internal) - (old_edges + old_internal);\n                    if (delta < 0) {\n                        reverse(order.begin() + i, order.begin() + j + 1);\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        // Or-opt: relocate segments of length 1, 2, 3\n        improved = true;\n        while (improved) {\n            improved = false;\n            for (int len = 1; len <= 3; ++len) {\n                for (int i = 0; i <= K - len; ++i) {\n                    for (int j = 0; j <= K; ++j) {\n                        if (j >= i && j <= i + len) continue;\n                        \n                        // Build new order by removing segment i..i+len-1\n                        vector<int> new_order;\n                        for (int k = 0; k < K; ++k) {\n                            if (k < i || k >= i + len) {\n                                new_order.push_back(order[k]);\n                            }\n                        }\n                        \n                        // Insert segment at position j\n                        int insert_pos = (j > i) ? j - len : j;\n                        new_order.insert(new_order.begin() + insert_pos, \n                                        order.begin() + i, order.begin() + i + len);\n                        \n                        int new_cost = compute_order_cost(new_order);\n                        int old_cost = compute_order_cost(order);\n                        \n                        if (new_cost < old_cost) {\n                            order = new_order;\n                            improved = true;\n                            break;\n                        }\n                    }\n                    if (improved) break;\n                }\n                if (improved) break;\n            }\n        }\n        \n        return order;\n    };\n    \n    // Apply local search to the best initial tour\n    best_order = run_local_search(best_order);\n    best_cost = compute_order_cost(best_order);\n    \n    // Try to improve further with random restarts\n    random_device rd;\n    mt19937 gen(rd());\n    \n    for (int restart = 0; restart < 5; ++restart) {\n        // Generate a random initial tour\n        vector<int> random_order(K);\n        iota(random_order.begin(), random_order.end(), 0);\n        shuffle(random_order.begin(), random_order.end(), gen);\n        \n        // Apply local search\n        random_order = run_local_search(random_order);\n        int random_cost = compute_order_cost(random_order);\n        \n        if (random_cost < best_cost) {\n            best_cost = random_cost;\n            best_order = random_order;\n        }\n    }\n\n    // ----- Build final tour (start -> best_order -> start) -------------\n    vector<int> tour;\n    tour.push_back(K);                 // start\n    for (int x : best_order) tour.push_back(x);\n    tour.push_back(K);                 // return to start\n\n    // ----- Reconstruct the move string ---------------------------------\n    string moves;\n    for (size_t t = 0; t + 1 < tour.size(); ++t) {\n        int from_idx = tour[t], to_idx = tour[t + 1];\n        auto [fi, fj] = (from_idx < K) ? points[from_idx] : make_pair(si, sj);\n        auto [ti, tj] = (to_idx < K) ? points[to_idx] : make_pair(si, sj);\n        auto &res = dijkstra_res[from_idx];\n\n        // Backtrack from (ti,tj) to (fi,fj)\n        vector<pair<int, int>> path;\n        int ci = ti, cj = tj;\n        while (!(ci == fi && cj == fj)) {\n            path.emplace_back(ci, cj);\n            int pid = res.prev[ci][cj];\n            if (pid == -1) break;      // should not happen\n            auto [pi, pj] = from_id(pid);\n            ci = pi; cj = pj;\n        }\n        path.emplace_back(fi, fj);\n        reverse(path.begin(), path.end());\n\n        // Convert path to moves\n        for (size_t i = 0; i + 1 < path.size(); ++i) {\n            auto [cur_i, cur_j] = path[i];\n            auto [nxt_i, nxt_j] = path[i + 1];\n            for (int d = 0; d < 4; ++d) {\n                if (cur_i + di[d] == nxt_i && cur_j + dj[d] == nxt_j) {\n                    moves += dir_char[d];\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << moves << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N+1, vector<int>(K));\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n        }\n    }\n    \n    // Build dependency graph\n    vector<vector<int>> children(N+1), parents(N+1);\n    vector<int> num_children(N+1, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        children[u].push_back(v);\n        parents[v].push_back(u);\n        num_children[u]++;\n    }\n    \n    // Compute critical path length (primary priority)\n    vector<int> priority1(N+1, 1);\n    for (int i = N; i >= 1; i--) {\n        for (int child : children[i]) {\n            priority1[i] = max(priority1[i], priority1[child] + 1);\n        }\n    }\n    \n    // Secondary priority: number of tasks that depend on this one\n    vector<int> priority2(N+1, 0);\n    for (int i = 1; i <= N; i++) {\n        priority2[i] = num_children[i];\n    }\n    \n    // State tracking\n    vector<int> task_status(N+1, -1); // -1: not started, 0: in progress, 1: completed\n    vector<int> worker_task(M+1, -1); // -1: idle, else: task being worked on\n    vector<vector<int>> worker_skills(M+1, vector<int>(K, 0)); // Lower bounds\n    vector<int> worker_confidence(M+1, 0); // Number of 1-day completions\n    vector<int> start_day(N+1, -1); // Day when task was started\n    vector<int> task_difficulty(N+1, 0); // Total requirement for each task\n    \n    // Precompute task difficulty (sum of requirements)\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            task_difficulty[i] += d[i][k];\n        }\n    }\n    \n    // For randomness\n    auto seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    int day = 0;\n    while (true) {\n        day++;\n        \n        // Find available workers\n        vector<int> available_workers;\n        for (int w = 1; w <= M; w++) {\n            if (worker_task[w] == -1) {\n                available_workers.push_back(w);\n            }\n        }\n        \n        // Find ready tasks (all dependencies completed)\n        vector<int> ready_tasks;\n        for (int t = 1; t <= N; t++) {\n            if (task_status[t] != -1) continue;\n            \n            bool all_deps_completed = true;\n            for (int parent : parents[t]) {\n                if (task_status[parent] != 1) {\n                    all_deps_completed = false;\n                    break;\n                }\n            }\n            \n            if (all_deps_completed) {\n                ready_tasks.push_back(t);\n            }\n        }\n        \n        // Sort ready tasks by combined priority\n        sort(ready_tasks.begin(), ready_tasks.end(), \n             [&](int a, int b) { \n                 if (priority1[a] != priority1[b]) return priority1[a] > priority1[b];\n                 if (priority2[a] != priority2[b]) return priority2[a] > priority2[b];\n                 return task_difficulty[a] > task_difficulty[b]; // Tertiary: harder tasks first\n             });\n        \n        // Prepare assignments\n        vector<pair<int, int>> assignments;\n        vector<bool> worker_used(M+1, false);\n        \n        // Dynamic exploration: reduce exploration as day increases\n        double base_explore_prob = 0.15; // Start with higher exploration\n        double explore_prob = max(0.05, base_explore_prob * exp(-day / 400.0));\n        \n        for (int task : ready_tasks) {\n            if (available_workers.empty()) break;\n            \n            int best_worker = -1;\n            double best_score = -1e18;\n            \n            // With exploration probability, do strategic exploration\n            uniform_real_distribution<double> explore_dist(0.0, 1.0);\n            bool do_exploration = explore_dist(rng) < explore_prob;\n            \n            if (do_exploration && available_workers.size() > 1) {\n                // Strategic exploration: prefer workers with low confidence\n                vector<int> low_confidence_workers;\n                for (int w : available_workers) {\n                    if (worker_confidence[w] < 3) {\n                        low_confidence_workers.push_back(w);\n                    }\n                }\n                \n                if (!low_confidence_workers.empty()) {\n                    // Assign to a low-confidence worker\n                    uniform_int_distribution<int> worker_dist(0, low_confidence_workers.size()-1);\n                    best_worker = low_confidence_workers[worker_dist(rng)];\n                } else {\n                    // All workers have decent confidence, assign randomly\n                    uniform_int_distribution<int> worker_dist(0, available_workers.size()-1);\n                    best_worker = available_workers[worker_dist(rng)];\n                }\n            } else {\n                // Find worker that minimizes expected completion time\n                for (int w : available_workers) {\n                    if (worker_used[w]) continue;\n                    \n                    // Estimate completion time based on current skill bounds\n                    int expected_time = 1;\n                    int deficiency = 0;\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > worker_skills[w][k]) {\n                            deficiency += d[task][k] - worker_skills[w][k];\n                        }\n                    }\n                    if (deficiency > 0) {\n                        expected_time = max(1, deficiency); // Conservative estimate\n                    }\n                    \n                    // Score calculation with multiple factors\n                    double priority_score = priority1[task] * 1000.0 + priority2[task] * 10.0;\n                    double time_penalty = expected_time * 2.0;\n                    double confidence_bonus = min(worker_confidence[w] * 5.0, 50.0);\n                    \n                    // Additional bonus for tasks that match worker's strong skills\n                    double skill_match_bonus = 0.0;\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > 0 && worker_skills[w][k] >= d[task][k]) {\n                            skill_match_bonus += 10.0;\n                        }\n                    }\n                    \n                    // Penalty for very difficult tasks if worker has low confidence\n                    double difficulty_penalty = 0.0;\n                    if (worker_confidence[w] < 3 && task_difficulty[task] > 100) {\n                        difficulty_penalty = 20.0;\n                    }\n                    \n                    double score = priority_score - time_penalty + confidence_bonus + \n                                   skill_match_bonus - difficulty_penalty;\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_worker = w;\n                    }\n                }\n            }\n            \n            if (best_worker != -1) {\n                assignments.emplace_back(best_worker, task);\n                worker_task[best_worker] = task;\n                task_status[task] = 0;\n                start_day[task] = day;\n                \n                // Remove worker from available list\n                available_workers.erase(\n                    remove(available_workers.begin(), available_workers.end(), best_worker),\n                    available_workers.end()\n                );\n                worker_used[best_worker] = true;\n            }\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [w, t] : assignments) {\n            cout << \" \" << w << \" \" << t;\n        }\n        cout << endl;\n        cout.flush();\n        \n        // Read completion information\n        int completion_count;\n        cin >> completion_count;\n        \n        if (completion_count == -1) {\n            break; // End of simulation\n        }\n        \n        // Update based on completions\n        for (int i = 0; i < completion_count; i++) {\n            int worker;\n            cin >> worker;\n            \n            int task = worker_task[worker];\n            if (task != -1) {\n                // Check if completed in 1 day\n                if (day - start_day[task] + 1 == 1) {\n                    // Update skill lower bounds and confidence\n                    for (int k = 0; k < K; k++) {\n                        worker_skills[worker][k] = max(worker_skills[worker][k], d[task][k]);\n                    }\n                    worker_confidence[worker]++;\n                }\n                task_status[task] = 1;\n                worker_task[worker] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nPoint center = {400, 400};\n\ninline int manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Delta cost for inserting pickup X at position p and dropoff Y at position q (p <= q)\n// into the current sequence seq.\nint delta_insert(const vector<int>& seq, int p, int q, int X, int Y,\n                 const vector<vector<int>>& dist) {\n    int n = seq.size();\n    if (n == 0) {\n        // only possible: p = q = 0\n        return dist[100][X] + dist[X][Y] + dist[Y][100];\n    }\n    int A, B;\n    if (p == 0) A = 100; else A = seq[p-1];\n    if (p == n) B = 100; else B = seq[p];\n    if (q == p) {\n        // dropoff immediately after pickup\n        return dist[A][X] + dist[X][Y] + dist[Y][B] - dist[A][B];\n    } else {\n        // q > p\n        int delta = dist[A][X] + dist[X][B] - dist[A][B];\n        // Determine left and right neighbors for Y after X has been inserted\n        int left, right;\n        if (q == n) {\n            left = seq[q-1];\n            right = 100;\n        } else {\n            left = seq[q-1];\n            right = seq[q];\n        }\n        delta += dist[left][Y] + dist[Y][right] - dist[left][right];\n        return delta;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input -----\n    vector<Point> pickup(1000), dropoff(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> pickup[i].x >> pickup[i].y >> dropoff[i].x >> dropoff[i].y;\n    }\n\n    // ----- Order selection -----\n    // Use a score that heavily penalizes long pickup-dropoff distances.\n    // score = d(center, pickup) + d(center, dropoff) + 0.5 * d(pickup, dropoff)\n    vector<int> order_idx(1000);\n    iota(order_idx.begin(), order_idx.end(), 0);\n    vector<double> score(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int d1 = manhattan(center, pickup[i]);\n        int d2 = manhattan(center, dropoff[i]);\n        int d3 = manhattan(pickup[i], dropoff[i]);\n        score[i] = d1 + d2 + 0.5 * d3;\n    }\n    sort(order_idx.begin(), order_idx.end(),\n         [&](int a, int b) { return score[a] < score[b]; });\n    vector<int> selected(order_idx.begin(), order_idx.begin() + 50);  // original 0\u2011based indices\n\n    // ----- Build nodes for selected orders -----\n    // nodes 0..49 : pickups, nodes 50..99 : dropoffs\n    vector<Point> nodes(100);\n    for (int i = 0; i < 50; ++i) {\n        int ord = selected[i];\n        nodes[i] = pickup[ord];\n        nodes[i + 50] = dropoff[ord];\n    }\n\n    // ----- Precompute distances (including center as node 100) -----\n    vector<Point> pts(101);\n    for (int i = 0; i < 100; ++i) pts[i] = nodes[i];\n    pts[100] = center;\n    vector<vector<int>> dist(101, vector<int>(101));\n    for (int i = 0; i < 101; ++i)\n        for (int j = 0; j < 101; ++j)\n            dist[i][j] = manhattan(pts[i], pts[j]);\n\n    // ----- Initial route construction (regret-based insertion) -----\n    vector<int> seq;                     // current sequence of node indices (0..99)\n    vector<bool> used(50, false);        // which orders are already in the route\n    int current_cost = 0;                // total travel time of current route\n\n    for (int step = 0; step < 50; ++step) {\n        int best_order = -1, best_p, best_q, best_delta = INT_MAX;\n        int max_regret = -1;\n        // For each uninserted order, compute best and second best insertion deltas\n        for (int i = 0; i < 50; ++i) {\n            if (used[i]) continue;\n            int X = i;          // pickup node\n            int Y = i + 50;     // dropoff node\n            int n = seq.size();\n            int first_delta = INT_MAX, second_delta = INT_MAX;\n            int first_p, first_q;\n            // Try all insertion positions p (for pickup) and q (for dropoff) with p <= q\n            for (int p = 0; p <= n; ++p) {\n                for (int q = p; q <= n; ++q) {\n                    int delta = delta_insert(seq, p, q, X, Y, dist);\n                    if (delta < first_delta) {\n                        second_delta = first_delta;\n                        first_delta = delta;\n                        first_p = p;\n                        first_q = q;\n                    } else if (delta < second_delta) {\n                        second_delta = delta;\n                    }\n                }\n            }\n            if (first_delta == INT_MAX) continue; // should not happen\n            if (second_delta == INT_MAX) second_delta = first_delta; // only one position (unlikely)\n            int regret = second_delta - first_delta;\n            if (regret > max_regret || (regret == max_regret && first_delta < best_delta)) {\n                max_regret = regret;\n                best_delta = first_delta;\n                best_order = i;\n                best_p = first_p;\n                best_q = first_q;\n            }\n        }\n        // Insert the best order\n        int X = best_order;\n        int Y = best_order + 50;\n        seq.insert(seq.begin() + best_p, X);\n        seq.insert(seq.begin() + best_q + 1, Y);   // after first insertion, index shifts\n        used[best_order] = true;\n        current_cost += best_delta;\n    }\n\n    // ----- Simulated Annealing (swap and move moves) -----\n    int best_cost = current_cost;\n    vector<int> best_seq = seq;\n\n    // Position of each node in the current sequence\n    vector<int> pos(100);\n    for (int i = 0; i < 100; ++i) pos[seq[i]] = i;\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> rand_pos(0, 99);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    const int MAX_ITER = 3500000;\n    double temp = 100.0;\n    const double cooling = 0.9999991;   // slow cooling for many iterations\n\n    // Helper: can we swap positions a and b? (a < b)\n    auto can_swap = [&](int a, int b) -> bool {\n        int nodeA = seq[a], nodeB = seq[b];\n        // For nodeA\n        bool pickupA = (nodeA < 50);\n        int new_pos_pickupA, new_pos_dropoffA;\n        if (pickupA) {\n            new_pos_pickupA = b;\n            int dropoffA = nodeA + 50;\n            new_pos_dropoffA = (dropoffA == nodeB) ? a : pos[dropoffA];\n        } else {\n            new_pos_dropoffA = b;\n            int pickupA = nodeA - 50;\n            new_pos_pickupA = (pickupA == nodeB) ? a : pos[pickupA];\n        }\n        if (new_pos_pickupA >= new_pos_dropoffA) return false;\n\n        // For nodeB\n        bool pickupB = (nodeB < 50);\n        int new_pos_pickupB, new_pos_dropoffB;\n        if (pickupB) {\n            new_pos_pickupB = a;\n            int dropoffB = nodeB + 50;\n            new_pos_dropoffB = (dropoffB == nodeA) ? b : pos[dropoffB];\n        } else {\n            new_pos_dropoffB = a;\n            int pickupB = nodeB - 50;\n            new_pos_pickupB = (pickupB == nodeA) ? b : pos[pickupB];\n        }\n        if (new_pos_pickupB >= new_pos_dropoffB) return false;\n\n        return true;\n    };\n\n    // Helper: delta cost for swapping positions a and b (a < b)\n    auto delta_swap = [&](int a, int b) -> int {\n        int n1 = seq[a], n2 = seq[b];\n        int old_cost = 0, new_cost = 0;\n\n        auto get_node = [&](int p) -> int {\n            if (p < 0 || p >= 100) return 100;\n            return seq[p];\n        };\n\n        int lefts[4] = {a-1, a, b-1, b};\n        bool used[4] = {false};\n        for (int i = 0; i < 4; ++i) {\n            if (used[i]) continue;\n            int lp = lefts[i];\n            if (lp < -1 || lp >= 100) continue;\n            for (int j = i+1; j < 4; ++j)\n                if (lefts[j] == lp) used[j] = true;\n\n            int u = get_node(lp);\n            int v = get_node(lp+1);\n            old_cost += dist[u][v];\n\n            int u_new = (lp == a) ? n2 : (lp == b) ? n1 : u;\n            int v_new = (lp+1 == a) ? n2 : (lp+1 == b) ? n1 : v;\n            new_cost += dist[u_new][v_new];\n        }\n        return new_cost - old_cost;\n    };\n\n    // Helper: can we move node at position i to position j? (j != i)\n    auto can_move = [&](int i, int j) -> bool {\n        int node = seq[i];\n        bool pickup = (node < 50);\n        int cp = pickup ? node + 50 : node - 50; // counterpart\n        int cp_pos = pos[cp];\n\n        // Compute new position of counterpart after move\n        int cp_new;\n        if (cp_pos == i) {\n            // Should not happen because node != cp\n            return false;\n        } else if (cp_pos > i) {\n            cp_new = cp_pos - 1; // after removal, shift left\n        } else {\n            cp_new = cp_pos;\n        }\n        // After insertion at j, if j <= cp_new, counterpart shifts right\n        if (j <= cp_new) {\n            cp_new++;\n        }\n\n        if (pickup) {\n            return j < cp_new;\n        } else {\n            return j > cp_new;\n        }\n    };\n\n    // Helper: delta cost for moving node at position i to position j (j != i)\n    auto delta_move = [&](int i, int j) -> int {\n        int n = seq.size();\n        int X = seq[i];\n        int A = (i == 0) ? 100 : seq[i-1];\n        int B = (i == n-1) ? 100 : seq[i+1];\n        int delta1 = dist[A][B] - dist[A][X] - dist[X][B];\n\n        // Now compute C and D in the reduced sequence S' (seq without X)\n        // We insert X at position j in the final sequence, which corresponds to\n        // insertion index j_in_S = j in S' (as reasoned).\n        int j_in_S = j;\n        int C, D;\n        if (j_in_S == 0) {\n            C = 100;\n            if (n == 1) {\n                D = 100; // not happening because n=100\n            } else {\n                // Right neighbor is S'[0]\n                if (0 < i) D = seq[0];\n                else D = seq[1]; // because i=0, S'[0] = seq[1]\n            }\n        } else if (j_in_S == n-1) {\n            D = 100;\n            // Left neighbor is S'[n-2]\n            int idx = n-2; // index in S'\n            if (idx < i) C = seq[idx];\n            else C = seq[idx+1];\n        } else {\n            // General case\n            // Left neighbor: S'[j_in_S-1]\n            int idx_left = j_in_S - 1;\n            if (idx_left < i) C = seq[idx_left];\n            else C = seq[idx_left+1];\n            // Right neighbor: S'[j_in_S]\n            int idx_right = j_in_S;\n            if (idx_right < i) D = seq[idx_right];\n            else D = seq[idx_right+1];\n        }\n        int delta2 = dist[C][X] + dist[X][D] - dist[C][D];\n        return delta1 + delta2;\n    };\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        temp *= cooling;\n        if (rand_real(gen) < 0.5) {\n            // Swap move\n            int a = rand_pos(gen);\n            int b = rand_pos(gen);\n            if (a == b) continue;\n            if (a > b) swap(a, b);\n            if (!can_swap(a, b)) continue;\n\n            int delta = delta_swap(a, b);\n            if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n                int nodeA = seq[a], nodeB = seq[b];\n                seq[a] = nodeB;\n                seq[b] = nodeA;\n                pos[nodeA] = b;\n                pos[nodeB] = a;\n                current_cost += delta;\n                if (current_cost < best_cost) {\n                    best_cost = current_cost;\n                    best_seq = seq;\n                }\n            }\n        } else {\n            // Move move\n            int i = rand_pos(gen);\n            int j = rand_pos(gen);\n            if (i == j) continue;\n            if (!can_move(i, j)) continue;\n\n            int delta = delta_move(i, j);\n            if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n                int node = seq[i];\n                // Remove node at i\n                seq.erase(seq.begin() + i);\n                // Insert at j (after removal, indices shift if j > i)\n                if (j > i) j--;\n                seq.insert(seq.begin() + j, node);\n                // Update positions\n                for (int k = 0; k < 100; ++k) pos[seq[k]] = k;\n                current_cost += delta;\n                if (current_cost < best_cost) {\n                    best_cost = current_cost;\n                    best_seq = seq;\n                }\n            }\n        }\n    }\n\n    // ----- Output -----\n    // Selected orders (convert to 1\u2011based)\n    cout << \"50\";\n    for (int idx : selected) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n\n    // Full route: center -> best_seq -> center\n    vector<Point> route;\n    route.push_back(center);\n    for (int id : best_seq) route.push_back(nodes[id]);\n    route.push_back(center);\n\n    cout << route.size();\n    for (Point p : route) cout << \" \" << p.x << \" \" << p.y;\n    cout << endl;\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    // Read coordinates (N lines)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Read edges (M lines)\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n    }\n\n    // Process each edge length and always adopt\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        cout << \"1\" << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID = 30;\nconst int MAX_TURNS = 300;\n\nint N, M;\nvector<int> pet_x, pet_y, pet_type;\nvector<int> human_x, human_y;\nbool wall[GRID+1][GRID+1] = {false};\n\nconst int dx[4] = {1, -1, 0, 0};\nconst int dy[4] = {0, 0, 1, -1};\n\nbool inside(int x, int y) {\n    return 1 <= x && x <= GRID && 1 <= y && y <= GRID;\n}\n\nbool passable(int x, int y) {\n    return inside(x, y) && !wall[x][y];\n}\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; ++i)\n        if (pet_x[i] == x && pet_y[i] == y)\n            return true;\n    return false;\n}\n\nbool has_adjacent_pet(int x, int y) {\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + dx[d], ny = y + dy[d];\n        if (inside(nx, ny) && has_pet_at(nx, ny))\n            return true;\n    }\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; ++i)\n        if (human_x[i] == x && human_y[i] == y)\n            return true;\n    return false;\n}\n\nbool can_build(int x, int y) {\n    return inside(x, y) && !wall[x][y] && !has_pet_at(x, y) && \n           !has_human_at(x, y) && !has_adjacent_pet(x, y);\n}\n\n// Safe movement: check if target square is passable and not occupied by a pet\nchar safe_move_towards(int cx, int cy, int tx, int ty) {\n    if (cx == tx && cy == ty) return '.';\n    \n    // Try to move in the direction that reduces distance\n    int best_dx = 0, best_dy = 0;\n    int best_dist = abs(cx - tx) + abs(cy - ty);\n    \n    // Check all four directions\n    for (int d = 0; d < 4; ++d) {\n        int nx = cx + dx[d], ny = cy + dy[d];\n        if (passable(nx, ny) && !has_pet_at(nx, ny)) {\n            int dist = abs(nx - tx) + abs(ny - ty);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dx = dx[d];\n                best_dy = dy[d];\n            }\n        }\n    }\n    \n    if (best_dx == 0 && best_dy == 0) return '.'; // No valid move\n    \n    if (best_dx == 1) return 'D';\n    if (best_dx == -1) return 'U';\n    if (best_dy == 1) return 'R';\n    if (best_dy == -1) return 'L';\n    return '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    pet_x.resize(N); pet_y.resize(N); pet_type.resize(N);\n    for (int i = 0; i < N; ++i)\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n    cin >> M;\n    human_x.resize(M); human_y.resize(M);\n    for (int i = 0; i < M; ++i)\n        cin >> human_x[i] >> human_y[i];\n\n    // Strategy: Build walls around each human to create small safe zones,\n    // and move towards other humans to merge safe zones.\n    \n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\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            \n            // First priority: build walls in the four cardinal directions if safe\n            bool built = false;\n            for (int d = 0; d < 4; ++d) {\n                int wx = hx + dx[d], wy = hy + dy[d];\n                if (can_build(wx, wy)) {\n                    // Determine build action based on direction\n                    if (dx[d] == -1) actions[i] = 'u';  // Build up\n                    else if (dx[d] == 1) actions[i] = 'd'; // Build down\n                    else if (dy[d] == -1) actions[i] = 'l'; // Build left\n                    else if (dy[d] == 1) actions[i] = 'r'; // Build right\n                    \n                    wall[wx][wy] = true;\n                    built = true;\n                    break;\n                }\n            }\n            \n            if (!built) {\n                // Second priority: move towards the nearest other human\n                int nearest_human_dist = 1000;\n                int target_x = hx, target_y = hy;\n                \n                for (int j = 0; j < M; ++j) {\n                    if (i == j) continue;\n                    int dist = abs(hx - human_x[j]) + abs(hy - human_y[j]);\n                    if (dist < nearest_human_dist) {\n                        nearest_human_dist = dist;\n                        target_x = human_x[j];\n                        target_y = human_y[j];\n                    }\n                }\n                \n                if (nearest_human_dist > 1) {  // Only move if not already adjacent\n                    actions[i] = safe_move_towards(hx, hy, target_x, target_y);\n                } else {\n                    // Already adjacent or no other human, try to move away from pets\n                    int max_min_pet_dist = -1;\n                    int best_dx = 0, best_dy = 0;\n                    \n                    for (int d = 0; d < 4; ++d) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        if (passable(nx, ny) && !has_pet_at(nx, ny)) {\n                            int min_pet_dist = 1000;\n                            for (int p = 0; p < N; ++p) {\n                                int dist = abs(nx - pet_x[p]) + abs(ny - pet_y[p]);\n                                min_pet_dist = min(min_pet_dist, dist);\n                            }\n                            \n                            if (min_pet_dist > max_min_pet_dist) {\n                                max_min_pet_dist = min_pet_dist;\n                                best_dx = dx[d];\n                                best_dy = dy[d];\n                            }\n                        }\n                    }\n                    \n                    if (max_min_pet_dist > -1) {\n                        if (best_dx == 1) actions[i] = 'D';\n                        else if (best_dx == -1) actions[i] = 'U';\n                        else if (best_dy == 1) actions[i] = 'R';\n                        else if (best_dy == -1) actions[i] = 'L';\n                    } else {\n                        actions[i] = '.';\n                    }\n                }\n            }\n        }\n        \n        // Output actions\n        for (char c : actions) cout << c;\n        cout << endl;\n        cout.flush();\n        \n        // Update human positions based on actions (movement only)\n        for (int i = 0; i < M; ++i) {\n            if (actions[i] == 'U') human_x[i]--;\n            else if (actions[i] == 'D') human_x[i]++;\n            else if (actions[i] == 'L') human_y[i]--;\n            else if (actions[i] == 'R') human_y[i]++;\n            // Build actions (lowercase) don't move humans\n        }\n        \n        // Read pet movements\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20, W = 20;\nconst int N = H * W; // 400\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint si, sj, ti, tj;\ndouble p;\nint h[H][W - 1]; // horizontal walls: between (i,j) and (i,j+1)\nint v[H - 1][W]; // vertical walls: between (i,j) and (i+1,j)\n\nstruct MoveData {\n    int nxt_idx;      // linear index of neighbor, -1 if blocked\n    float stay;       // probability to stay\n    float move;       // probability to move (0 if blocked)\n    bool is_target;   // does moving lead directly to the office?\n};\nMoveData move_info[N][4];\nint dir_to_idx[256];\n\n// Convert (i,j) to linear index\ninline int to_idx(int i, int j) { return i * W + j; }\n// Convert linear index to (i,j)\ninline pair<int, int> to_pos(int idx) { return {idx / W, idx % W}; }\n\n// Precompute transition data for every cell and direction.\nvoid precompute_move_info() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = to_idx(i, j);\n            for (int d = 0; d < 4; ++d) {\n                auto& data = move_info[idx][d];\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                bool blocked = false;\n                if (d == 0) { // U\n                    if (i == 0) blocked = true;\n                    else if (v[i - 1][j] == 1) blocked = true;\n                } else if (d == 1) { // D\n                    if (i == H - 1) blocked = true;\n                    else if (v[i][j] == 1) blocked = true;\n                } else if (d == 2) { // L\n                    if (j == 0) blocked = true;\n                    else if (h[i][j - 1] == 1) blocked = true;\n                } else { // R\n                    if (j == W - 1) blocked = true;\n                    else if (h[i][j] == 1) blocked = true;\n                }\n                data.stay = p + (1 - p) * blocked;\n                data.move = blocked ? 0.0f : (1 - p);\n                data.is_target = (!blocked && ni == ti && nj == tj);\n                if (!blocked) {\n                    data.nxt_idx = to_idx(ni, nj);\n                } else {\n                    data.nxt_idx = -1;\n                }\n            }\n        }\n    }\n    dir_to_idx['U'] = 0;\n    dir_to_idx['D'] = 1;\n    dir_to_idx['L'] = 2;\n    dir_to_idx['R'] = 3;\n}\n\n// Compute expected score for a given command string.\ndouble compute_score(const string& s) {\n    float cur[N] = {0};\n    float nxt[N];\n    cur[to_idx(si, sj)] = 1.0f;\n    double score = 0.0;\n    int L = s.size();\n    for (int step = 0; step < L; ++step) {\n        int d = dir_to_idx[s[step]];\n        // Clear nxt array\n        fill(nxt, nxt + N, 0.0f);\n        for (int idx = 0; idx < N; ++idx) {\n            float prob = cur[idx];\n            if (prob == 0.0f) continue;\n            const MoveData& data = move_info[idx][d];\n            nxt[idx] += prob * data.stay;\n            if (data.move > 0) {\n                if (data.is_target) {\n                    score += (401 - (step + 1)) * prob * data.move;\n                } else {\n                    nxt[data.nxt_idx] += prob * data.move;\n                }\n            }\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\n// BFS to find a shortest valid path (ignoring forgetting).\nstring bfs_path() {\n    queue<pair<int, int>> q;\n    vector<vector<bool>> visited(H, vector<bool>(W, false));\n    vector<vector<int>> parent_i(H, vector<int>(W, -1));\n    vector<vector<int>> parent_j(H, vector<int>(W, -1));\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            const MoveData& data = move_info[to_idx(i, j)][d];\n            if (data.move > 0) { // move allowed\n                auto [ni, nj] = to_pos(data.nxt_idx);\n                if (!visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent_i[ni][nj] = i;\n                    parent_j[ni][nj] = j;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n    // Reconstruct path from target to start.\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int pi = parent_i[ci][cj];\n        int pj = parent_j[ci][cj];\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Repeat a string to reach length max_len (truncate if longer).\nstring repeat_to_length(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U'); // fallback\n    string result;\n    while (result.size() < max_len) {\n        result += s;\n    }\n    result.resize(max_len);\n    return result;\n}\n\n// Generate a random string biased towards the target.\nstring random_biased_string(int len, mt19937& rng) {\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    string s;\n    int ci = si, cj = sj;\n    for (int i = 0; i < len; ++i) {\n        // With probability 0.7, try to move towards target.\n        if (uniform(rng) < 0.7) {\n            // Choose a direction that reduces Manhattan distance if possible.\n            int best_dir = -1;\n            int best_dist = 1000;\n            for (int d = 0; d < 4; ++d) {\n                const MoveData& data = move_info[to_idx(ci, cj)][d];\n                if (data.move > 0) {\n                    auto [ni, nj] = to_pos(data.nxt_idx);\n                    int dist = abs(ni - ti) + abs(nj - tj);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_dir = d;\n                    }\n                }\n            }\n            if (best_dir != -1) {\n                s += dir_chars[best_dir];\n                auto [ni, nj] = to_pos(move_info[to_idx(ci, cj)][best_dir].nxt_idx);\n                ci = ni; cj = nj;\n                continue;\n            }\n        }\n        // Otherwise random direction.\n        int d = rand_dir(rng);\n        const MoveData& data = move_info[to_idx(ci, cj)][d];\n        if (data.move > 0) {\n            s += dir_chars[d];\n            auto [ni, nj] = to_pos(data.nxt_idx);\n            ci = ni; cj = nj;\n        } else {\n            // If blocked, just add a random direction (will stay).\n            s += dir_chars[d];\n        }\n    }\n    return s;\n}\n\n// Generate a string where each move is duplicated (e.g., DDRR becomes DDRRDDRR).\nstring duplicated_moves(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U');\n    string result;\n    for (char c : s) {\n        result += c;\n        result += c;\n        if (result.size() >= max_len) break;\n    }\n    result.resize(max_len);\n    return result;\n}\n\n// Ensure the string contains only UDLR and length between 1 and 200.\nstring sanitize(const string& s) {\n    if (s.empty()) return \"U\";\n    string res = s;\n    for (char& c : res) {\n        if (c != 'U' && c != 'D' && c != 'L' && c != 'R') {\n            c = 'U'; // replace any invalid char with 'U'\n        }\n    }\n    if (res.size() > 200) res.resize(200);\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj >> ti >> tj >> p;\n    for (int i = 0; i < 20; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 19; ++j) h[i][j] = line[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 20; ++j) v[i][j] = line[j] - '0';\n    }\n\n    precompute_move_info();\n\n    // Random generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    auto rand_index = [&](int n) -> int {\n        return uniform_int_distribution<int>(0, n - 1)(rng);\n    };\n\n    // Initial candidates\n    string best_str;\n    double best_score = -1;\n\n    // Candidate 1: BFS path\n    string bfs_str = bfs_path();\n    bfs_str = sanitize(bfs_str);\n    double bfs_score = compute_score(bfs_str);\n    if (bfs_score > best_score) {\n        best_score = bfs_score;\n        best_str = bfs_str;\n    }\n\n    // Candidate 2: doubled BFS path if fits\n    if (bfs_str.size() * 2 <= 200) {\n        string doubled = bfs_str + bfs_str;\n        doubled = sanitize(doubled);\n        double doubled_score = compute_score(doubled);\n        if (doubled_score > best_score) {\n            best_score = doubled_score;\n            best_str = doubled;\n        }\n    }\n\n    // Candidate 3: repeated BFS path to length 200\n    string repeated = repeat_to_length(bfs_str, 200);\n    repeated = sanitize(repeated);\n    double repeated_score = compute_score(repeated);\n    if (repeated_score > best_score) {\n        best_score = repeated_score;\n        best_str = repeated;\n    }\n\n    // Candidate 4: duplicated moves version of BFS path\n    string dup = duplicated_moves(bfs_str, 200);\n    dup = sanitize(dup);\n    double dup_score = compute_score(dup);\n    if (dup_score > best_score) {\n        best_score = dup_score;\n        best_str = dup;\n    }\n\n    // Candidate 5-6: random biased strings\n    for (int trial = 0; trial < 2; ++trial) {\n        string rand_str = random_biased_string(200, rng);\n        rand_str = sanitize(rand_str);\n        double rand_score = compute_score(rand_str);\n        if (rand_score > best_score) {\n            best_score = rand_score;\n            best_str = rand_str;\n        }\n    }\n\n    string current = best_str;\n    double current_score = best_score;\n\n    const double time_limit = 1.8; // seconds\n    auto start_time = chrono::steady_clock::now();\n\n    double start_temp = 1.0;\n    double end_temp = 1e-4;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        double progress = elapsed / time_limit;\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        // Generate neighbour solution\n        string neighbour = current;\n        int L = neighbour.size();\n\n        // Operation probabilities\n        double op = uniform(rng);\n        if (op < 0.20) { // replace single\n            int pos = rand_index(L);\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour[pos] = newc;\n        } else if (op < 0.50 && L < 200) { // insert\n            int pos = rand_index(L + 1);\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour.insert(neighbour.begin() + pos, newc);\n        } else if (op < 0.70 && L > 1) { // delete\n            int pos = rand_index(L);\n            neighbour.erase(neighbour.begin() + pos);\n        } else if (op < 0.80 && L >= 2) { // swap adjacent\n            int pos = rand_index(L - 1);\n            swap(neighbour[pos], neighbour[pos + 1]);\n        } else if (op < 0.90 && L >= 5) { // reverse substring\n            int max_len = min(10, L - 1);\n            int len = uniform_int_distribution<int>(2, max_len)(rng);\n            int start = rand_index(L - len + 1);\n            reverse(neighbour.begin() + start, neighbour.begin() + start + len);\n        } else if (L >= 5) { // block replace\n            int max_len = min(5, L);\n            int len = uniform_int_distribution<int>(2, max_len)(rng);\n            int start = rand_index(L - len + 1);\n            string block;\n            for (int i = 0; i < len; ++i) {\n                block += dir_chars[rand_dir(rng)];\n            }\n            neighbour.replace(start, len, block);\n        } else {\n            // fallback: replace\n            int pos = rand_index(L);\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour[pos] = newc;\n        }\n\n        neighbour = sanitize(neighbour);\n        double new_score = compute_score(neighbour);\n        double delta = new_score - current_score;\n        if (delta > 0 || uniform(rng) < exp(delta / T)) {\n            current = move(neighbour);\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_str = current;\n            }\n        }\n    }\n\n    best_str = sanitize(best_str);\n    cout << best_str << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cstring>\n#include <cmath>\n#include <chrono>\n#include <queue>\n\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Predefined connection table from problem statement\nconst int 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 grid[N][N];\nint conn[N][N][4]; // Internal connections for each tile\n\n// Compute internal connections based on rotations\nvoid compute_conn(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            int r = rotations[i][j];\n            for (int d = 0; d < 4; d++) {\n                int d0 = (d - r + 4) % 4;\n                if (to[type][d0] == -1) {\n                    conn[i][j][d] = -1;\n                } else {\n                    conn[i][j][d] = (to[type][d0] + r) % 4;\n                }\n            }\n        }\n    }\n}\n\n// Optimized cycle detection using BFS from each half-edge\nint compute_score(int rotations[][N]) {\n    compute_conn(rotations);\n    vector<bool> visited(N*N*4, false);\n    vector<int> cycle_lengths;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                int start_id = (i*N + j)*4 + d;\n                if (conn[i][j][d] != -1 && !visited[start_id]) {\n                    // Use BFS to find the component\n                    queue<int> q;\n                    q.push(start_id);\n                    visited[start_id] = true;\n                    int count = 0;\n                    bool is_cycle = true;\n                    vector<int> component;\n                    \n                    while (!q.empty()) {\n                        int cur_id = q.front();\n                        q.pop();\n                        component.push_back(cur_id);\n                        count++;\n                        \n                        int tile_id = cur_id / 4;\n                        int ci = tile_id / N;\n                        int cj = tile_id % N;\n                        int cd = cur_id % 4;\n                        \n                        // Check internal connection\n                        int d2 = conn[ci][cj][cd];\n                        if (d2 != -1) {\n                            int internal_id = (ci*N + cj)*4 + d2;\n                            if (!visited[internal_id]) {\n                                visited[internal_id] = true;\n                                q.push(internal_id);\n                            }\n                        }\n                        \n                        // Check external connection\n                        int ni = ci + di[cd];\n                        int nj = cj + dj[cd];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            int opp_d = (cd + 2) % 4;\n                            if (conn[ni][nj][opp_d] != -1) {\n                                int external_id = (ni*N + nj)*4 + opp_d;\n                                if (!visited[external_id]) {\n                                    visited[external_id] = true;\n                                    q.push(external_id);\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Check if it's a cycle: all nodes should have degree 2\n                    for (int id : component) {\n                        int tile_id = id / 4;\n                        int ci = tile_id / N;\n                        int cj = tile_id % N;\n                        int cd = id % 4;\n                        \n                        int degree = 0;\n                        // Internal connection\n                        if (conn[ci][cj][cd] != -1) degree++;\n                        // External connection\n                        int ni = ci + di[cd];\n                        int nj = cj + dj[cd];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n                            conn[ni][nj][(cd+2)%4] != -1) {\n                            degree++;\n                        }\n                        \n                        if (degree != 2) {\n                            is_cycle = false;\n                            break;\n                        }\n                    }\n                    \n                    if (is_cycle && count >= 4) { // Minimum cycle has 2 edges = 4 half-edges\n                        cycle_lengths.push_back(count / 2);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Sort and get top two\n    if (cycle_lengths.empty()) return 0;\n    sort(cycle_lengths.rbegin(), cycle_lengths.rend());\n    int L1 = cycle_lengths[0];\n    int L2 = cycle_lengths.size() > 1 ? cycle_lengths[1] : 0;\n    return L1 * L2;\n}\n\n// Generate a good initial solution by aligning straight tiles\nvoid generate_initial_solution(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            if (type == 6) { // Horizontal straight\n                // Try to align with left/right neighbors\n                rotations[i][j] = 0; // Default horizontal\n                // Check if we should rotate to vertical\n                bool left_ok = (j > 0) && (grid[i][j-1] == 7);\n                bool right_ok = (j < N-1) && (grid[i][j+1] == 7);\n                if (left_ok || right_ok) {\n                    rotations[i][j] = 1; // Rotate to vertical\n                }\n            } else if (type == 7) { // Vertical straight\n                rotations[i][j] = 0; // Default vertical\n                // Check if we should rotate to horizontal\n                bool up_ok = (i > 0) && (grid[i-1][j] == 6);\n                bool down_ok = (i < N-1) && (grid[i+1][j] == 6);\n                if (up_ok || down_ok) {\n                    rotations[i][j] = 1; // Rotate to horizontal\n                }\n            } else if (type >= 4 && type <= 5) { // Double curves\n                // Random for now\n                rotations[i][j] = rand() % 4;\n            } else { // Single curves\n                // Try to connect to neighbors\n                rotations[i][j] = rand() % 4;\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[j] - '0';\n        }\n    }\n\n    // Initialize random number generators\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> tile_dist(0, N*N-1);\n    uniform_int_distribution<> rot_dist(0, 3);\n    uniform_real_distribution<> prob_dist(0.0, 1.0);\n\n    // Start with a better initial solution\n    int current_rotations[N][N];\n    generate_initial_solution(current_rotations);\n    int current_score = compute_score(current_rotations);\n    \n    // Keep track of best solution\n    int best_rotations[N][N];\n    memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n    int best_score = current_score;\n\n    // Simulated annealing parameters - more aggressive\n    double temperature = 20.0;\n    double cooling_rate = 0.9999;\n    int sa_steps = 20000;\n    int no_improve_count = 0;\n    int restart_threshold = 2000;\n\n    // Simulated annealing with restarts\n    for (int step = 0; step < sa_steps; step++) {\n        // If stuck, restart from best solution\n        if (no_improve_count > restart_threshold) {\n            memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n            current_score = best_score;\n            temperature = 20.0; // Reset temperature\n            no_improve_count = 0;\n        }\n\n        // Pick a random tile and a new rotation\n        int tile_idx = tile_dist(gen);\n        int i = tile_idx / N;\n        int j = tile_idx % N;\n        int old_rot = current_rotations[i][j];\n        int new_rot = rot_dist(gen);\n        \n        // Skip if same rotation\n        if (new_rot == old_rot) {\n            continue;\n        }\n\n        // Apply change\n        current_rotations[i][j] = new_rot;\n        int new_score = compute_score(current_rotations);\n\n        // Decide whether to accept the new solution\n        int score_diff = new_score - current_score;\n        if (score_diff > 0 || \n            prob_dist(gen) < exp(score_diff / temperature)) {\n            // Accept\n            current_score = new_score;\n            no_improve_count = 0;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n            }\n        } else {\n            // Reject - revert change\n            current_rotations[i][j] = old_rot;\n            no_improve_count++;\n        }\n\n        // Cool down\n        temperature *= cooling_rate;\n    }\n\n    // Final intensive greedy search on promising tiles\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    current_score = best_score;\n    \n    // Focus on tiles that are part of cycles or could connect cycles\n    for (int iter = 0; iter < 3; iter++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int original = current_rotations[i][j];\n                int best_local_score = current_score;\n                int best_local_rot = original;\n                \n                for (int r = 0; r < 4; r++) {\n                    if (r == original) continue;\n                    current_rotations[i][j] = r;\n                    int new_score = compute_score(current_rotations);\n                    if (new_score > best_local_score) {\n                        best_local_score = new_score;\n                        best_local_rot = r;\n                    }\n                }\n                \n                current_rotations[i][j] = best_local_rot;\n                if (best_local_score > current_score) {\n                    current_score = best_local_score;\n                    if (current_score > best_score) {\n                        best_score = current_score;\n                        memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n                    }\n                }\n            }\n        }\n    }\n\n    // Output best solution found\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <cstring>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Direction arrays: L, R, U, D\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'L', 'R', 'U', 'D'};\nconst int dir_bit[4] = {1, 4, 2, 8};  // L=1, R=4, U=2, D=8\nconst int opposite[4] = {1, 0, 3, 2};  // opposite directions\n\nint N, T;\nvector<vector<int>> board;\nint empty_r, empty_c;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Check if moving in direction d is valid\nbool can_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    return nr >= 0 && nr < N && nc >= 0 && nc < N && board[nr][nc] != 0;\n}\n\n// Execute move in direction d\nvoid make_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    empty_r = nr;\n    empty_c = nc;\n}\n\n// Board analysis: returns (max_tree_size, extra_edges, components)\ntuple<int, int, int> analyze_board() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree_size = 0;\n    int total_components = 0;\n    int total_vertices = 0;\n    int total_edges = 0;\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]) {\n                total_components++;\n                // BFS to find component\n                vector<pair<int,int>> component;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [r, c] = q.front();\n                    q.pop();\n                    component.push_back({r, c});\n                    total_vertices++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dy[d];\n                        int nc = c + dx[d];\n                        if (nr >= 0 && nr < N && nc >= 0 && nc < N && \n                            board[nr][nc] != 0 && !visited[nr][nc]) {\n                            // Check if connection exists\n                            int curr_bit = dir_bit[d];\n                            int next_bit = dir_bit[opposite[d]];\n                            if ((board[r][c] & curr_bit) && (board[nr][nc] & next_bit)) {\n                                visited[nr][nc] = true;\n                                q.push({nr, nc});\n                            }\n                        }\n                    }\n                }\n                \n                // Count edges in component\n                int V = component.size();\n                int E = 0;\n                vector<vector<bool>> in_comp(N, vector<bool>(N, false));\n                for (auto [r, c] : component) {\n                    in_comp[r][c] = true;\n                }\n                \n                for (auto [r, c] : component) {\n                    // Check right neighbor\n                    if (c + 1 < N && in_comp[r][c+1]) {\n                        if ((board[r][c] & 4) && (board[r][c+1] & 1)) {\n                            E++;\n                        }\n                    }\n                    // Check down neighbor\n                    if (r + 1 < N && in_comp[r+1][c]) {\n                        if ((board[r][c] & 8) && (board[r+1][c] & 2)) {\n                            E++;\n                        }\n                    }\n                }\n                \n                total_edges += E;\n                \n                // Check if this component is a tree\n                if (E == V - 1) {\n                    max_tree_size = max(max_tree_size, V);\n                }\n            }\n        }\n    }\n    \n    // Calculate extra edges (edges that create cycles)\n    int extra_edges = total_edges - (total_vertices - total_components);\n    if (extra_edges < 0) extra_edges = 0;\n    \n    return {max_tree_size, extra_edges, total_components};\n}\n\n// Enhanced move evaluation with adaptive strategy\npair<int, int> evaluate_move(int d, int step, int current_tree_size) {\n    // Simulate move\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    int saved_er = empty_r, saved_ec = empty_c;\n    empty_r = nr;\n    empty_c = nc;\n    \n    auto [tree_size, extra_edges, components] = analyze_board();\n    \n    // Adaptive scoring based on progress\n    int score = 0;\n    \n    // Phase 1: Focus on building large trees (first 70% of moves)\n    if (step < T * 0.7) {\n        score = tree_size * 100000;\n        \n        // Reward connecting components\n        auto [old_tree_size, old_extra_edges, old_components] = analyze_board();\n        // We need to get old_components from the original state, but we already simulated the move.\n        // Instead, we can compute the change in components by comparing with current state.\n        // We'll compute old components by analyzing the original board (but we already swapped).\n        // Let's restore and compute old state, then re-simulate.\n        \n        // Restore temporarily\n        empty_r = saved_er;\n        empty_c = saved_ec;\n        swap(board[empty_r][empty_c], board[nr][nc]);\n        auto [old_tree, old_extra, old_comp] = analyze_board();\n        \n        // Re-simulate\n        swap(board[empty_r][empty_c], board[nr][nc]);\n        empty_r = nr;\n        empty_c = nc;\n        \n        // Reward for reducing components\n        if (components < old_comp) {\n            score += 50000;\n        }\n        \n        // Reward for increasing tree size\n        if (tree_size > old_tree) {\n            score += 30000;\n        }\n    } \n    // Phase 2: Focus on cycle reduction (last 30% of moves)\n    else {\n        score = tree_size * 50000;\n        \n        // Get old state\n        empty_r = saved_er;\n        empty_c = saved_ec;\n        swap(board[empty_r][empty_c], board[nr][nc]);\n        auto [old_tree, old_extra, old_comp] = analyze_board();\n        \n        // Re-simulate\n        swap(board[empty_r][empty_c], board[nr][nc]);\n        empty_r = nr;\n        empty_c = nc;\n        \n        // Heavily penalize extra edges\n        score -= extra_edges * 10000;\n        \n        // Reward reducing extra edges\n        if (extra_edges < old_extra) {\n            score += 20000;\n        }\n    }\n    \n    // Bonus for achieving full tree\n    if (tree_size == N * N - 1) {\n        score += 1000000;\n    }\n    \n    // Small penalty for many components\n    score -= components * 50;\n    \n    // Restore board\n    empty_r = saved_er;\n    empty_c = saved_ec;\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    \n    return {score, tree_size};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.resize(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] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_r = i;\n                empty_c = j;\n            }\n        }\n    }\n    \n    string moves;\n    auto [current_max, current_extra, current_comp] = analyze_board();\n    \n    // Random move probability (adaptive)\n    double random_prob = 0.08;\n    int stagnation_count = 0;\n    int last_best_tree_size = current_max;\n    \n    for (int step = 0; step < T; step++) {\n        if (current_max == N * N - 1) {\n            break;  // Already achieved full tree\n        }\n        \n        // Increase random probability if we're stuck\n        if (current_max == last_best_tree_size) {\n            stagnation_count++;\n            if (stagnation_count > 20) {\n                random_prob = min(0.3, random_prob * 1.2);\n                stagnation_count = 0;\n            }\n        } else {\n            stagnation_count = 0;\n            last_best_tree_size = current_max;\n            random_prob = max(0.05, random_prob * 0.95);\n        }\n        \n        // Occasionally make a random move to escape local optima\n        if (rng() % 1000 < random_prob * 1000) {\n            vector<int> valid_moves;\n            for (int d = 0; d < 4; d++) {\n                if (can_move(d)) valid_moves.push_back(d);\n            }\n            if (!valid_moves.empty()) {\n                int random_d = valid_moves[rng() % valid_moves.size()];\n                make_move(random_d);\n                moves += dir_char[random_d];\n                tie(current_max, current_extra, current_comp) = analyze_board();\n                continue;\n            }\n        }\n        \n        int best_d = -1;\n        int best_score = -100000000;\n        int best_tree_size = current_max;\n        \n        // Try all possible moves\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(d)) continue;\n            \n            auto [score, tree_size] = evaluate_move(d, step, current_max);\n            \n            // Add small random factor to break ties\n            score += rng() % 50;\n            \n            // Update best move\n            if (score > best_score || \n                (score == best_score && tree_size > best_tree_size)) {\n                best_score = score;\n                best_tree_size = tree_size;\n                best_d = d;\n            }\n        }\n        \n        if (best_d == -1) {\n            // No valid moves, try any move\n            for (int d = 0; d < 4; d++) {\n                if (can_move(d)) {\n                    best_d = d;\n                    break;\n                }\n            }\n            if (best_d == -1) break;\n        }\n        \n        // Execute best move\n        make_move(best_d);\n        moves += dir_char[best_d];\n        tie(current_max, current_extra, current_comp) = analyze_board();\n    }\n    \n    // If we haven't achieved a full tree, try some last-resort moves\n    if (current_max < N * N - 1 && moves.size() < T) {\n        // Try to connect components aggressively\n        for (int attempt = 0; attempt < 20 && moves.size() < T; attempt++) {\n            bool improved = false;\n            for (int d = 0; d < 4; d++) {\n                if (!can_move(d)) continue;\n                \n                // Simulate move\n                int nr = empty_r + dy[d];\n                int nc = empty_c + dx[d];\n                swap(board[empty_r][empty_c], board[nr][nc]);\n                int saved_er = empty_r, saved_ec = empty_c;\n                empty_r = nr;\n                empty_c = nc;\n                \n                auto [new_tree, new_extra, new_comp] = analyze_board();\n                \n                // Restore\n                empty_r = saved_er;\n                empty_c = saved_ec;\n                swap(board[empty_r][empty_c], board[nr][nc]);\n                \n                // If this move increases tree size or connects components\n                if (new_tree > current_max || new_comp < current_comp) {\n                    make_move(d);\n                    moves += dir_char[d];\n                    tie(current_max, current_extra, current_comp) = analyze_board();\n                    improved = true;\n                    break;\n                }\n            }\n            if (!improved) break;\n        }\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\nstruct Pt { ll x, y; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K = 100;\n    cin >> N >> K;\n    int a[11] = {};\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    vector<Pt> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n\n    auto calc = [&](const vector<array<ll,4>>& L) {\n        int cnt[11] = {};\n        for (int i = 0; i < N; i++) {\n            int s = 0;\n            for (auto& l : L) {\n                ll d = (l[2]-l[0])*(pts[i].y-l[1]) - (l[3]-l[1])*(pts[i].x-l[0]);\n                if (d < 0) s |= 1; else if (d > 0) s |= 2;\n            }\n            if (s) { int b = __builtin_popcount(s); if (b >= 1 && b <= 10) cnt[b]++; }\n        }\n        int sc = 0, tot = 0;\n        for (int d = 1; d <= 10; d++) { sc += min(a[d], cnt[d]); tot += a[d]; }\n        return tot ? (int)round(1e6 * sc / (double)tot) : 0;\n    };\n\n    vector<array<ll,4>> best;\n    int bs = -1;\n\n    // Grid approach with multiple ratios\n    for (int vh : {50, 49, 45, 40, 35, 30, 25, 20, 55, 60, 65, 70, 75, 80}) {\n        int vv = K - vh;\n        if (vv < 1 || vh < 1) continue;\n\n        vector<int> sx(N), sy(N);\n        iota(sx.begin(), sx.end(), 0);\n        iota(sy.begin(), sy.end(), 0);\n        sort(sx.begin(), sx.end(), [&](int i, int j) {\n            return pts[i].x < pts[j].x || (pts[i].x == pts[j].x && pts[i].y < pts[j].y);\n        });\n        sort(sy.begin(), sy.end(), [&](int i, int j) {\n            return pts[i].y < pts[j].y || (pts[i].y == pts[j].y && pts[i].x < pts[j].x);\n        });\n\n        vector<array<ll,4>> sol;\n        for (int i = 1; i <= vh; i++) {\n            int idx = (ll)i * N / (vh + 1);\n            idx = min(idx, N - 2);\n            idx = max(idx, 0);\n            ll mx = (pts[sx[idx]].x + pts[sx[idx+1]].x) / 2;\n            sol.push_back({mx, -20000, mx, 20000});\n        }\n        for (int i = 1; i <= vv; i++) {\n            int idx = (ll)i * N / (vv + 1);\n            idx = min(idx, N - 2);\n            idx = max(idx, 0);\n            ll my = (pts[sy[idx]].y + pts[sy[idx+1]].y) / 2;\n            sol.push_back({-20000, my, 20000, my});\n        }\n\n        int sc = calc(sol);\n        if (sc > bs) { bs = sc; best = sol; }\n    }\n\n    // Also try reversed sort orders\n    for (int vh : {50, 40, 30}) {\n        int vv = K - vh;\n        if (vv < 1 || vh < 1) continue;\n\n        vector<int> sx(N), sy(N);\n        iota(sx.begin(), sx.end(), 0);\n        iota(sy.begin(), sy.end(), 0);\n        sort(sx.begin(), sx.end(), [&](int i, int j) {\n            return pts[i].x > pts[j].x || (pts[i].x == pts[j].x && pts[i].y > pts[j].y);\n        });\n        sort(sy.begin(), sy.end(), [&](int i, int j) {\n            return pts[i].y > pts[j].y || (pts[i].y == pts[j].y && pts[i].x > pts[j].x);\n        });\n\n        vector<array<ll,4>> sol;\n        for (int i = 1; i <= vh; i++) {\n            int idx = (ll)i * N / (vh + 1);\n            idx = min(idx, N - 2);\n            idx = max(idx, 0);\n            ll mx = (pts[sx[idx]].x + pts[sx[idx+1]].x) / 2;\n            sol.push_back({mx, -20000, mx, 20000});\n        }\n        for (int i = 1; i <= vv; i++) {\n            int idx = (ll)i * N / (vv + 1);\n            idx = min(idx, N - 2);\n            idx = max(idx, 0);\n            ll my = (pts[sy[idx]].y + pts[sy[idx+1]].y) / 2;\n            sol.push_back({-20000, my, 20000, my});\n        }\n\n        int sc = calc(sol);\n        if (sc > bs) { bs = sc; best = sol; }\n    }\n\n    int k = min((int)best.size(), K);\n    cout << k << \"\\n\";\n    for (int i = 0; i < k; i++)\n        cout << best[i][0] << \" \" << best[i][1] << \" \" << best[i][2] << \" \" << best[i][3] << \"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Cand {\n    double score;\n    int nx, ny, p1x, p1y, p2x, p2y, p3x, p3y;\n    bool operator<(const Cand& o) const { return score > o.score; }\n};\n\nint main(){\n    int N, M;\n    scanf(\"%d%d\",&N,&M);\n    const int MX=62;\n    bool g[MX][MX]={};\n    vector<pair<int,int>> dots;\n    for(int i=0;i<M;i++){\n        int x,y; scanf(\"%d%d\",&x,&y);\n        g[x][y]=true; dots.push_back({x,y});\n    }\n    double c=(N-1)/2.0;\n    double w[MX][MX];\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)\n        w[x][y]=(x-c)*(x-c)+(y-c)*(y-c)+1;\n    bitset<60> hz[MX][MX],vt[MX][MX],ne[MX][MX],nw[MX][MX];\n    auto ckH=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y>=N)return false;\n        return !hz[x][y].test(0);};\n    auto ckV=[&](int x,int y)->bool{\n        if(x<0||x<N||y<0||y>=N-1)return false;\n        return !vt[x][y].test(0);};\n    auto ckNE=[&](int x,int y)->bool{\n        if(x<0||x>=N-1||y<0||y>=N)return false;\n        return !ne[x][y].test(0);};\n    auto ckNW=[&](int x,int y)->bool{\n        if(x<1||x<N||y<0||y>=N)return false;\n        return !nw[x][y].test(0);};\n    auto sH=[&](int x,int y){hz[x][y].set(0);};\n    auto sV=[&](int x,int y){vt[x][y].set(0);};\n    auto sNE=[&](int x,int y){ne[x][y].set(0);};\n    auto sNW=[&](int x,int y){nw[x][y].set(0);};\n    vector<array<int,8>> ops;\n    auto getTime=[&]()->double{\n        auto now=chrono::steady_clock::now();\n        return chrono::duration<double>(now.time_since_epoch()).count();};\n    double startTime=getTime();\n    while(getTime()-startTime<4.5){\n        vector<Cand> cands;\n        for(auto&[px,py]:dots){\n            for(int d=0;d<4;d++){\n                static const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};\n                int qx=px+dx[d]*2,qy=py+dy[d]*2;\n                if(qx<0||qx>=N||qy<0||qy>=N||g[qx][qy])continue;\n                int c1x=px+dx[d],c1y=py+dy[d],c2x=qx-dx[d],c2y=qy-dy[d];\n                if(c2x<0||c2x>=N||c2y<0||c2y>=N||!g[c2x][c2y])continue;\n                double sc=w[qx][qy];\n                if(d==0||d==2){\n                    if(!ckV(qx,min(qy,c1y))||!ckV(c2x,min(c2y,py))||\n                       !ckH(min(qx,c2x),qy)||!ckH(min(px,c1x),c1y))continue;\n                }else{\n                    if(!ckH(min(qx,c1x),qy)||!ckH(min(c2x,px),c2y)||\n                       !ckV(qx,min(qy,c2y))||!ckV(c1x,min(c1y,py)))continue;\n                }\n                cands.push_back({sc,qx,qy,px,py,c1x,c1y,c2x,c2y});\n            }\n            for(int d=0;d<2;d++){\n                int nx=px+1,ny=py+(d==0?1:-1);\n                if(nx<0||nx>=N||ny<0||ny>=N||g[nx][ny])continue;\n                int x1=px,y1=py,x2=nx,y2=ny;\n                if((x1+y1)%2!=(x2+y2)%2)continue;\n                int a1x=(x1+y1+x2-y2)/2,a1y=(x1+y1-x2+y2)/2;\n                int b1x=(x2+y2+x1-y1)/2,b1y=(x2+y2-x1+y1)/2;\n                int ok1=(a1x>=0&&a1x<N&&a1y>=0&&a1y<N&&b1x>=0&&b1x<N&&b1y>=0&&b1y<N);\n                if(ok1){\n                    bool f1=g[a1x][a1y],f2=g[b1x][b1y];\n                    if(f1&&!f2){\n                        double sc=w[b1x][b1y];\n                        if(ckNE(min(b1x,a1x),min(b1y,a1y))&&\n                           ckNW(min(a1x,x1),min(a1y,y1))&&\n                           ckNE(min(x1,b1x),min(y1,b1y))&&\n                           ckNW(min(b1x,x2),min(b1y,y2)))\n                            cands.push_back({sc,b1x,b1y,x1,y1,a1x,a1y,x2,y2});\n                    }else if(!f1&&f2){\n                        double sc=w[a1x][a1y];\n                        if(ckNE(min(a1x,b1x),min(a1y,b1y))&&\n                           ckNW(min(b1x,x1),min(b1y,y1))&&\n                           ckNE(min(x1,a1x),min(y1,a1y))&&\n                           ckNW(min(a1x,x2),min(a1y,y2)))\n                            cands.push_back({sc,a1x,a1y,x1,y1,b1x,b1y,x2,y2});\n                    }\n                }\n                int c1x=(x1+y1+x2+y2)/2,c1y=(x1-y1+x2+y2)/2;\n                int c2x=(x1+y1-x2-y2)/2,c2y=(x1-y1-x2-y2)/2;\n                int ok2=(c1x>=0&&c1x<N&&c1y>=0&&c1y<N&&c2x>=0&&c2x<N&&c2y>=0&&c2y<N);\n                if(ok2){\n                    bool f1=g[c1x][c1y],f2=g[c2x][c2y];\n                    if(f1&&!f2){\n                        double sc=w[c2x][c2y];\n                        if(ckNE(min(c2x,x2),min(c2y,y2))&&\n                           ckNW(min(x2,c1x),min(y2,c1y))&&\n                           ckNE(min(c1x,x1),min(c1y,y1))&&\n                           ckNW(min(x1,c2x),min(y1,c2y)))\n                            cands.push_back({sc,c2x,c2y,x1,y1,x2,y2,c1x,c1y});\n                    }else if(!f1&&f2){\n                        double sc=w[c1x][c1y];\n                        if(ckNE(min(c1x,x2),min(c1y,y2))&&\n                           ckNW(min(x2,c2x),min(y2,c2y))&&\n                           ckNE(min(c2x,x1),min(c2y,y1))&&\n                           ckNW(min(x1,c1x),min(y1,c1y)))\n                            cands.push_back({sc,c1x,c1y,x1,y1,x2,y2,c2x,c2y});\n                    }\n                }\n            }\n        }\n        sort(cands.begin(),cands.end());\n        bool found=false;\n        for(auto& cd:cands){\n            int nx=cd.nx,ny=cd.ny,p1x=cd.p1x,p1y=cd.p1y;\n            int p2x=cd.p2x,p2y=cd.p2y,p3x=cd.p3x,p3y=cd.p3y;\n            if(!ckH(min(nx,p1x),min(ny,p1y)))continue;\n            if(!ckV(min(p1x,p2x),min(p1y,p2y)))continue;\n            if(!ckH(min(p2x,p3x),min(p2y,p3y)))continue;\n            if(!ckV(min(p3x,nx),min(p3y,ny)))continue;\n            if(!ckNE(min(nx,p2x),min(ny,p2y)))continue;\n            if(!ckNW(min(p2x,p1x),min(p2y,p1y)))continue;\n            if(!ckNE(min(p1x,p3x),min(p1y,p3y)))continue;\n            if(!ckNW(min(p3x,nx),min(p3y,ny)))continue;\n            sH(min(nx,p1x),min(ny,p1y));sV(min(p1x,p2x),min(p1y,p2y));\n            sH(min(p2x,p3x),min(p2y,p3y));sV(min(p3x,nx),min(p3y,ny));\n            sNE(min(nx,p2x),min(ny,p2y));sNW(min(p2x,p1x),min(p2y,p1y));\n            sNE(min(p1x,p3x),min(p1y,p3y));sNW(min(p3x,nx),min(p3y,ny));\n            g[nx][ny]=true;\n            dots.push_back({nx,ny});\n            array<int,8> op={nx,ny,p1x,p1y,p2x,p2y,p3x,p3y};\n            ops.push_back(op);\n            found=true;break;\n        }\n        if(!found)break;\n    }\n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&o:ops)\n        printf(\"%d %d %d %d %d %d %d %d\\n\",o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7]);\n    double ws=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(g[x][y])ws+=w[x][y];\n    double S=0;\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)S+=w[x][y];\n    printf(\"Score: %lld\\n\",(long long)round(1e6*N*N/M*ws/S));\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cstring>\n#include <algorithm>\n\nusing namespace std;\n\nint grid[10][10];\nint flavors[100];\n\nvoid tilt(char dir, int g[10][10]) {\n    if (dir == 'F') {\n        for (int j = 0; j < 10; ++j) {\n            int write = 0;\n            for (int i = 0; i < 10; ++i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int i = write; i < 10; ++i) g[i][j] = 0;\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; ++j) {\n            int write = 9;\n            for (int i = 9; i >= 0; --i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    --write;\n                }\n            }\n            for (int i = write; i >= 0; --i) g[i][j] = 0;\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; ++i) {\n            int write = 0;\n            for (int j = 0; j < 10; ++j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int j = write; j < 10; ++j) g[i][j] = 0;\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; ++i) {\n            int write = 9;\n            for (int j = 9; j >= 0; --j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    --write;\n                }\n            }\n            for (int j = write; j >= 0; --j) g[i][j] = 0;\n        }\n    }\n}\n\nint compute_score(int g[10][10]) {\n    bool visited[10][10] = {};\n    int total = 0;\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            if (g[i][j] != 0 && !visited[i][j]) {\n                int flavor = g[i][j];\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int size = 0;\n                while (!q.empty()) {\n                    auto [r, c] = q.front(); q.pop();\n                    ++size;\n                    if (r > 0 && g[r-1][c] == flavor && !visited[r-1][c]) {\n                        visited[r-1][c] = true;\n                        q.push({r-1, c});\n                    }\n                    if (r < 9 && g[r+1][c] == flavor && !visited[r+1][c]) {\n                        visited[r+1][c] = true;\n                        q.push({r+1, c});\n                    }\n                    if (c > 0 && g[r][c-1] == flavor && !visited[r][c-1]) {\n                        visited[r][c-1] = true;\n                        q.push({r, c-1});\n                    }\n                    if (c < 9 && g[r][c+1] == flavor && !visited[r][c+1]) {\n                        visited[r][c+1] = true;\n                        q.push({r, c+1});\n                    }\n                }\n                total += size * size;\n            }\n        }\n    }\n    return total;\n}\n\npair<int, int> get_first_empty(int g[10][10]) {\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            if (g[i][j] == 0) {\n                return {i, j};\n            }\n        }\n    }\n    return {-1, -1}; // should not happen when there are empty cells\n}\n\nint main() {\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n\n    memset(grid, 0, sizeof(grid));\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        // Find the p-th empty cell\n        vector<pair<int, int>> empties;\n        for (int i = 0; i < 10; ++i) {\n            for (int j = 0; j < 10; ++j) {\n                if (grid[i][j] == 0) {\n                    empties.push_back({i, j});\n                }\n            }\n        }\n        auto [r, c] = empties[p - 1];\n        grid[r][c] = flavors[t];\n\n        // If this is the last candy, just use immediate greedy\n        if (t == 99) {\n            int best_score = -1;\n            char best_dir = 'F';\n            for (char dir : {'F', 'B', 'L', 'R'}) {\n                int temp[10][10];\n                memcpy(temp, grid, sizeof(temp));\n                tilt(dir, temp);\n                int score = compute_score(temp);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n            cout << best_dir << endl;\n            tilt(best_dir, grid);\n            continue;\n        }\n\n        // For other steps, use one-step lookahead\n        int best_future_score = -1;\n        char best_dir = 'F';\n\n        // Try each direction for the current step\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            int temp1[10][10];\n            memcpy(temp1, grid, sizeof(temp1));\n            tilt(dir, temp1);\n\n            // Place the next candy in the first empty cell\n            auto [nr, nc] = get_first_empty(temp1);\n            if (nr == -1) continue; // should not happen\n            temp1[nr][nc] = flavors[t + 1];\n\n            // Now try all directions for the next step and take the best score\n            int best_next_score = -1;\n            for (char next_dir : {'F', 'B', 'L', 'R'}) {\n                int temp2[10][10];\n                memcpy(temp2, temp1, sizeof(temp2));\n                tilt(next_dir, temp2);\n                int score = compute_score(temp2);\n                if (score > best_next_score) {\n                    best_next_score = score;\n                }\n            }\n\n            // Update best direction based on future score\n            if (best_next_score > best_future_score) {\n                best_future_score = best_next_score;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        tilt(best_dir, grid);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <limits>\n\nusing namespace std;\n\ndouble q_function(double x) {\n    return 0.5 * erfc(x / sqrt(2.0));\n}\n\nint main() {\n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    if (M == 1) {\n        cout << \"4\" << endl;\n        cout << \"000000\" << endl;\n        for (int q = 0; q < 100; ++q) {\n            string H;\n            cin >> H;\n            cout << \"0\" << endl;\n        }\n        return 0;\n    }\n    \n    double best_expected_score = -1.0;\n    int best_N = 4;\n    \n    for (int N = 4; N <= 100; ++N) {\n        int T = N * (N - 1) / 2;\n        if (T < M - 1) continue;\n        \n        double delta = (double)T * (1.0 - 2.0 * eps) / (M - 1);\n        double noise = sqrt(T * eps * (1.0 - eps));\n        \n        double p_error;\n        if (noise < 1e-12) {\n            p_error = (delta > 0) ? 0.0 : 1.0;\n        } else {\n            double x = delta / (2.0 * noise);\n            double Q = q_function(x);\n            p_error = (2.0 - 2.0 / M) * Q;\n            if (p_error > 1.0) p_error = 1.0;\n        }\n        \n        double survival_prob = 1.0 - 0.1 * p_error;\n        if (survival_prob < 0.0) survival_prob = 0.0;\n        double expected_score = 1e9 * pow(survival_prob, 100) / N;\n        \n        if (expected_score > best_expected_score) {\n            best_expected_score = expected_score;\n            best_N = N;\n        }\n    }\n    \n    int N = best_N;\n    int T = N * (N - 1) / 2;\n    \n    vector<int> edge_counts(M);\n    for (int s = 0; s < M; ++s) {\n        edge_counts[s] = (s * T) / (M - 1);\n    }\n    \n    cout << N << endl;\n    for (int s = 0; s < M; ++s) {\n        string graph(T, '0');\n        for (int i = 0; i < edge_counts[s]; ++i) {\n            graph[i] = '1';\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n    \n    vector<double> expected_observed(M);\n    for (int s = 0; s < M; ++s) {\n        expected_observed[s] = edge_counts[s] * (1.0 - 2.0 * eps) + T * eps;\n    }\n    \n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        \n        int observed_edges = 0;\n        for (char c : H) {\n            if (c == '1') observed_edges++;\n        }\n        \n        int best_s = 0;\n        double min_diff = numeric_limits<double>::max();\n        for (int s = 0; s < M; ++s) {\n            double diff = abs(observed_edges - expected_observed[s]);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        \n        cout << best_s << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <cassert>\n#include <tuple>\n#include <chrono>\n#include <functional>\n\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\n\nstruct Edge {\n    int u, v, w;\n    int idx;\n};\n\nstruct EdgeAdj {\n    int to, idx;\n    ll w;\n};\n\nvector<ll> dijkstra(int s, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\nvector<ll> dijkstra_ignore_set(int s, const vector<bool>& ignore_edge, \n                               const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (ignore_edge[e.idx]) continue;\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\n// Compute betweenness centrality for edges\nvector<double> compute_edge_betweenness(int N, const vector<Edge>& edges, \n                                        const vector<vector<ll>>& dist) {\n    int M = edges.size();\n    vector<double> edge_betw(M, 0.0);\n    \n    for (int s = 0; s < N; ++s) {\n        const auto& d_s = dist[s];\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 0);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) { \n            return d_s[a] < d_s[b]; \n        });\n        \n        vector<double> sigma(N, 0.0);\n        sigma[s] = 1.0;\n        vector<vector<int>> preds(N);\n        vector<vector<int>> pred_edges(N);\n        \n        for (int i = 0; i < M; ++i) {\n            int u = edges[i].u, v = edges[i].v;\n            ll w = edges[i].w;\n            if (d_s[u] + w == d_s[v]) {\n                preds[v].push_back(u);\n                pred_edges[v].push_back(i);\n            }\n            if (d_s[v] + w == d_s[u]) {\n                preds[u].push_back(v);\n                pred_edges[u].push_back(i);\n            }\n        }\n        \n        for (int v : nodes) {\n            if (v == s) continue;\n            for (int u : preds[v]) {\n                sigma[v] += sigma[u];\n            }\n        }\n        \n        vector<double> dep(N, 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int v = *it;\n            if (v == s) continue;\n            for (size_t i = 0; i < preds[v].size(); ++i) {\n                int u = preds[v][i];\n                int edge_idx = pred_edges[v][i];\n                double contrib = (sigma[u] / sigma[v]) * (1.0 + dep[v]);\n                dep[u] += contrib;\n                edge_betw[edge_idx] += contrib;\n            }\n        }\n    }\n    \n    return edge_betw;\n}\n\ndouble compute_day_frustration(int day, const vector<int>& day_assignment, \n                              const vector<Edge>& edges, const vector<vector<ll>>& orig_dist,\n                              const vector<vector<EdgeAdj>>& adj, int N, \n                              const vector<int>& sample_sources) {\n    vector<bool> ignore_edge(edges.size(), false);\n    int edge_count = 0;\n    for (int i = 0; i < edges.size(); ++i) {\n        if (day_assignment[i] == day) {\n            ignore_edge[i] = true;\n            edge_count++;\n        }\n    }\n    \n    if (edge_count == 0) return 0.0;\n    \n    double total_increase = 0.0;\n    int pair_count = 0;\n    \n    for (int s : sample_sources) {\n        vector<ll> new_dist = dijkstra_ignore_set(s, ignore_edge, adj);\n        for (int t = 0; t < N; ++t) {\n            if (s == t) continue;\n            ll orig_d = orig_dist[s][t];\n            ll new_d = new_dist[t];\n            if (new_d >= INF/2) new_d = 1000000000;\n            total_increase += (new_d - orig_d);\n            pair_count++;\n        }\n    }\n    \n    double avg_increase = total_increase / pair_count;\n    return avg_increase * (N * (N - 1)) / (sample_sources.size() * (N - 1));\n}\n\nvector<int> greedy_initial_assignment(const vector<Edge>& edges, const vector<double>& edge_importance,\n                                      int D, int K, int M) {\n    vector<int> assignment(M, 0);\n    vector<int> day_count(D, 0);\n    vector<double> day_importance(D, 0.0);\n    \n    // Sort edges by importance descending\n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return edge_importance[a] > edge_importance[b];\n    });\n    \n    for (int e_idx : edge_order) {\n        // Find day with minimum importance that has capacity\n        int best_day = -1;\n        double min_importance = 1e18;\n        for (int d = 0; d < D; ++d) {\n            if (day_count[d] < K && day_importance[d] < min_importance) {\n                min_importance = day_importance[d];\n                best_day = d;\n            }\n        }\n        assignment[e_idx] = best_day;\n        day_count[best_day]++;\n        day_importance[best_day] += edge_importance[e_idx];\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    \n    vector<Edge> edges(M);\n    vector<vector<EdgeAdj>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        adj[u].push_back({v, i, w});\n        adj[v].push_back({u, i, w});\n    }\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Precompute original distances\n    vector<vector<ll>> orig_dist(N);\n    for (int s = 0; s < N; ++s) {\n        orig_dist[s] = dijkstra(s, adj);\n    }\n    \n    // Compute edge importance (betweenness * delta)\n    vector<double> edge_importance(M, 0.0);\n    vector<double> edge_betw = compute_edge_betweenness(N, edges, orig_dist);\n    \n    // Compute delta for each edge (alternative path length - original length)\n    vector<ll> edge_delta(M, 0);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u, v = edges[i].v;\n        ll w = edges[i].w;\n        vector<bool> ignore(M, false);\n        ignore[i] = true;\n        vector<ll> dist_u = dijkstra_ignore_set(u, ignore, adj);\n        edge_delta[i] = dist_u[v] - w;\n        if (edge_delta[i] < 0) edge_delta[i] = 0;\n    }\n    \n    for (int i = 0; i < M; ++i) {\n        edge_importance[i] = edge_betw[i] * edge_delta[i];\n    }\n    \n    // Sample vertices for frustration estimation\n    int sample_size = min(30, N);\n    vector<int> sample_sources(sample_size);\n    iota(sample_sources.begin(), sample_sources.end(), 0);\n    if (N > sample_size) {\n        random_device rd;\n        mt19937 gen(rd());\n        shuffle(sample_sources.begin(), sample_sources.end(), gen);\n        sample_sources.resize(sample_size);\n    }\n    \n    // Get initial assignment using greedy algorithm\n    vector<int> assignment = greedy_initial_assignment(edges, edge_importance, D, K, M);\n    \n    // Compute initial frustration\n    vector<double> day_frustration(D, 0.0);\n    double total_frustration = 0.0;\n    for (int day = 0; day < D; ++day) {\n        day_frustration[day] = compute_day_frustration(day, assignment, edges, orig_dist, \n                                                      adj, N, sample_sources);\n        total_frustration += day_frustration[day];\n    }\n    \n    // Simulated annealing with edge moves and swaps\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> dis(0.0, 1.0);\n    uniform_int_distribution<int> rand_edge(0, M - 1);\n    uniform_int_distribution<int> rand_day(0, D - 1);\n    uniform_int_distribution<int> rand_move_type(0, 1); // 0: move, 1: swap\n    \n    double temp = 1000.0;\n    double cooling = 0.9998;\n    const int ITER = 250000;\n    \n    for (int iter = 0; iter < ITER; ++iter) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 5.5) break;\n        \n        if (rand_move_type(gen) == 0) {\n            // Move single edge\n            int e = rand_edge(gen);\n            int old_day = assignment[e];\n            int new_day = rand_day(gen);\n            while (new_day == old_day) new_day = rand_day(gen);\n            \n            // Check capacity\n            int cnt_new = count(assignment.begin(), assignment.end(), new_day);\n            if (cnt_new >= K) continue;\n            \n            assignment[e] = new_day;\n            \n            double new_frustration_old = compute_day_frustration(old_day, assignment, edges, \n                                                                orig_dist, adj, N, sample_sources);\n            double new_frustration_new = compute_day_frustration(new_day, assignment, edges, \n                                                                orig_dist, adj, N, sample_sources);\n            \n            double new_total = total_frustration - day_frustration[old_day] - day_frustration[new_day] \n                              + new_frustration_old + new_frustration_new;\n            \n            double delta = new_total - total_frustration;\n            \n            if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n                total_frustration = new_total;\n                day_frustration[old_day] = new_frustration_old;\n                day_frustration[new_day] = new_frustration_new;\n            } else {\n                assignment[e] = old_day;\n            }\n        } else {\n            // Swap two edges between days\n            int e1 = rand_edge(gen);\n            int e2 = rand_edge(gen);\n            if (e1 == e2) continue;\n            \n            int day1 = assignment[e1];\n            int day2 = assignment[e2];\n            if (day1 == day2) continue;\n            \n            // Perform swap\n            assignment[e1] = day2;\n            assignment[e2] = day1;\n            \n            double new_frustration_day1 = compute_day_frustration(day1, assignment, edges, \n                                                                 orig_dist, adj, N, sample_sources);\n            double new_frustration_day2 = compute_day_frustration(day2, assignment, edges, \n                                                                 orig_dist, adj, N, sample_sources);\n            \n            double new_total = total_frustration - day_frustration[day1] - day_frustration[day2] \n                              + new_frustration_day1 + new_frustration_day2;\n            \n            double delta = new_total - total_frustration;\n            \n            if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n                total_frustration = new_total;\n                day_frustration[day1] = new_frustration_day1;\n                day_frustration[day2] = new_frustration_day2;\n            } else {\n                // Revert swap\n                assignment[e1] = day1;\n                assignment[e2] = day2;\n            }\n        }\n        \n        temp *= cooling;\n    }\n    \n    // Output (convert to 1-indexed days)\n    for (int i = 0; i < M; ++i) {\n        if (i > 0) cout << ' ';\n        cout << (assignment[i] + 1);\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    // Read silhouettes, remove spaces if any\n    vector<string> f[2], r[2];\n    for (int i = 0; i < 2; ++i) {\n        f[i].resize(D);\n        for (int j = 0; j < D; ++j) {\n            cin >> f[i][j];\n            string clean;\n            for (char c : f[i][j]) if (c != ' ') clean.push_back(c);\n            f[i][j] = clean;\n        }\n        r[i].resize(D);\n        for (int j = 0; j < D; ++j) {\n            cin >> r[i][j];\n            string clean;\n            for (char c : r[i][j]) if (c != ' ') clean.push_back(c);\n            r[i][j] = clean;\n        }\n    }\n\n    // Sets of occupied cells for each object\n    vector<array<int, 3>> cells[2];\n    // Common cells (intersection)\n    vector<array<int, 3>> common;\n\n    // Generate all allowed cells for each object and find intersection\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 in0 = (f[0][z][x] == '1' && r[0][z][y] == '1');\n                bool in1 = (f[1][z][x] == '1' && r[1][z][y] == '1');\n                if (in0 && in1) {\n                    common.push_back({x, y, z});\n                } else if (in0) {\n                    cells[0].push_back({x, y, z});\n                } else if (in1) {\n                    cells[1].push_back({x, y, z});\n                }\n            }\n        }\n    }\n\n    // Assign block IDs\n    int n = common.size() + cells[0].size() + cells[1].size();\n    vector<vector<vector<int>>> b[2];\n    for (int i = 0; i < 2; ++i) {\n        b[i].assign(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    }\n\n    int id = 1;\n    // Place common cells (shared blocks)\n    for (auto [x, y, z] : common) {\n        b[0][x][y][z] = id;\n        b[1][x][y][z] = id;\n        ++id;\n    }\n    // Place exclusive cells for object 0\n    for (auto [x, y, z] : cells[0]) {\n        b[0][x][y][z] = id++;\n    }\n    // Place exclusive cells for object 1\n    for (auto [x, y, z] : cells[1]) {\n        b[1][x][y][z] = id++;\n    }\n\n    // Output\n    cout << n << '\\n';\n    for (int obj = 0; obj < 2; ++obj) {\n        bool first = true;\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 (first) first = false;\n                    else cout << ' ';\n                    cout << b[obj][x][y][z];\n                }\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\nconst ll RADIUS_SQ = 25000000LL; // 5000^2\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    cin >> N >> M >> K;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n\n    // graph and edge index mapping\n    vector<vector<ll>> distV(N, vector<ll>(N, INF));\n    vector<vector<int>> nextV(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        distV[i][i] = 0;\n        nextV[i][i] = i;\n    }\n    vector<tuple<int, int, int>> edges(M); // u, v, w\n    vector<vector<int>> edgeIdx(N, vector<int>(N, -1));\n    for (int j = 0; j < M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u, --v;\n        edges[j] = {u, v, w};\n        distV[u][v] = distV[v][u] = w;\n        nextV[u][v] = v;\n        nextV[v][u] = u;\n        edgeIdx[u][v] = edgeIdx[v][u] = j;\n    }\n\n    // residents\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n\n    // precompute distances between vertices and residents\n    vector<vector<ll>> sqDist(N, vector<ll>(K));\n    vector<vector<double>> eucDist(N, vector<double>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = x[i] - a[k];\n            ll dy = y[i] - b[k];\n            sqDist[i][k] = dx*dx + dy*dy;\n            eucDist[i][k] = sqrt((double)sqDist[i][k]);\n        }\n    }\n\n    // Floyd-Warshall for shortest paths between vertices\n    for (int kk = 0; kk < N; ++kk) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][kk] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[kk][j] == INF) continue;\n                if (distV[i][j] > distV[i][kk] + distV[kk][j]) {\n                    distV[i][j] = distV[i][kk] + distV[kk][j];\n                    nextV[i][j] = nextV[i][kk];\n                }\n            }\n        }\n    }\n\n    // Initialize with all vertices connected to vertex 0\n    vector<int> S(N);\n    iota(S.begin(), S.end(), 0);\n    \n    // Greedy assignment to minimize sum of squares\n    vector<double> maxDist(N, 0.0);\n    vector<int> assign(K);\n    \n    // Initial assignment: each resident to nearest vertex\n    for (int k = 0; k < K; ++k) {\n        double minDist = 1e18;\n        int bestV = -1;\n        for (int v : S) {\n            double d = eucDist[v][k];\n            if (d < minDist) {\n                minDist = d;\n                bestV = v;\n            }\n        }\n        assign[k] = bestV;\n        if (minDist > maxDist[bestV]) {\n            maxDist[bestV] = minDist;\n        }\n    }\n\n    // Local search: try to remove vertices\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < (int)S.size(); ++i) {\n            int v = S[i];\n            if (v == 0) continue; // Keep vertex 0\n\n            // Try removing vertex v\n            vector<int> newS = S;\n            newS.erase(newS.begin() + i);\n            \n            // Check if all residents can be reassigned within 5000\n            bool canRemove = true;\n            vector<int> newAssign = assign;\n            vector<double> newMaxDist(N, 0.0);\n            \n            for (int k = 0; k < K; ++k) {\n                if (assign[k] == v) {\n                    // Find nearest vertex in newS within 5000\n                    double bestDist = 1e18;\n                    int bestVertex = -1;\n                    for (int u : newS) {\n                        double d = eucDist[u][k];\n                        if (d <= 5000.0 && d < bestDist) {\n                            bestDist = d;\n                            bestVertex = u;\n                        }\n                    }\n                    if (bestVertex == -1) {\n                        canRemove = false;\n                        break;\n                    }\n                    newAssign[k] = bestVertex;\n                    if (bestDist > newMaxDist[bestVertex]) {\n                        newMaxDist[bestVertex] = bestDist;\n                    }\n                } else {\n                    int u = assign[k];\n                    if (eucDist[u][k] > newMaxDist[u]) {\n                        newMaxDist[u] = eucDist[u][k];\n                    }\n                }\n            }\n            \n            if (!canRemove) continue;\n            \n            // Compute new costs\n            ll newSumSq = 0;\n            for (int u : newS) {\n                if (newMaxDist[u] > 0) {\n                    int p = (int)ceil(newMaxDist[u] - 1e-9);\n                    newSumSq += (ll)p * p;\n                }\n            }\n            \n            // Compute MST cost for newS\n            vector<tuple<ll, int, int>> mstEdges;\n            for (size_t a = 0; a < newS.size(); ++a) {\n                for (size_t b = a+1; b < newS.size(); ++b) {\n                    int u = newS[a], v2 = newS[b];\n                    mstEdges.emplace_back(distV[u][v2], u, v2);\n                }\n            }\n            sort(mstEdges.begin(), mstEdges.end());\n            vector<int> parent(N);\n            iota(parent.begin(), parent.end(), 0);\n            function<int(int)> find = [&](int x) {\n                return parent[x] == x ? x : parent[x] = find(parent[x]);\n            };\n            auto unite = [&](int x, int y) {\n                parent[find(x)] = find(y);\n            };\n            ll newMSTCost = 0;\n            for (auto [w, u, v2] : mstEdges) {\n                if (find(u) != find(v2)) {\n                    unite(u, v2);\n                    newMSTCost += w;\n                }\n            }\n            \n            // Current costs\n            ll currentSumSq = 0;\n            for (int u : S) {\n                if (maxDist[u] > 0) {\n                    int p = (int)ceil(maxDist[u] - 1e-9);\n                    currentSumSq += (ll)p * p;\n                }\n            }\n            \n            // Current MST cost\n            vector<tuple<ll, int, int>> currentMSTEdges;\n            for (size_t a = 0; a < S.size(); ++a) {\n                for (size_t b = a+1; b < S.size(); ++b) {\n                    int u = S[a], v2 = S[b];\n                    currentMSTEdges.emplace_back(distV[u][v2], u, v2);\n                }\n            }\n            sort(currentMSTEdges.begin(), currentMSTEdges.end());\n            vector<int> currentParent(N);\n            iota(currentParent.begin(), currentParent.end(), 0);\n            function<int(int)> currentFind = [&](int x) {\n                return currentParent[x] == x ? x : currentParent[x] = currentFind(currentParent[x]);\n            };\n            auto currentUnite = [&](int x, int y) {\n                currentParent[currentFind(x)] = currentFind(y);\n            };\n            ll currentMSTCost = 0;\n            for (auto [w, u, v2] : currentMSTEdges) {\n                if (currentFind(u) != currentFind(v2)) {\n                    currentUnite(u, v2);\n                    currentMSTCost += w;\n                }\n            }\n            \n            if (newSumSq + newMSTCost < currentSumSq + currentMSTCost) {\n                // Accept removal\n                S = newS;\n                assign = newAssign;\n                maxDist = newMaxDist;\n                improved = true;\n                break;\n            }\n        }\n    }\n\n    // Compute final P values\n    vector<int> P(N, 0);\n    for (int u : S) {\n        if (maxDist[u] > 0) {\n            int p = (int)ceil(maxDist[u] - 1e-9);\n            P[u] = p;\n        }\n    }\n\n    // Build final MST\n    vector<tuple<ll, int, int>> finalMSTEdges;\n    for (size_t i = 0; i < S.size(); ++i) {\n        for (size_t j = i+1; j < S.size(); ++j) {\n            int u = S[i], v = S[j];\n            finalMSTEdges.emplace_back(distV[u][v], u, v);\n        }\n    }\n    sort(finalMSTEdges.begin(), finalMSTEdges.end());\n    vector<int> finalParent(N);\n    iota(finalParent.begin(), finalParent.end(), 0);\n    function<int(int)> finalFind = [&](int x) {\n        return finalParent[x] == x ? x : finalParent[x] = finalFind(finalParent[x]);\n    };\n    auto finalUnite = [&](int x, int y) {\n        finalParent[finalFind(x)] = finalFind(y);\n    };\n    vector<pair<int, int>> finalMSTPairs;\n    for (auto [w, u, v] : finalMSTEdges) {\n        if (finalFind(u) != finalFind(v)) {\n            finalUnite(u, v);\n            finalMSTPairs.emplace_back(u, v);\n        }\n    }\n\n    // Turn on edges along shortest paths\n    vector<bool> edgeOn(M, false);\n    for (auto [u, v] : finalMSTPairs) {\n        int cur = u;\n        while (cur != v) {\n            int nxt = nextV[cur][v];\n            int idx = edgeIdx[cur][nxt];\n            if (idx != -1) {\n                edgeOn[idx] = true;\n            }\n            cur = nxt;\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N-1 ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; ++j) {\n        cout << edgeOn[j] << (j == M-1 ? '\\n' : ' ');\n    }\n\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30;\n    int grid[N][N];\n    map<int,pair<int,int>> pos;\n    vector<array<int,4>> ops;\n    \n    auto do_swap = [&](int x1,int y1,int x2,int y2){\n        int v1=grid[x1][y1], v2=grid[x2][y2];\n        grid[x1][y1]=v2; grid[x2][y2]=v1;\n        pos[v1]={x2,y2}; pos[v2]={x1,y1};\n        ops.push_back({x1,y1,x2,y2});\n    };\n    \n    auto find_path = [&](int sx,int sy,int ex,int ey){\n        queue<pair<int,int>> q;\n        vector<int> par(N*N,-1);\n        auto sk=[&](int a,int b){return a*N+b;};\n        q.push({sx,sy});\n        int ss=sk(sx,sy);\n        par[ss]=ss;\n        while(!q.empty()){\n            auto[x,y]=q.front();q.pop();\n            int s=sk(x,y);\n            if(x==ex&&y==ey){\n                vector<pair<int,int>> p;\n                int c=s;\n                while(c!=par[c]){\n                    p.push_back({c/N,c%N});\n                    c=par[c];\n                }\n                p.push_back({c/N,c%N});\n                reverse(p.begin(),p.end());\n                return p;\n            }\n            for(auto[dx,dy]:{pair{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}}){\n                int nx=x+dx,ny=y+dy;\n                if(nx>=0&&nx<N&&ny>=0&&ny<=nx){\n                    int ns=sk(nx,ny);\n                    if(par[ns]==-1){par[ns]=s;q.push({nx,ny});}\n                }\n            }\n        }\n        return vector<pair<int,int>>{{sx,sy}};\n    };\n    \n    auto exec_path = [&](int val,int tx,int ty){\n        auto[sx,sy]=pos[val];\n        if(sx==tx&&sy==ty)return;\n        auto path=find_path(sx,sy,tx,ty);\n        for(int i=0;i+1<(int)path.size();i++)\n            do_swap(path[i].first,path[i].second,path[i+1].first,path[i+1].second);\n    };\n    \n    for(int i=0;i<N;i++)\n        for(int j=0;j<=i;j++){\n            cin>>grid[i][j];\n            pos[grid[i][j]]={i,j};\n        }\n    \n    // Floyd's heapify with full sifting and backtrack\n    for(int x=N-2;x>=0;x--){\n        for(int y=x;y>=0;y--){\n            int cx=x, cy=y;\n            while(cx<N-1){\n                int v=grid[cx][cy];\n                int lx=cx+1, ly=cy, rx=cx+1, ry=cy+1;\n                int mx=cx, my=cy, mv=v;\n                if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mx=lx;my=ly;mv=grid[lx][ly];}\n                if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mx=rx;my=ry;mv=grid[rx][ry];}\n                if(mx==cx&&my==cy) break;\n                exec_path(v,mx,my);\n                cx=mx; cy=my;\n            }\n            // Backtrack: if a smaller value bubbled up, re-sift from parent\n            if(cx>x){\n                int px=cx-1, py=(cy>0&&cy>cx-1)?cy-1:cy;\n                if(px>=0&&py>=0&&py<=px&&grid[px][py]>grid[cx][cy]){\n                    int bx=px, by=py;\n                    while(bx<N-1){\n                        int v=grid[bx][by];\n                        int lx=bx+1, ly=by, rx=bx+1, ry=by+1;\n                        int mx=bx, my=by, mv=v;\n                        if(lx<N&&ly<=lx&&grid[lx][ly]<mv){mx=lx;my=ly;mv=grid[lx][ly];}\n                        if(rx<N&&ry<=rx&&grid[rx][ry]<mv){mx=rx;my=ry;mv=grid[rx][ry];}\n                        if(mx==bx&&my==by) break;\n                        exec_path(v,mx,my);\n                        bx=mx; by=my;\n                    }\n                }\n            }\n        }\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto& o:ops) cout<<o[0]<<\" \"<<o[1]<<\" \"<<o[2]<<\" \"<<o[3]<<\"\\n\";\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n#include <cmath>\n#include <set>\n#include <climits>\n#include <functional>\nusing namespace std;\n\nconst int entrance_i = 0, entrance_j = 4;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nbool obstacle[9][9] = {false};\nbool occupied[9][9] = {false};\nint placed_number[9][9];\nvector<pair<int, int>> container_squares;\nint M;\nint dist[9][9];\nint min_d = INT_MAX, max_d = 0;\n\ninline bool in_bounds(int i, int j) {\n    return i >= 0 && i < 9 && j >= 0 && j < 9;\n}\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    dist[entrance_i][entrance_j] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || dist[nx][ny] != -1) continue;\n            dist[nx][ny] = dist[x][y] + 1;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    for (auto [i, j] : container_squares) {\n        if (dist[i][j] != -1) {\n            min_d = min(min_d, dist[i][j]);\n            max_d = max(max_d, dist[i][j]);\n        }\n    }\n}\n\nvector<pair<int, int>> get_reachable() {\n    bool vis[9][9] = {false};\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    vis[entrance_i][entrance_j] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n            if (nx == entrance_i && ny == entrance_j) continue;\n            if (occupied[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    vector<pair<int, int>> reachable;\n    for (auto [i, j] : container_squares) {\n        if (vis[i][j] && !occupied[i][j]) {\n            reachable.emplace_back(i, j);\n        }\n    }\n    return reachable;\n}\n\nbool would_disconnect(int i, int j, int remaining) {\n    occupied[i][j] = true;\n    \n    bool vis[9][9] = {false};\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    vis[entrance_i][entrance_j] = true;\n    int count = 1;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n            if (occupied[nx][ny]) continue;\n            vis[nx][ny] = true;\n            count++;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    occupied[i][j] = false;\n    return count != remaining;\n}\n\n// Advanced strategic value considering number weights\ndouble advanced_strategic_value(int i, int j, int remaining, int current_t) {\n    occupied[i][j] = true;\n    \n    double penalty = 0;\n    int blocked_count = 0;\n    \n    for (auto [x, y] : container_squares) {\n        if (occupied[x][y]) continue;\n        \n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        bool reachable = false;\n        \n        while (!q.empty() && !reachable) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny] || occupied[nx][ny]) continue;\n                if (nx == x && ny == y) {\n                    reachable = true;\n                    break;\n                }\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n        \n        if (!reachable) {\n            blocked_count++;\n            // If this square has a number placed, weight by how small it is\n            if (placed_number[x][y] != -1) {\n                // Smaller numbers should have higher penalty (we don't want to block them)\n                double weight = 1.0 - (double)placed_number[x][y] / (M - 1);\n                penalty += 10.0 * weight;\n            } else {\n                // Unknown number - assume it could be small\n                penalty += 5.0;\n            }\n        }\n    }\n    \n    occupied[i][j] = false;\n    \n    // Normalize by remaining squares\n    return penalty / (remaining + 1e-9);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    memset(placed_number, -1, sizeof(placed_number));\n    \n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n    \n    for (int i = 0; i < 9; ++i) {\n        for (int j = 0; j < 9; ++j) {\n            if (i == entrance_i && j == entrance_j) continue;\n            if (obstacle[i][j]) continue;\n            container_squares.emplace_back(i, j);\n        }\n    }\n    M = container_squares.size();\n    \n    compute_distances();\n    \n    int placed = 0;\n    \n    for (int step = 0; step < M; ++step) {\n        int t;\n        cin >> t;\n        \n        auto reachable = get_reachable();\n        int remaining = M - placed;\n        \n        vector<pair<int, int>> safe_squares;\n        for (auto [i, j] : reachable) {\n            if (!would_disconnect(i, j, remaining)) {\n                safe_squares.emplace_back(i, j);\n            }\n        }\n        \n        if (safe_squares.empty()) {\n            safe_squares = reachable;\n        }\n        \n        pair<int, int> best_pos = safe_squares[0];\n        double best_score = -1e18;\n        \n        // Dynamic weight adjustment based on how full the grid is\n        double fill_ratio = (double)placed / M;\n        \n        for (auto [i, j] : safe_squares) {\n            int d = dist[i][j];\n            double normalized_d = (max_d == min_d) ? 0.5 : (double)(d - min_d) / (max_d - min_d);\n            double t_percentile = (double)t / (M - 1);\n            \n            // Distance score using exponential decay (more forgiving than quadratic)\n            double distance_error = abs(normalized_d - t_percentile);\n            double distance_score = 100.0 * exp(-3.0 * distance_error);\n            \n            // Advanced strategic value\n            double strategic_penalty = advanced_strategic_value(i, j, remaining, t);\n            double strategic_score = 80.0 * exp(-strategic_penalty);\n            \n            // Neighbor connectivity with decay as grid fills\n            int neighbor_count = 0;\n            int empty_neighbors = 0;\n            for (int dd = 0; dd < 4; ++dd) {\n                int ni = i + dx[dd], nj = j + dy[dd];\n                if (in_bounds(ni, nj) && !obstacle[ni][nj]) {\n                    neighbor_count++;\n                    if (!occupied[ni][nj]) {\n                        empty_neighbors++;\n                    }\n                }\n            }\n            \n            // Neighbor score decays as grid fills (early placements care more about neighbors)\n            double neighbor_decay = exp(-2.0 * fill_ratio);\n            double neighbor_score = (10.0 * empty_neighbors + 3.0 * neighbor_count) * neighbor_decay;\n            \n            // Path diversity bonus (multiple paths to entrance)\n            int path_count = 0;\n            for (int dd = 0; dd < 4; ++dd) {\n                int ni = i + dx[dd], nj = j + dy[dd];\n                if (in_bounds(ni, nj) && !obstacle[ni][nj] && dist[ni][nj] != -1 && dist[ni][nj] < dist[i][j]) {\n                    path_count++;\n                }\n            }\n            double diversity_score = 15.0 * min(path_count, 2) / 2.0;\n            \n            // Special handling for very small and very large numbers\n            double special_bonus = 0;\n            if (t_percentile < 0.1) {\n                // Very small numbers: strongly prefer very close\n                special_bonus = 50.0 * (1.0 - normalized_d);\n            } else if (t_percentile > 0.9) {\n                // Very large numbers: strongly prefer far\n                special_bonus = 50.0 * normalized_d;\n            }\n            \n            // Combined score\n            double score = distance_score + strategic_score + neighbor_score + \n                          diversity_score + special_bonus;\n            \n            // Deterministic tie-breaker favoring certain patterns\n            score += (i * 9 + j) * 1e-6;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_pos = {i, j};\n            }\n        }\n        \n        auto [pi, pj] = best_pos;\n        cout << pi << \" \" << pj << endl;\n        occupied[pi][pj] = true;\n        placed_number[pi][pj] = t;\n        placed++;\n    }\n    \n    // Optimal retrieval: always take smallest reachable number\n    vector<pair<int, int>> retrieval_order;\n    \n    bool sim_occupied[9][9];\n    int sim_numbers[9][9];\n    memcpy(sim_occupied, occupied, sizeof(sim_occupied));\n    memcpy(sim_numbers, placed_number, sizeof(sim_numbers));\n    \n    while (retrieval_order.size() < M) {\n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        \n        vector<pair<int, int>> reachable;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n                if (sim_occupied[nx][ny]) {\n                    reachable.emplace_back(nx, ny);\n                    vis[nx][ny] = true;\n                } else {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n        \n        if (reachable.empty()) break;\n        \n        auto best_square = reachable[0];\n        for (auto [i, j] : reachable) {\n            if (sim_numbers[i][j] < sim_numbers[best_square.first][best_square.second]) {\n                best_square = {i, j};\n            }\n        }\n        \n        retrieval_order.push_back(best_square);\n        sim_occupied[best_square.first][best_square.second] = false;\n    }\n    \n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> grid(n, vector<int>(n));\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    // Output the original grid unchanged\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 << '\\n';\n    }\n    \n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint used = 0;\nint N, D, Q;\n\nstring do_query(int l, int r) {\n    cout << \"1 1 \" << l << \" \" << r << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nstring compare_groups(const vector<int>& a, const vector<int>& b) {\n    cout << a.size() << \" \" << b.size();\n    for (int x : a) cout << \" \" << x;\n    for (int x : b) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    // Initialize random generator for shuffling\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    // Create initial order and shuffle\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    \n    // Estimate required comparisons\n    int sort_comparisons = 0;\n    for (int i = 2; i <= N; i++) {\n        sort_comparisons += static_cast<int>(ceil(log2(i) / log2(3.0)));\n    }\n    \n    // For heap-based greedy: O(N log D) comparisons\n    int greedy_comparisons = static_cast<int>(N * ceil(log2(D)));\n    \n    // Strategy selection\n    bool use_greedy = false;\n    int sort_limit = Q;\n    \n    if (Q >= sort_comparisons + greedy_comparisons) {\n        // Enough for full sort and heap-based greedy\n        use_greedy = true;\n        sort_limit = sort_comparisons;\n    } else if (Q >= 2 * N && Q >= greedy_comparisons) {\n        // Enough for partial sort and greedy\n        use_greedy = true;\n        sort_limit = Q - greedy_comparisons;\n    } else {\n        // Not enough for greedy, use snake order\n        use_greedy = false;\n        sort_limit = Q;\n    }\n    \n    vector<int> sorted;\n    sorted.reserve(N);\n    \n    // Binary insertion sort with limited comparisons\n    for (int x : order) {\n        if (used >= sort_limit) {\n            sorted.push_back(x);\n            continue;\n        }\n        \n        int low = 0, high = sorted.size();\n        while (low < high && used < sort_limit) {\n            int mid = (low + high) / 2;\n            string res = do_query(x, sorted[mid]);\n            \n            bool mid_is_heavier;\n            if (res == \">\") {\n                mid_is_heavier = true;\n            } else if (res == \"<\") {\n                mid_is_heavier = false;\n            } else {\n                // Tie-break by index\n                mid_is_heavier = (sorted[mid] < x);\n            }\n            \n            if (mid_is_heavier) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        sorted.insert(sorted.begin() + low, x);\n    }\n    \n    vector<int> group(N);\n    \n    if (use_greedy) {\n        // Heap-based greedy assignment\n        vector<vector<int>> groups(D);\n        \n        // Assign first D items to different groups\n        for (int i = 0; i < D && i < (int)sorted.size(); i++) {\n            groups[i].push_back(sorted[i]);\n        }\n        \n        // Create a list of group indices sorted by current sum\n        vector<int> sorted_groups;\n        \n        // Insert groups into sorted list using binary search with comparisons\n        for (int g = 0; g < D; g++) {\n            if (groups[g].empty()) continue;\n            \n            int low = 0, high = sorted_groups.size();\n            while (low < high && used < Q) {\n                int mid = (low + high) / 2;\n                string res = compare_groups(groups[g], groups[sorted_groups[mid]]);\n                \n                bool g_is_lighter;\n                if (res == \"<\") {\n                    g_is_lighter = true;\n                } else if (res == \">\") {\n                    g_is_lighter = false;\n                } else {\n                    // Tie-break by group index\n                    g_is_lighter = (g < sorted_groups[mid]);\n                }\n                \n                if (g_is_lighter) {\n                    high = mid;\n                } else {\n                    low = mid + 1;\n                }\n            }\n            sorted_groups.insert(sorted_groups.begin() + low, g);\n        }\n        \n        // Assign remaining items to smallest group\n        for (int i = D; i < (int)sorted.size() && used < Q; i++) {\n            int item = sorted[i];\n            \n            // Get the smallest group (first in sorted_groups)\n            int smallest_group = sorted_groups[0];\n            groups[smallest_group].push_back(item);\n            \n            // Remove the smallest group from sorted list\n            sorted_groups.erase(sorted_groups.begin());\n            \n            // Re-insert the updated group into sorted list\n            int low = 0, high = sorted_groups.size();\n            while (low < high && used < Q) {\n                int mid = (low + high) / 2;\n                string res = compare_groups(groups[smallest_group], groups[sorted_groups[mid]]);\n                \n                bool is_lighter;\n                if (res == \"<\") {\n                    is_lighter = true;\n                } else if (res == \">\") {\n                    is_lighter = false;\n                } else {\n                    is_lighter = (smallest_group < sorted_groups[mid]);\n                }\n                \n                if (is_lighter) {\n                    high = mid;\n                } else {\n                    low = mid + 1;\n                }\n            }\n            sorted_groups.insert(sorted_groups.begin() + low, smallest_group);\n        }\n        \n        // Convert groups to assignment array\n        for (int g = 0; g < D; g++) {\n            for (int item : groups[g]) {\n                group[item] = g;\n            }\n        }\n    } else {\n        // Snake order assignment\n        int cur_group = 0;\n        int step = 1;\n        for (int idx : sorted) {\n            group[idx] = cur_group;\n            cur_group += step;\n            if (cur_group == D) {\n                cur_group = D - 1;\n                step = -1;\n            } else if (cur_group == -1) {\n                cur_group = 0;\n                step = 1;\n            }\n        }\n    }\n    \n    // Use any remaining queries as dummy queries\n    while (used < Q) {\n        do_query(0, 1);\n    }\n    \n    // Output the division\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << group[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        int cnt = n / m;\n        stacks[i].resize(cnt);\n        for (int j = 0; j < cnt; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    vector<pair<int, int>> ops;\n    int next_box = 1;\n\n    // Helper to find the position of a box\n    auto find_box = [&](int val) -> pair<int, int> {\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == val) {\n                    return {i, j};\n                }\n            }\n        }\n        return {-1, -1};\n    };\n\n    // Helper to get the top value of a stack (or INT_MAX if empty)\n    auto get_top = [&](int stack_idx) -> int {\n        if (stacks[stack_idx].empty()) return INT_MAX;\n        return stacks[stack_idx].back();\n    };\n\n    // Helper to find the best destination for a block\n    auto find_best_destination = [&](int source_stack, const vector<int>& block) -> int {\n        int best_dest = -1;\n        int best_score = INT_MIN;\n        \n        for (int d = 0; d < m; ++d) {\n            if (d == source_stack) continue;\n            \n            int score = 0;\n            \n            // Empty stack is excellent\n            if (stacks[d].empty()) {\n                score += 1000;\n            } else {\n                // Check if adding this block would maintain decreasing order\n                int dest_top = get_top(d);\n                int block_bottom = block[0];\n                \n                // If destination top > block bottom, order is maintained\n                if (dest_top > block_bottom) {\n                    score += 500;\n                }\n                \n                // Check if the block itself is decreasing\n                bool block_decreasing = true;\n                for (size_t i = 1; i < block.size(); ++i) {\n                    if (block[i] >= block[i-1]) {\n                        block_decreasing = false;\n                        break;\n                    }\n                }\n                if (block_decreasing) {\n                    score += 300;\n                }\n                \n                // Prefer stacks with larger tops (to avoid burying small boxes)\n                score += dest_top / 10; // Scale down\n                \n                // Penalize if we're creating a very tall stack\n                if (stacks[d].size() > 15) {\n                    score -= 200;\n                }\n            }\n            \n            // Penalize if the block's top is very small (might block future outputs)\n            int block_top = block.back();\n            if (block_top <= next_box + 10) { // If it's close to current smallest\n                score -= 300;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dest = d;\n            }\n        }\n        \n        // Fallback if no good destination found\n        if (best_dest == -1) {\n            for (int d = 0; d < m; ++d) {\n                if (d != source_stack) {\n                    best_dest = d;\n                    break;\n                }\n            }\n        }\n        \n        return best_dest;\n    };\n\n    while (next_box <= n) {\n        auto [s, idx] = find_box(next_box);\n        \n        if (idx == (int)stacks[s].size() - 1) {\n            // Already on top - carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        } else {\n            // Need to move boxes above it\n            int w = stacks[s][idx + 1];\n            \n            // Extract the segment above next_box\n            vector<int> segment(stacks[s].begin() + idx + 1, stacks[s].end());\n            \n            // Find best destination using our heuristic\n            int d = find_best_destination(s, segment);\n            \n            // Move the segment\n            ops.emplace_back(w, d + 1);\n            stacks[d].insert(stacks[d].end(), segment.begin(), segment.end());\n            \n            // Remove the moved boxes from source stack\n            stacks[s].resize(idx + 1);\n            \n            // Now next_box is on top - carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        }\n        \n        // Optional: Try to maintain decreasing order by moving single boxes\n        // that are out of place (only if we have plenty of operation budget)\n        if (ops.size() < 4000) { // Only if we have budget\n            for (int i = 0; i < m; ++i) {\n                if (stacks[i].size() > 1) {\n                    // Check if the top two boxes are out of order\n                    if (stacks[i].size() >= 2) {\n                        int top = stacks[i].back();\n                        int below = stacks[i][stacks[i].size() - 2];\n                        if (top > below) { // Should be decreasing, so top should be smaller\n                            // Find a place to move the top box\n                            for (int j = 0; j < m; ++j) {\n                                if (j != i && !stacks[j].empty() && \n                                    stacks[j].back() > top) {\n                                    ops.emplace_back(top, j + 1);\n                                    stacks[j].push_back(top);\n                                    stacks[i].pop_back();\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output operations\n    for (auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <array>\n#include <functional>\n\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_NODES = MAX_N * MAX_N;\nconst int DIRS = 4;\nconst int di[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dj[DIRS] = {0, 0, -1, 1};\nconst char dir_char[DIRS] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<double>> sqrt_d;\nvector<array<int, 4>> neighbors;\nvector<vector<int>> dist;\nvector<vector<int>> next_move;\n\nvoid build_graph() {\n    int total = N * N;\n    neighbors.assign(total, {-1, -1, -1, -1});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node = i * N + j;\n            if (i < N-1 && h[i][j] == '0') {\n                int ni = i+1, nj = j;\n                int nnode = ni * N + nj;\n                neighbors[node][1] = nnode;\n                neighbors[nnode][0] = node;\n            }\n            if (j < N-1 && v[i][j] == '0') {\n                int ni = i, nj = j+1;\n                int nnode = ni * N + nj;\n                neighbors[node][3] = nnode;\n                neighbors[nnode][2] = node;\n            }\n        }\n    }\n}\n\nvoid precompute_paths() {\n    int total = N * N;\n    dist.assign(total, vector<int>(total, -1));\n    next_move.assign(total, vector<int>(total, -1));\n    for (int s = 0; s < total; ++s) {\n        queue<int> q;\n        q.push(s);\n        dist[s][s] = 0;\n        next_move[s][s] = -1;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int v = neighbors[u][dir];\n                if (v == -1) continue;\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    if (u == s) {\n                        next_move[s][v] = dir;\n                    } else {\n                        next_move[s][v] = next_move[s][u];\n                    }\n                    q.push(v);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    sqrt_d.assign(N, vector<double>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n            sqrt_d[i][j] = sqrt(d[i][j]);\n        }\n    }\n\n    build_graph();\n    precompute_paths();\n\n    int total_nodes = N * N;\n    int home = 0;\n    const int L_max = 100000;\n\n    string moves;\n    vector<int> m(total_nodes, 0);\n    vector<bool> visited(total_nodes, false);\n    int current = home;\n\n    // Proper DFS that generates a minimal traversal\n    // We'll use recursion with backtracking\n    function<void(int)> dfs = [&](int node) {\n        visited[node] = true;\n        \n        // Sort neighbors by \u221ad descending\n        vector<pair<double, int>> sorted_neighbors;\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[node][dir];\n            if (nb == -1) continue;\n            int i = nb / N, j = nb % N;\n            sorted_neighbors.emplace_back(sqrt_d[i][j], dir);\n        }\n        sort(sorted_neighbors.rbegin(), sorted_neighbors.rend());\n        \n        for (auto [_, dir] : sorted_neighbors) {\n            int nb = neighbors[node][dir];\n            if (nb == -1 || visited[nb]) continue;\n            \n            // Move to neighbor\n            moves += dir_char[dir];\n            current = nb;\n            m[current]++;\n            \n            // Recursively visit\n            dfs(nb);\n            \n            // Backtrack\n            int opposite_dir = dir ^ 1;\n            moves += dir_char[opposite_dir];\n            current = node;\n            m[current]++;\n        }\n    };\n    \n    // Start DFS from home\n    dfs(home);\n\n    // Now we have a DFS traversal that returns to home\n    // The length should be 2*(N^2-1) which is at most 2*1599 = 3198\n    \n    // Phase 2: Extend the walk to approach L_max moves\n    int current_length = moves.size();\n    \n    // If we already have more than L_max moves, truncate\n    if (current_length > L_max) {\n        moves.resize(L_max);\n        cout << moves << endl;\n        return 0;\n    }\n    \n    // Otherwise, extend with simple, safe moves\n    while (current_length < L_max) {\n        int remaining = L_max - current_length;\n        int dist_home = dist[current][home];\n        \n        // If we can't make any more moves and return home, break\n        if (remaining <= dist_home) {\n            break;\n        }\n        \n        // Find the neighbor with highest \u221ad that still allows returning home\n        double best_score = -1.0;\n        int best_dir = -1;\n        \n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb == -1) continue;\n            \n            int new_dist_home = dist[nb][home];\n            if (remaining - 1 < new_dist_home) {\n                continue; // Can't return home if we make this move\n            }\n            \n            int i = nb / N, j = nb % N;\n            double score = sqrt_d[i][j] / (m[nb] + 1.0);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        if (best_dir == -1) {\n            // No safe move to a better square, try any safe move\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int nb = neighbors[current][dir];\n                if (nb == -1) continue;\n                \n                int new_dist_home = dist[nb][home];\n                if (remaining - 1 >= new_dist_home) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir == -1) {\n            // No safe move at all, break\n            break;\n        }\n        \n        // Make the move\n        moves += dir_char[best_dir];\n        current = neighbors[current][best_dir];\n        m[current]++;\n        current_length++;\n    }\n    \n    // Return home\n    while (current != home && current_length < L_max) {\n        int dir = next_move[current][home];\n        if (dir == -1) break;\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        current_length++;\n    }\n    \n    // If we still have moves left, add simple loops at home\n    while (current_length < L_max) {\n        // Find any valid move from home\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb != -1) {\n                // Go to neighbor and back\n                moves += dir_char[dir];\n                current = neighbors[current][dir];\n                m[current]++;\n                current_length++;\n                if (current_length >= L_max) break;\n                \n                moves += dir_char[dir ^ 1]; // opposite direction\n                current = neighbors[current][dir ^ 1];\n                m[current]++;\n                current_length++;\n                break;\n            }\n        }\n    }\n\n    // Ensure we end at home\n    if (current != home) {\n        // This shouldn't happen, but if it does, try to go home\n        while (current != home && moves.size() < L_max) {\n            int dir = next_move[current][home];\n            if (dir == -1) break;\n            moves += dir_char[dir];\n            current = neighbors[current][dir];\n        }\n    }\n\n    // Final check: ensure we don't exceed L_max\n    if (moves.size() > L_max) {\n        moves.resize(L_max);\n    }\n\n    cout << moves << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int M_MAX = 200;\nusing Bits = bitset<M_MAX>;\n\n// Rolling hash parameters\nconst uint64_t BASE = 91138233;\nconst int MAX_LEN = 2000;\nvector<uint64_t> POW(MAX_LEN + 1);\n\nstruct MyString {\n    string s;\n    Bits cov;\n    vector<uint64_t> pref;\n    int len;\n\n    MyString(string s_, Bits cov_) : s(move(s_)), cov(cov_), len(s.size()) {\n        pref.resize(len + 1);\n        pref[0] = 0;\n        for (int i = 0; i < len; ++i) {\n            pref[i + 1] = pref[i] * BASE + (s[i] - 'A' + 1);\n        }\n    }\n\n    uint64_t get_hash(int l, int r) const {\n        return pref[r + 1] - pref[l] * POW[r - l + 1];\n    }\n};\n\n// Global variables for patterns and letter distances\nunordered_map<string, int> pat_to_idx_global;\nint min_letter_dist[26][26];\n\n// Helper: compute which patterns appear in a string\nBits compute_cov(const string& s) {\n    Bits bs;\n    int L = s.size();\n    for (int i = 0; i <= L - 5; ++i) {\n        string sub = s.substr(i, 5);\n        auto it = pat_to_idx_global.find(sub);\n        if (it != pat_to_idx_global.end()) {\n            bs.set(it->second);\n        }\n    }\n    return bs;\n}\n\n// Helper: maximum suffix-prefix overlap\nint overlap(const MyString& a, const MyString& b) {\n    int lo = 0, hi = min(a.len, b.len);\n    while (lo < hi) {\n        int mid = (lo + hi + 1) / 2;\n        uint64_t ha = a.get_hash(a.len - mid, a.len - 1);\n        uint64_t hb = b.get_hash(0, mid - 1);\n        if (ha == hb)\n            lo = mid;\n        else\n            hi = mid - 1;\n    }\n    return lo;\n}\n\n// Heuristic: estimate travel cost between consecutive letters\nint heuristic_cost(const string& s) {\n    int cost = 0;\n    for (size_t i = 0; i < s.size() - 1; ++i) {\n        cost += min_letter_dist[s[i] - 'A'][s[i + 1] - 'A'];\n    }\n    return cost;\n}\n\n// Pair merging with random tie-breaking and heuristic optimization\nstring pair_merge_randomized(vector<MyString> initial, mt19937& rng) {\n    vector<MyString> cur = initial;\n    \n    while (cur.size() > 1) {\n        // Remove strings that are subsets of others\n        bool removed = false;\n        for (size_t i = 0; i < cur.size() && !removed; ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                if ((cur[i].cov & cur[j].cov) == cur[j].cov) {\n                    cur.erase(cur.begin() + j);\n                    removed = true;\n                    break;\n                }\n                if ((cur[i].cov & cur[j].cov) == cur[i].cov) {\n                    cur.erase(cur.begin() + i);\n                    removed = true;\n                    break;\n                }\n            }\n        }\n        if (removed) continue;\n\n        // Find all pairs with maximum overlap\n        int best_ov = -1;\n        vector<tuple<size_t, size_t, bool>> candidates; // i, j, rev\n        \n        for (size_t i = 0; i < cur.size(); ++i) {\n            for (size_t j = 0; j < cur.size(); ++j) {\n                if (i == j) continue;\n                \n                int ov = overlap(cur[i], cur[j]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    candidates.clear();\n                    candidates.emplace_back(i, j, false);\n                } else if (ov == best_ov) {\n                    candidates.emplace_back(i, j, false);\n                }\n                \n                ov = overlap(cur[j], cur[i]);\n                if (ov > best_ov) {\n                    best_ov = ov;\n                    candidates.clear();\n                    candidates.emplace_back(i, j, true);\n                } else if (ov == best_ov) {\n                    candidates.emplace_back(i, j, true);\n                }\n            }\n        }\n        \n        // Among candidates with best overlap, find those with minimum heuristic cost\n        int best_heuristic = INT_MAX;\n        vector<tuple<size_t, size_t, bool>> best_candidates;\n        \n        for (auto [i, j, rev] : candidates) {\n            string merged;\n            if (!rev) {\n                merged = cur[i].s + cur[j].s.substr(best_ov);\n            } else {\n                merged = cur[j].s + cur[i].s.substr(best_ov);\n            }\n            int h = heuristic_cost(merged);\n            if (h < best_heuristic) {\n                best_heuristic = h;\n                best_candidates.clear();\n                best_candidates.emplace_back(i, j, rev);\n            } else if (h == best_heuristic) {\n                best_candidates.emplace_back(i, j, rev);\n            }\n        }\n        \n        // Randomly select one from the best candidates\n        auto [best_i, best_j, best_rev] = best_candidates[rng() % best_candidates.size()];\n        \n        // Merge\n        string new_s;\n        if (!best_rev) {\n            new_s = cur[best_i].s + cur[best_j].s.substr(best_ov);\n        } else {\n            new_s = cur[best_j].s + cur[best_i].s.substr(best_ov);\n        }\n        \n        Bits new_cov = compute_cov(new_s);\n        \n        // Remove the two strings (larger index first)\n        size_t idx1 = best_i, idx2 = best_j;\n        if (idx1 > idx2) swap(idx1, idx2);\n        cur.erase(cur.begin() + idx2);\n        cur.erase(cur.begin() + idx1);\n        cur.emplace_back(move(new_s), new_cov);\n        \n        // Early exit if we have full coverage\n        if (new_cov.all()) {\n            cur = {cur.back()};\n            break;\n        }\n    }\n    \n    return cur[0].s;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Precompute powers\n    POW[0] = 1;\n    for (int i = 1; i <= MAX_LEN; ++i) {\n        POW[i] = POW[i - 1] * BASE;\n    }\n\n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<string> patterns(M);\n    for (int k = 0; k < M; ++k) {\n        cin >> patterns[k];\n        pat_to_idx_global[patterns[k]] = k;\n    }\n\n    // Precompute minimum distances between letters\n    const int INF = 1e9;\n    for (int i = 0; i < 26; ++i) {\n        for (int j = 0; j < 26; ++j) {\n            min_letter_dist[i][j] = INF;\n        }\n    }\n    \n    vector<vector<int>> pos_for_char(26);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            pos_for_char[c - 'A'].push_back(i * N + j);\n        }\n    }\n    \n    for (int c1 = 0; c1 < 26; ++c1) {\n        for (int id1 : pos_for_char[c1]) {\n            int x1 = id1 / N, y1 = id1 % N;\n            for (int c2 = 0; c2 < 26; ++c2) {\n                for (int id2 : pos_for_char[c2]) {\n                    int x2 = id2 / N, y2 = id2 % N;\n                    int d = abs(x1 - x2) + abs(y1 - y2);\n                    if (d < min_letter_dist[c1][c2]) {\n                        min_letter_dist[c1][c2] = d;\n                    }\n                }\n            }\n        }\n    }\n\n    const int CELLS = N * N;\n    vector<vector<int>> dist(CELLS, vector<int>(CELLS));\n    for (int id1 = 0; id1 < CELLS; ++id1) {\n        int x1 = id1 / N, y1 = id1 % N;\n        for (int id2 = 0; id2 < CELLS; ++id2) {\n            int x2 = id2 / N, y2 = id2 % N;\n            dist[id1][id2] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    // Create initial MyString objects\n    vector<MyString> initial;\n    for (int k = 0; k < M; ++k) {\n        Bits b;\n        b.set(k);\n        initial.emplace_back(patterns[k], b);\n    }\n\n    // Multi-start randomized pair merging\n    random_device rd;\n    mt19937 rng(rd());\n    const int NUM_TRIALS = 20;\n    string best_string;\n    int best_len = INT_MAX;\n    \n    for (int trial = 0; trial < NUM_TRIALS; ++trial) {\n        // Shuffle initial patterns\n        shuffle(initial.begin(), initial.end(), rng);\n        string candidate = pair_merge_randomized(initial, rng);\n        if (candidate.size() < best_len) {\n            best_len = candidate.size();\n            best_string = candidate;\n        }\n    }\n\n    // DP for optimal key sequence\n    int L = best_string.size();\n    struct State {\n        int id;\n        int cost;\n        int prev_idx;\n    };\n    vector<vector<State>> states(L);\n\n    int start_id = si * N + sj;\n    for (int id : pos_for_char[best_string[0] - 'A']) {\n        states[0].push_back({id, dist[start_id][id] + 1, -1});\n    }\n\n    for (int i = 1; i < L; ++i) {\n        char c = best_string[i];\n        vector<int> cur_ids = pos_for_char[c - 'A'];\n        vector<State> cur_states;\n        for (int id : cur_ids) {\n            int best_cost = INT_MAX;\n            int best_prev = -1;\n            for (size_t idx = 0; idx < states[i - 1].size(); ++idx) {\n                const State& prev = states[i - 1][idx];\n                int cand = prev.cost + dist[prev.id][id] + 1;\n                if (cand < best_cost) {\n                    best_cost = cand;\n                    best_prev = idx;\n                }\n            }\n            cur_states.push_back({id, best_cost, best_prev});\n        }\n        states[i] = move(cur_states);\n    }\n\n    // Find best final state\n    int best_idx = 0;\n    int best_cost = states[L - 1][0].cost;\n    for (size_t i = 1; i < states[L - 1].size(); ++i) {\n        if (states[L - 1][i].cost < best_cost) {\n            best_cost = states[L - 1][i].cost;\n            best_idx = i;\n        }\n    }\n\n    // Backtrack to get path\n    vector<int> path_ids(L);\n    int idx = best_idx;\n    for (int i = L - 1; i >= 0; --i) {\n        path_ids[i] = states[i][idx].id;\n        idx = states[i][idx].prev_idx;\n    }\n\n    // Output\n    for (int id : path_ids) {\n        int x = id / N, y = id % N;\n        cout << x << ' ' << y << '\\n';\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    // Read shapes (not used in this approach)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        for (int s = 0; s < d; ++s) {\n            int i, j;\n            cin >> i >> j;\n        }\n    }\n\n    vector<pair<int, int>> positives;\n    vector<vector<bool>> drilled(N, vector<bool>(N, false));\n    queue<pair<int, int>> q;\n\n    // Helper function to drill a square\n    auto drill = [&](int i, int j) {\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        int val;\n        cin >> val;\n        return val;\n    };\n\n    // Initial sparse drilling: checkerboard pattern\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if ((i + j) % 2 == 0) {\n                int val = drill(i, j);\n                drilled[i][j] = true;\n                if (val > 0) {\n                    positives.emplace_back(i, j);\n                    // Add neighbors to queue\n                    if (i + 1 < N) q.emplace(i + 1, j);\n                    if (i - 1 >= 0) q.emplace(i - 1, j);\n                    if (j + 1 < N) q.emplace(i, j + 1);\n                    if (j - 1 >= 0) q.emplace(i, j - 1);\n                }\n            }\n        }\n    }\n\n    // BFS from queued squares\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (drilled[i][j]) continue;\n        \n        int val = drill(i, j);\n        drilled[i][j] = true;\n        if (val > 0) {\n            positives.emplace_back(i, j);\n            // Add neighbors\n            if (i + 1 < N && !drilled[i + 1][j]) q.emplace(i + 1, j);\n            if (i - 1 >= 0 && !drilled[i - 1][j]) q.emplace(i - 1, j);\n            if (j + 1 < N && !drilled[i][j + 1]) q.emplace(i, j + 1);\n            if (j - 1 >= 0 && !drilled[i][j - 1]) q.emplace(i, j - 1);\n        }\n    }\n\n    // Output final guess\n    cout << \"a \" << positives.size();\n    for (auto [i, j] : positives) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    cout.flush();\n    \n    int resp;\n    cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int area;\n};\n\n// tries to pack rectangles with desired areas B (sorted descending) using common row height H\n// returns true and fills rects if successful\nbool pack(int W, int H, const vector<int>& B, vector<Rect>& rects) {\n    int N = B.size();\n    vector<int> w(N);\n    for (int i = 0; i < N; ++i) {\n        w[i] = (B[i] + H - 1) / H;          // width needed for area at least B[i]\n        if (w[i] > W) return false;         // too wide to fit\n    }\n    // indices sorted by width descending (first-fit decreasing)\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    vector<int> row_used;                     // used width in each row\n    vector<vector<pair<int, int>>> row_items; // each row: (rectangle index, start_x)\n\n    for (int i : idx) {\n        int placed = -1;\n        for (int r = 0; r < (int)row_used.size(); ++r) {\n            if (row_used[r] + w[i] <= W) {\n                placed = r;\n                break;\n            }\n        }\n        if (placed == -1) {                   // start new row\n            row_used.push_back(w[i]);\n            row_items.push_back({{i, 0}});\n        } else {\n            int start_x = row_used[placed];\n            row_used[placed] += w[i];\n            row_items[placed].emplace_back(i, start_x);\n        }\n    }\n\n    int rows = row_used.size();\n    if (rows * H > W) return false;           // total height exceeds W\n\n    rects.assign(N, Rect());\n    for (int r = 0; r < rows; ++r) {\n        int y0 = r * H;\n        int y1 = y0 + H;\n        for (auto& p : row_items[r]) {\n            int id = p.first;\n            int x0 = p.second;\n            rects[id].x0 = x0;\n            rects[id].x1 = x0 + w[id];\n            rects[id].y0 = y0;\n            rects[id].y1 = y1;\n            rects[id].area = w[id] * H;\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    cin >> W >> D >> N;\n\n    vector<vector<int>> a_original(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a_original[d][k];\n\n    // ----- build descending demands per day -----\n    vector<vector<int>> a_desc(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        a_desc[d] = a_original[d];\n        sort(a_desc[d].begin(), a_desc[d].end(), greater<int>());\n    }\n\n    // ----- for each position i (i-th largest) collect values over days -----\n    vector<vector<int>> slot_vals(N, vector<int>(D));\n    for (int i = 0; i < N; ++i) {\n        for (int d = 0; d < D; ++d)\n            slot_vals[i][d] = a_desc[d][i];\n        sort(slot_vals[i].begin(), slot_vals[i].end(), greater<int>());\n    }\n\n    // ----- water filling to obtain optimal target areas b[i] -----\n    vector<int> b(N, 0);\n    vector<int> ptr(N, D);                // number of values > current b[i]\n    using P = pair<int, int>;\n    priority_queue<P> pq;                 // max-heap by f = ptr\n    for (int i = 0; i < N; ++i)\n        pq.emplace(ptr[i], i);\n\n    const int S = W * W;\n    int total_used = 0;\n    while (total_used < S && !pq.empty()) {\n        auto [f, i] = pq.top();\n        pq.pop();\n        if (f != ptr[i]) continue;        // outdated entry\n        if (f == 0) break;                // no further improvement possible\n        // add one unit to rectangle i\n        b[i]++;\n        total_used++;\n        // update ptr[i]\n        while (ptr[i] > 0 && slot_vals[i][ptr[i] - 1] <= b[i])\n            ptr[i]--;\n        pq.emplace(ptr[i], i);\n    }\n\n    // b now contains the desired areas; sort them descending\n    vector<int> B = b;\n    sort(B.begin(), B.end(), greater<int>());\n\n    // ----- pack rectangles into the W x W square -----\n    vector<Rect> rects;\n    int H_min = 0;\n    for (int bi : B)\n        H_min = max(H_min, (bi + W - 1) / W);   // smallest H such that width <= W\n\n    bool packed = false;\n    auto pack_lambda = [&](int H, const vector<int>& B, vector<Rect>& rects) -> bool {\n        return pack(W, H, B, rects);\n    };\n    for (int H = H_min; H <= W; ++H) {\n        if (pack_lambda(H, B, rects)) {\n            packed = true;\n            break;\n        }\n    }\n    if (!packed) {   // fallback: vertical strips of almost equal width\n        int Nrect = B.size();\n        vector<int> widths(Nrect, W / Nrect);\n        int rem = W % Nrect;\n        for (int i = 0; i < rem; ++i) widths[i]++;\n        rects.resize(Nrect);\n        int x = 0;\n        for (int i = 0; i < Nrect; ++i) {\n            rects[i].x0 = x;\n            rects[i].x1 = x + widths[i];\n            rects[i].y0 = 0;\n            rects[i].y1 = W;\n            rects[i].area = widths[i] * W;\n            x += widths[i];\n        }\n    }\n\n    // ----- order rectangles by area (largest first) -----\n    vector<int> rect_order(N);\n    iota(rect_order.begin(), rect_order.end(), 0);\n    sort(rect_order.begin(), rect_order.end(),\n         [&](int i, int j) { return rects[i].area > rects[j].area; });\n\n    // ----- assign rectangles to reservations each day -----\n    vector<vector<int>> assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int, int>> dem;   // (demand, original index)\n        for (int k = 0; k < N; ++k)\n            dem.emplace_back(a_original[d][k], k);\n        sort(dem.begin(), dem.end(), greater<pair<int, int>>());\n        for (int t = 0; t < N; ++t) {\n            int orig_k = dem[t].second;\n            int ridx = rect_order[t];\n            assign[d][orig_k] = ridx;\n        }\n    }\n\n    // ----- output -----\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int r = assign[d][k];\n            cout << rects[r].x0 << \" \" << rects[r].y0 << \" \"\n                 << rects[r].x1 << \" \" << rects[r].y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll MOD = 998244353;\n\nll mod(ll x) {\n    return ((x % MOD) + MOD) % MOD;\n}\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<vector<ll>> a(N, vector<ll>(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    vector<vector<vector<ll>>> s(M, vector<vector<ll>>(3, vector<ll>(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    // Greedy initial solution\n    vector<vector<ll>> board = a;\n    vector<tuple<int, int, int>> ops;\n    for (int step = 0; step < K; ++step) {\n        ll best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll gain = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int i = p + di, j = q + dj;\n                            ll old_val = board[i][j];\n                            ll add = s[m][di][dj];\n                            ll new_val = old_val + add;\n                            gain += mod(new_val) - mod(old_val);\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int i = best_p + di, j = best_q + dj;\n                board[i][j] += s[best_m][di][dj];\n            }\n        }\n        ops.emplace_back(best_m, best_p, best_q);\n    }\n\n    // Compute current score\n    ll current_score = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_score += mod(board[i][j]);\n        }\n    }\n    ll best_score = current_score;\n    auto best_board = board;\n    auto best_ops = ops;\n\n    // Simulated Annealing\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_op(0, M - 1);\n    uniform_int_distribution<int> rand_pos(0, N - 3);\n\n    const int SA_ITER = 300000;\n    double T = 1e10;\n    const double cooling = 0.999985;\n\n    int L = ops.size();\n    for (int iter = 0; iter < SA_ITER; ++iter) {\n        if (L == 0 && K == 0) break;\n        double move_choice = uniform(rng);\n        int move_type;\n        if (L == 0) move_type = 0; // add\n        else if (L == K) {\n            if (move_choice < 0.3) move_type = 1; // remove\n            else if (move_choice < 0.6) move_type = 2; // replace\n            else move_type = 3; // double replace (only if L>=2)\n            if (move_type == 3 && L < 2) move_type = (move_choice < 0.5) ? 1 : 2;\n        } else {\n            if (move_choice < 0.2) move_type = 0; // add\n            else if (move_choice < 0.4) move_type = 1; // remove\n            else if (move_choice < 0.7) move_type = 2; // replace\n            else move_type = 3; // double replace\n            if (move_type == 3 && L < 2) move_type = (move_choice < 0.85) ? 0 : 2;\n        }\n\n        ll delta = 0;\n        if (move_type == 0) { // add\n            if (L >= K) continue;\n            int m = rand_op(rng);\n            int p = rand_pos(rng);\n            int q = rand_pos(rng);\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val + s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] += s[m][di][dj];\n                    }\n                }\n                ops.emplace_back(m, p, q);\n                L++;\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else if (move_type == 1) { // remove\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m, p, q] = ops[idx];\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val - s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] -= s[m][di][dj];\n                    }\n                }\n                ops.erase(ops.begin() + idx);\n                L--;\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else if (move_type == 2) { // replace\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m_old, p_old, q_old] = ops[idx];\n            int m_new = rand_op(rng);\n            int p_new = rand_pos(rng);\n            int q_new = rand_pos(rng);\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p_old + di, q_old + dj});\n                    cells.insert({p_new + di, q_new + dj});\n                }\n            }\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                if (i >= p_old && i < p_old + 3 && j >= q_old && j < q_old + 3) {\n                    int di = i - p_old, dj = j - q_old;\n                    new_val -= s[m_old][di][dj];\n                }\n                if (i >= p_new && i < p_new + 3 && j >= q_new && j < q_new + 3) {\n                    int di = i - p_new, dj = j - q_new;\n                    new_val += s[m_new][di][dj];\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_old + di, j = q_old + dj;\n                        board[i][j] -= s[m_old][di][dj];\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_new + di, j = q_new + dj;\n                        board[i][j] += s[m_new][di][dj];\n                    }\n                }\n                ops[idx] = {m_new, p_new, q_new};\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else { // double replace (move_type == 3)\n            if (L < 2) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx1 = rand_idx(rng);\n            int idx2 = rand_idx(rng);\n            while (idx2 == idx1) idx2 = rand_idx(rng);\n            auto [m_old1, p_old1, q_old1] = ops[idx1];\n            auto [m_old2, p_old2, q_old2] = ops[idx2];\n            int m_new1 = rand_op(rng), p_new1 = rand_pos(rng), q_new1 = rand_pos(rng);\n            int m_new2 = rand_op(rng), p_new2 = rand_pos(rng), q_new2 = rand_pos(rng);\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p_old1 + di, q_old1 + dj});\n                    cells.insert({p_old2 + di, q_old2 + dj});\n                    cells.insert({p_new1 + di, q_new1 + dj});\n                    cells.insert({p_new2 + di, q_new2 + dj});\n                }\n            }\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                if (i >= p_old1 && i < p_old1 + 3 && j >= q_old1 && j < q_old1 + 3) {\n                    int di = i - p_old1, dj = j - q_old1;\n                    new_val -= s[m_old1][di][dj];\n                }\n                if (i >= p_old2 && i < p_old2 + 3 && j >= q_old2 && j < q_old2 + 3) {\n                    int di = i - p_old2, dj = j - q_old2;\n                    new_val -= s[m_old2][di][dj];\n                }\n                if (i >= p_new1 && i < p_new1 + 3 && j >= q_new1 && j < q_new1 + 3) {\n                    int di = i - p_new1, dj = j - q_new1;\n                    new_val += s[m_new1][di][dj];\n                }\n                if (i >= p_new2 && i < p_new2 + 3 && j >= q_new2 && j < q_new2 + 3) {\n                    int di = i - p_new2, dj = j - q_new2;\n                    new_val += s[m_new2][di][dj];\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                // Remove old operations (larger index first to avoid shifting issues)\n                int first = idx1, second = idx2;\n                if (first < second) swap(first, second);\n                ops.erase(ops.begin() + first);\n                ops.erase(ops.begin() + second);\n                // Add new operations\n                ops.emplace_back(m_new1, p_new1, q_new1);\n                ops.emplace_back(m_new2, p_new2, q_new2);\n                // Update board\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        board[p_old1 + di][q_old1 + dj] -= s[m_old1][di][dj];\n                        board[p_old2 + di][q_old2 + dj] -= s[m_old2][di][dj];\n                        board[p_new1 + di][q_new1 + dj] += s[m_new1][di][dj];\n                        board[p_new2 + di][q_new2 + dj] += s[m_new2][di][dj];\n                    }\n                }\n                L = ops.size();\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        }\n        T *= cooling;\n    }\n\n    // Post-processing: greedy fill to K operations if we have less than K\n    board = best_board;\n    ops = best_ops;\n    L = ops.size();\n    while (L < K) {\n        ll best_gain = 0;\n        int best_m = -1, best_p = -1, best_q = -1;\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll gain = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int i = p + di, j = q + dj;\n                            ll old_val = board[i][j];\n                            ll add = s[m][di][dj];\n                            ll new_val = old_val + add;\n                            gain += mod(new_val) - mod(old_val);\n                        }\n                    }\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        if (best_gain <= 0) break;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int i = best_p + di, j = best_q + dj;\n                board[i][j] += s[best_m][di][dj];\n            }\n        }\n        ops.emplace_back(best_m, best_p, best_q);\n        L++;\n    }\n\n    // Output the best found solution (now possibly with added operations)\n    cout << ops.size() << \"\\n\";\n    for (auto [m, p, q] : ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    const int N = 5;\n    int A[N][N];\n    int grid[N][N];\n    pair<int, int> pos_of[25];          // position of each container on the grid, (-1,-1) if not present\n    int next_idx[N] = {0};              // how many containers have been placed from each gate\n    bool dispatched[25] = {false};\n    int next_dispatch = 0;              // not used in decisions but kept for completeness\n\n    // crane state\n    int crane_r = 0, crane_c = 0;\n    int crane_hold = -1;                // -1 means not holding\n\n    // read input\n    int dummy; cin >> dummy;            // N is always 5, but we read it\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // initialise grid and pos_of\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = -1;\n    for (int b = 0; b < 25; ++b)\n        pos_of[b] = {-1, -1};\n\n    vector<char> actions;               // actions of the large crane\n\n    // helper lambdas\n    auto move_towards = [&](int tr, int tc) -> char {\n        if (crane_r != tr)\n            return (tr < crane_r) ? 'U' : 'D';\n        else\n            return (tc < crane_c) ? 'L' : 'R';\n    };\n\n    auto decide = [&]() -> char {\n        if (crane_hold != -1) {\n            // holding a container -> go to its dispatch gate and release\n            int tr = crane_hold / N;\n            int tc = N - 1;\n            if (crane_r == tr && crane_c == tc)\n                return 'Q';\n            return move_towards(tr, tc);\n        } else {\n            // find the best container to pick up (greedy: minimize travel to pick up + travel to dispatch)\n            int best_b = -1;\n            int best_cost = 1e9;\n            int best_r = -1, best_c = -1;\n            for (int b = 0; b < N*N; ++b) {\n                if (pos_of[b].first != -1) { // container is on the grid\n                    int r = pos_of[b].first, c = pos_of[b].second;\n                    int dist_to_container = abs(crane_r - r) + abs(crane_c - c);\n                    int dist_to_dispatch = abs(r - b/N) + abs(c - (N-1));\n                    int total = dist_to_container + dist_to_dispatch;\n                    if (total < best_cost) {\n                        best_cost = total;\n                        best_b = b;\n                        best_r = r;\n                        best_c = c;\n                    }\n                }\n            }\n            if (best_b != -1) {\n                if (crane_r == best_r && crane_c == best_c)\n                    return 'P';\n                return move_towards(best_r, best_c);\n            } else {\n                // no container on grid, wait\n                return '.';\n            }\n        }\n    };\n\n    auto apply = [&](char act) {\n        if (act == 'P') {\n            // pick up\n            crane_hold = grid[crane_r][crane_c];\n            grid[crane_r][crane_c] = -1;\n            pos_of[crane_hold] = {-1, -1};\n        } else if (act == 'Q') {\n            // release\n            int cont = crane_hold;\n            grid[crane_r][crane_c] = cont;\n            pos_of[cont] = {crane_r, crane_c};\n            crane_hold = -1;\n        } else if (act == 'U') {\n            --crane_r;\n        } else if (act == 'D') {\n            ++crane_r;\n        } else if (act == 'L') {\n            --crane_c;\n        } else if (act == 'R') {\n            ++crane_c;\n        } // '.' does nothing\n    };\n\n    // simulation loop\n    const int MAX_TURN = 10000;\n    for (int turn = 1; turn <= MAX_TURN; ++turn) {\n        // ----- step 1 : receiving -----\n        for (int i = 0; i < N; ++i) {\n            if (next_idx[i] < N && grid[i][0] == -1) {\n                // condition: no crane holding a container at this square\n                if (crane_r == i && crane_c == 0 && crane_hold != -1)\n                    continue;   // blocked\n                int cont = A[i][next_idx[i]];\n                grid[i][0] = cont;\n                pos_of[cont] = {i, 0};\n                ++next_idx[i];\n            }\n        }\n\n        // ----- step 2 : actions -----\n        char act = decide();\n        actions.push_back(act);\n        apply(act);\n\n        // ----- step 3 : dispatch -----\n        for (int i = 0; i < N; ++i) {\n            int cont = grid[i][N-1];\n            if (cont != -1) {\n                dispatched[cont] = true;\n                grid[i][N-1] = -1;\n                pos_of[cont] = {-1, -1};\n            }\n        }\n\n        // update next_dispatch (not used in decisions but kept for completeness)\n        while (next_dispatch < N*N && dispatched[next_dispatch])\n            ++next_dispatch;\n\n        // check completion\n        bool all_done = true;\n        for (int b = 0; b < N*N; ++b)\n            if (!dispatched[b]) { all_done = false; break; }\n        if (all_done)\n            break;\n    }\n\n    int T = actions.size();\n    // output for large crane (initially at (0,0))\n    string S0(actions.begin(), actions.end());\n    cout << S0 << endl;\n    // output for the four small cranes: bomb at first turn, then idle\n    for (int i = 1; i < N; ++i) {\n        string Si = 'B' + string(T-1, '.');\n        cout << Si << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<array<int, 3>> supplies, demands;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0)\n                supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0)\n                demands.push_back({i, j, -h[i][j]});\n        }\n    }\n\n    vector<string> ops;\n    int cur_r = 0, cur_c = 0, load = 0;\n\n    auto move_to = [&](int tr, int tc) {\n        while (cur_r > tr) {\n            ops.push_back(\"U\");\n            --cur_r;\n        }\n        while (cur_r < tr) {\n            ops.push_back(\"D\");\n            ++cur_r;\n        }\n        while (cur_c > tc) {\n            ops.push_back(\"L\");\n            --cur_c;\n        }\n        while (cur_c < tc) {\n            ops.push_back(\"R\");\n            ++cur_c;\n        }\n    };\n\n    auto dist = [](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n\n    while (!supplies.empty() || !demands.empty()) {\n        if (load == 0) {\n            // Choose supply that minimizes: distance*100 - amount*benefit\n            int best_idx = -1;\n            double best_cost = 1e18;\n            for (int i = 0; i < (int)supplies.size(); ++i) {\n                auto& s = supplies[i];\n                int d = dist(cur_r, cur_c, s[0], s[1]);\n                int amt = s[2];\n                double cost = d * 100.0 - amt * 12.0;\n                if (best_idx == -1 || cost < best_cost) {\n                    best_idx = i;\n                    best_cost = cost;\n                }\n            }\n            auto& s = supplies[best_idx];\n            move_to(s[0], s[1]);\n            ops.push_back(\"+\" + to_string(s[2]));\n            load += s[2];\n            supplies.erase(supplies.begin() + best_idx);\n        } else {\n            vector<int> feasible;\n            for (int i = 0; i < (int)demands.size(); ++i) {\n                if (demands[i][2] <= load)\n                    feasible.push_back(i);\n            }\n            \n            if (!feasible.empty()) {\n                // Choose demand that minimizes: distance*(100+load) - amount*benefit\n                int best_idx = -1;\n                double best_cost = 1e18;\n                for (int idx : feasible) {\n                    auto& d = demands[idx];\n                    int distance = dist(cur_r, cur_c, d[0], d[1]);\n                    int amount = d[2];\n                    double cost = distance * (100.0 + load) - amount * 55.0;\n                    if (best_idx == -1 || cost < best_cost) {\n                        best_idx = idx;\n                        best_cost = cost;\n                    }\n                }\n                auto& d = demands[best_idx];\n                move_to(d[0], d[1]);\n                ops.push_back(\"-\" + to_string(d[2]));\n                load -= d[2];\n                demands.erase(demands.begin() + best_idx);\n            } else {\n                // No feasible demand - go to supply that balances distance and amount\n                int best_idx = -1;\n                double best_cost = 1e18;\n                for (int i = 0; i < (int)supplies.size(); ++i) {\n                    auto& s = supplies[i];\n                    int d = dist(cur_r, cur_c, s[0], s[1]);\n                    int amt = s[2];\n                    double cost = d * (100.0 + load) - amt * 22.0;\n                    if (best_idx == -1 || cost < best_cost) {\n                        best_idx = i;\n                        best_cost = cost;\n                    }\n                }\n                auto& s = supplies[best_idx];\n                move_to(s[0], s[1]);\n                ops.push_back(\"+\" + to_string(s[2]));\n                load += s[2];\n                supplies.erase(supplies.begin() + best_idx);\n            }\n        }\n    }\n\n    for (string& op : ops)\n        cout << op << endl;\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <numeric>\n#include <cmath>\n#include <random>\n#include <chrono>\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);  // 60\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    // Random generator for simulated annealing\n    auto now = chrono::high_resolution_clock::now();\n    auto seed = chrono::duration_cast<chrono::microseconds>(now.time_since_epoch()).count();\n    mt19937 rng(seed);\n\n    for (int t = 0; t < T; t++) {\n        // Compute sum for each seed\n        vector<int> sum(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            int s = 0;\n            for (int j = 0; j < M; j++) {\n                s += seeds[i][j];\n            }\n            sum[i] = s;\n        }\n\n        // Compute potential matrix for all seeds\n        vector<vector<int>> pot_all(seed_count, vector<int>(seed_count, 0));\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < seed_count; j++) {\n                if (i == j) continue;\n                int total = 0;\n                for (int l = 0; l < M; l++) {\n                    total += max(seeds[i][l], seeds[j][l]);\n                }\n                pot_all[i][j] = total;\n            }\n        }\n\n        // Find seed with max value for each criterion\n        vector<int> max_val(M, -1);\n        vector<int> max_idx(M, -1);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                if (seeds[i][l] > max_val[l]) {\n                    max_val[l] = seeds[i][l];\n                    max_idx[l] = i;\n                }\n            }\n        }\n\n        // Set of important seeds (max per criterion)\n        set<int> important;\n        for (int l = 0; l < M; l++) {\n            important.insert(max_idx[l]);\n        }\n\n        // Greedy selection of 36 seeds to maximize total potential\n        vector<bool> selected(seed_count, false);\n        vector<int> selected_orig;\n        for (int idx : important) {\n            selected[idx] = true;\n            selected_orig.push_back(idx);\n        }\n\n        // Greedy addition of remaining seeds\n        while (selected_orig.size() < 36) {\n            int best_gain = -1;\n            int best_idx = -1;\n            for (int i = 0; i < seed_count; i++) {\n                if (selected[i]) continue;\n                int gain = 0;\n                for (int j : selected_orig) {\n                    gain += pot_all[i][j];\n                }\n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_idx = i;\n                }\n            }\n            selected[best_idx] = true;\n            selected_orig.push_back(best_idx);\n        }\n\n        int K = selected_orig.size();  // 36\n        // Compute potential matrix for selected seeds (submatrix)\n        vector<vector<int>> pot(K, vector<int>(K, 0));\n        for (int i = 0; i < K; i++) {\n            for (int j = 0; j < K; j++) {\n                if (i == j) continue;\n                pot[i][j] = pot_all[selected_orig[i]][selected_orig[j]];\n            }\n        }\n\n        // Compute sums for selected seeds\n        vector<int> selected_sum(K);\n        for (int i = 0; i < K; i++) {\n            selected_sum[i] = sum[selected_orig[i]];\n        }\n\n        // Compute average L1 distance for each selected seed\n        vector<double> avg_dist(K, 0.0);\n        for (int i = 0; i < K; i++) {\n            double total_l1 = 0.0;\n            for (int j = 0; j < K; j++) {\n                if (i == j) continue;\n                // L1 = 2*pot - sum_i - sum_j\n                total_l1 += 2 * pot[i][j] - selected_sum[i] - selected_sum[j];\n            }\n            avg_dist[i] = total_l1 / (K - 1);\n        }\n\n        // Order to place seeds: descending by average L1 distance\n        vector<int> order(K);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) { return avg_dist[a] > avg_dist[b]; });\n\n        // Grid assignment: grid[i][j] = index in selected_orig (0..K-1)\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n\n        // Greedy placement\n        for (int idx : order) {\n            int best_score = -1;\n            int best_i = -1, best_j = -1;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) continue;\n                    int score = 0;\n                    // Check up, down, left, right\n                    if (i > 0 && grid[i-1][j] != -1) {\n                        score += pot[idx][grid[i-1][j]];\n                    }\n                    if (i < N-1 && grid[i+1][j] != -1) {\n                        score += pot[idx][grid[i+1][j]];\n                    }\n                    if (j > 0 && grid[i][j-1] != -1) {\n                        score += pot[idx][grid[i][j-1]];\n                    }\n                    if (j < N-1 && grid[i][j+1] != -1) {\n                        score += pot[idx][grid[i][j+1]];\n                    }\n                    if (score > best_score) {\n                        best_score = score;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n            // Place seed idx at (best_i, best_j)\n            grid[best_i][best_j] = idx;\n        }\n\n        // Helper function to compute score (max_potential * 1000 + total_potential)\n        auto compute_score = [&](const vector<vector<int>>& g) {\n            int max_pot = 0;\n            int total_pot = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    int s1 = g[i][j];\n                    if (i+1 < N) {\n                        int s2 = g[i+1][j];\n                        int p = pot[s1][s2];\n                        max_pot = max(max_pot, p);\n                        total_pot += p;\n                    }\n                    if (j+1 < N) {\n                        int s2 = g[i][j+1];\n                        int p = pot[s1][s2];\n                        max_pot = max(max_pot, p);\n                        total_pot += p;\n                    }\n                }\n            }\n            return max_pot * 1000 + total_pot;\n        };\n\n        // Simulated Annealing\n        double temperature = 1000.0;\n        double cooling_rate = 0.9999;\n        int iterations = 50000;\n        long long current_score = compute_score(grid);\n\n        uniform_int_distribution<int> dist_pos(0, N-1);\n        uniform_real_distribution<double> dist_real(0.0, 1.0);\n\n        for (int iter = 0; iter < iterations; iter++) {\n            // Randomly select two distinct positions\n            int i1 = dist_pos(rng), j1 = dist_pos(rng);\n            int i2 = dist_pos(rng), j2 = dist_pos(rng);\n            while (i1 == i2 && j1 == j2) {\n                i2 = dist_pos(rng);\n                j2 = dist_pos(rng);\n            }\n\n            // Swap\n            swap(grid[i1][j1], grid[i2][j2]);\n            long long new_score = compute_score(grid);\n            long long delta = new_score - current_score;\n\n            if (delta > 0 || dist_real(rng) < exp(delta / temperature)) {\n                current_score = new_score;\n            } else {\n                // Swap back\n                swap(grid[i1][j1], grid[i2][j2]);\n            }\n\n            temperature *= cooling_rate;\n        }\n\n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << selected_orig[grid[i][j]];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read next generation if not last turn\n        if (t < T - 1) {\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\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n#include <cstdlib>\n#include <cassert>\n#include <climits>\n\nusing namespace std;\n\n// Directions: 0:right, 1:down, 2:left, 3:up\nconst int dr[4] = {0, 1, 0, -1};\nconst int dc[4] = {1, 0, -1, 0};\n\nint N, M, V;\nint V_prime;          // number of vertices used\nint K;                // number of leaves = V_prime-1\nvector<int> len;      // length of each leaf (1-indexed, len[i] for leaf i)\nint root_r, root_c;   // current root position\nvector<int> dir;      // direction of each leaf (1-indexed)\nvector<bool> holding; // whether leaf i holds a takoyaki\nbool src_rem[30][30]; // remaining source squares\nbool tgt_rem[30][30]; // remaining target squares\nint src_cnt, tgt_cnt; // counts\n\n// Helper functions\ninline bool in_grid(int r, int c) {\n    return 0 <= r && r < N && 0 <= c && c < N;\n}\n\n// Output one turn\nvoid output_turn(char move, const vector<char>& rot, const vector<char>& act) {\n    string S(2 * V_prime, '.');\n    S[0] = move;\n    for (int i = 1; i <= K; ++i) {\n        S[i] = rot[i];\n    }\n    for (int i = 0; i <= K; ++i) {\n        if (act[i] == 'P') {\n            S[V_prime + i] = 'P';\n        }\n    }\n    cout << S << '\\n';\n}\n\n// Move root to (tr,tc) while rotating leaf `leaf` to direction `des_dir`.\n// Performs one step per turn, rotating the leaf as much as possible.\nvoid move_root_to(int tr, int tc, int leaf, int des_dir) {\n    while (root_r != tr || root_c != tc) {\n        // Determine movement direction\n        char move_char;\n        if (tr > root_r) move_char = 'D';\n        else if (tr < root_r) move_char = 'U';\n        else if (tc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Rotation for the leaf we are controlling\n        char rot_leaf = '.';\n        if (leaf != -1 && dir[leaf] != des_dir) {\n            int diff = (des_dir - dir[leaf] + 4) % 4;\n            if (diff == 1) {\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            } else if (diff == 3) {\n                rot_leaf = 'L';\n                dir[leaf] = (dir[leaf] + 3) % 4;\n            } else { // diff == 2, rotate arbitrarily (choose R)\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            }\n        }\n\n        vector<char> rot(K+1, '.');\n        if (leaf != -1) rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.'); // no pick/drop during movement\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        if (move_char == 'U') root_r--;\n        else if (move_char == 'D') root_r++;\n        else if (move_char == 'L') root_c--;\n        else if (move_char == 'R') root_c++;\n    }\n\n    // After reaching the target, finish rotation if needed\n    while (leaf != -1 && dir[leaf] != des_dir) {\n        char rot_leaf = '.';\n        int diff = (des_dir - dir[leaf] + 4) % 4;\n        if (diff == 1) {\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        } else if (diff == 3) {\n            rot_leaf = 'L';\n            dir[leaf] = (dir[leaf] + 3) % 4;\n        } else { // diff == 2\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        }\n        vector<char> rot(K+1, '.');\n        rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.');\n        output_turn('.', rot, act);\n    }\n}\n\n// Output a turn with only a pick/drop for a given leaf (no movement, no other rotations)\nvoid output_action(int leaf, char action) {\n    vector<char> rot(K+1, '.');\n    vector<char> act(K+1, '.');\n    act[leaf] = action;\n    output_turn('.', rot, act);\n}\n\n// Find any remaining target square that leaf i can reach, together with a suitable direction.\ntuple<int,int,int> find_target_for_leaf(int i) {\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (tgt_rem[r][c]) {\n                for (int d = 0; d < 4; ++d) {\n                    int nr = r - dr[d] * len[i];\n                    int nc = c - dc[d] * len[i];\n                    if (in_grid(nr, nc)) {\n                        return make_tuple(r, c, d);\n                    }\n                }\n            }\n        }\n    }\n    // should never happen\n    return make_tuple(-1, -1, -1);\n}\n\n// Find any remaining source square\npair<int,int> find_source() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (src_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Find any remaining target square\npair<int,int> find_target() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (tgt_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Try to stay in place to rotate a leaf 180\u00b0 and pick/drop if possible.\n// Returns true if we performed stay turns.\nbool try_stay_for_rotation() {\n    // First try drops\n    for (int i = 1; i <= K; ++i) {\n        if (!holding[i]) continue;\n        for (int d = 0; d < 4; ++d) {\n            int pr = root_r + dr[d] * len[i];\n            int pc = root_c + dc[d] * len[i];\n            if (!in_grid(pr, pc) || !tgt_rem[pr][pc]) continue;\n            int delta = (d - dir[i] + 4) % 4;\n            if (delta == 2) { // 180\u00b0 rotation needed\n                // Rotate twice (choose R,R) and drop on the second turn.\n                // First turn: rotate 90\u00b0 (R)\n                vector<char> rot1(K+1, '.');\n                rot1[i] = 'R';\n                vector<char> act1(K+1, '.');\n                output_turn('.', rot1, act1);\n                dir[i] = (dir[i] + 1) % 4;\n                \n                // Second turn: rotate another 90\u00b0 (R) and drop\n                vector<char> rot2(K+1, '.');\n                rot2[i] = 'R';\n                vector<char> act2(K+1, '.');\n                act2[i] = 'P';\n                output_turn('.', rot2, act2);\n                dir[i] = (dir[i] + 1) % 4; // now equals d\n                holding[i] = false;\n                tgt_rem[pr][pc] = false;\n                --tgt_cnt;\n                return true;\n            }\n        }\n    }\n    \n    // Then try picks\n    for (int i = 1; i <= K; ++i) {\n        if (holding[i]) continue;\n        for (int d = 0; d < 4; ++d) {\n            int pr = root_r + dr[d] * len[i];\n            int pc = root_c + dc[d] * len[i];\n            if (!in_grid(pr, pc) || !src_rem[pr][pc]) continue;\n            int delta = (d - dir[i] + 4) % 4;\n            if (delta == 2) { // 180\u00b0 rotation needed\n                // Rotate twice and pick on the second turn.\n                // First turn: rotate 90\u00b0 (R)\n                vector<char> rot1(K+1, '.');\n                rot1[i] = 'R';\n                vector<char> act1(K+1, '.');\n                output_turn('.', rot1, act1);\n                dir[i] = (dir[i] + 1) % 4;\n                \n                // Second turn: rotate another 90\u00b0 (R) and pick\n                vector<char> rot2(K+1, '.');\n                rot2[i] = 'R';\n                vector<char> act2(K+1, '.');\n                act2[i] = 'P';\n                output_turn('.', rot2, act2);\n                dir[i] = (dir[i] + 1) % 4; // now equals d\n                holding[i] = true;\n                src_rem[pr][pc] = false;\n                --src_cnt;\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N >> M >> V;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Determine sources and targets (remove overlaps)\n    src_cnt = tgt_cnt = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool s = (s_grid[i][j] == '1');\n            bool t = (t_grid[i][j] == '1');\n            if (s && t) {\n                // already in place, ignore\n                src_rem[i][j] = false;\n                tgt_rem[i][j] = false;\n            } else if (s) {\n                src_rem[i][j] = true;\n                ++src_cnt;\n                tgt_rem[i][j] = false;\n            } else if (t) {\n                tgt_rem[i][j] = true;\n                ++tgt_cnt;\n                src_rem[i][j] = false;\n            } else {\n                src_rem[i][j] = tgt_rem[i][j] = false;\n            }\n        }\n    }\n\n    // Design the arm: star with root 0 and leaves 1..K, lengths = 1,2,...,K\n    V_prime = V;                // use all vertices\n    K = V_prime - 1;\n    len.resize(K+1);\n    for (int i = 1; i <= K; ++i) len[i] = i;   // guaranteed i <= N-1 because N>=15, K<=14\n\n    // Initial root position (choose (0,0))\n    root_r = 0; root_c = 0;\n\n    // Output arm design\n    cout << V_prime << '\\n';\n    for (int i = 1; i <= K; ++i) {\n        cout << \"0 \" << len[i] << '\\n';\n    }\n    cout << root_r << ' ' << root_c << '\\n';\n\n    // Initialize state\n    dir.assign(K+1, 0);          // all initially point right\n    holding.assign(K+1, false);\n\n    // Snake traversal: generate order of cells\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        } else {\n            for (int j = N-1; j >= 0; --j) cells.emplace_back(i, j);\n        }\n    }\n\n    // Perform moves along the snake\n    size_t idx = 0;\n    while (idx < cells.size() - 1) {\n        int nr = cells[idx+1].first;\n        int nc = cells[idx+1].second;\n\n        // Determine movement character\n        char move_char;\n        if (nr > root_r) move_char = 'D';\n        else if (nr < root_r) move_char = 'U';\n        else if (nc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Greedy assignment of picks/drops at the new position\n        vector<bool> used(K+1, false);\n        vector<int> desired_dir(K+1, -1);\n        vector<char> action(K+1, '.');\n\n        // Drops first\n        for (int i = 1; i <= K; ++i) {\n            if (holding[i] && !used[i]) {\n                // Try the three reachable directions (current, left, right)\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && tgt_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = false;\n                        tgt_rem[pr][pc] = false;\n                        --tgt_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Picks\n        for (int i = 1; i <= K; ++i) {\n            if (!holding[i] && !used[i]) {\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && src_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = true;\n                        src_rem[pr][pc] = false;\n                        --src_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Build rotation commands\n        vector<char> rot(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (desired_dir[i] != -1) {\n                int delta = (desired_dir[i] - dir[i] + 4) % 4;\n                if (delta == 0) rot[i] = '.';\n                else if (delta == 1) rot[i] = 'R';\n                else if (delta == 3) rot[i] = 'L';\n                // delta == 2 cannot happen because we only used reachable directions\n                dir[i] = desired_dir[i];\n            }\n        }\n\n        // Build action vector (root action always '.')\n        vector<char> act(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (action[i] == 'P') act[i] = 'P';\n        }\n\n        // Output the turn (move to next cell)\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        root_r = nr;\n        root_c = nc;\n        ++idx;\n\n        // After moving, stay for rotations if beneficial (multiple stays allowed)\n        int stays = 0;\n        while (stays < K && try_stay_for_rotation()) {\n            stays++;\n        }\n    }\n\n    // If all takoyaki are already at targets, we are done\n    if (src_cnt == 0 && tgt_cnt == 0) {\n        return 0;\n    }\n\n    // ----- Cleanup phase -----\n    // Step 1: Drop any takoyaki still held by leaves\n    for (int i = 1; i <= K; ++i) {\n        while (holding[i]) {\n            auto [tr, tc, d] = find_target_for_leaf(i);\n            int nr = tr - dr[d] * len[i];\n            int nc = tc - dc[d] * len[i];\n            move_root_to(nr, nc, i, d);\n            output_action(i, 'P');\n            holding[i] = false;\n            tgt_rem[tr][tc] = false;\n            --tgt_cnt;\n        }\n    }\n\n    // Step 2: Move remaining sources to targets using optimal leaf selection\n    while (src_cnt > 0) {\n        // Find the source that can be picked with minimal travel distance\n        int best_dist = INT_MAX;\n        int best_sr = -1, best_sc = -1;\n        int best_leaf = -1, best_dir = -1;\n        int best_nr = -1, best_nc = -1;\n        \n        for (int sr = 0; sr < N; ++sr) {\n            for (int sc = 0; sc < N; ++sc) {\n                if (!src_rem[sr][sc]) continue;\n                for (int i = 1; i <= K; ++i) {\n                    if (holding[i]) continue; // leaf already holding\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = sr - dr[d] * len[i];\n                        int nc = sc - dc[d] * len[i];\n                        if (!in_grid(nr, nc)) continue;\n                        int dist = abs(nr - root_r) + abs(nc - root_c);\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_sr = sr; best_sc = sc;\n                            best_leaf = i; best_dir = d;\n                            best_nr = nr; best_nc = nc;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Should always find a pickable source\n        if (best_dist == INT_MAX) break;\n        \n        // Move to pick position and pick\n        move_root_to(best_nr, best_nc, best_leaf, best_dir);\n        output_action(best_leaf, 'P');\n        holding[best_leaf] = true;\n        src_rem[best_sr][best_sc] = false;\n        --src_cnt;\n        \n        // Now find the best target for this leaf\n        int best_drop_dist = INT_MAX;\n        int best_tr = -1, best_tc = -1;\n        int best_d2 = -1;\n        int best_nr2 = -1, best_nc2 = -1;\n        \n        for (int tr = 0; tr < N; ++tr) {\n            for (int tc = 0; tc < N; ++tc) {\n                if (!tgt_rem[tr][tc]) continue;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int nr2 = tr - dr[d2] * len[best_leaf];\n                    int nc2 = tc - dc[d2] * len[best_leaf];\n                    if (!in_grid(nr2, nc2)) continue;\n                    int dist2 = abs(nr2 - root_r) + abs(nc2 - root_c);\n                    if (dist2 < best_drop_dist) {\n                        best_drop_dist = dist2;\n                        best_tr = tr; best_tc = tc;\n                        best_d2 = d2;\n                        best_nr2 = nr2; best_nc2 = nc2;\n                    }\n                }\n            }\n        }\n        \n        if (best_drop_dist == INT_MAX) {\n            // Should not happen, but just in case: find any target\n            auto [tr, tc, d2] = find_target_for_leaf(best_leaf);\n            best_tr = tr; best_tc = tc; best_d2 = d2;\n            best_nr2 = tr - dr[d2] * len[best_leaf];\n            best_nc2 = tc - dc[d2] * len[best_leaf];\n        }\n        \n        // Move to drop position and drop\n        move_root_to(best_nr2, best_nc2, best_leaf, best_d2);\n        output_action(best_leaf, 'P');\n        holding[best_leaf] = false;\n        tgt_rem[best_tr][best_tc] = false;\n        --tgt_cnt;\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n};\n\nint compute_score(int x1, int x2, int y1, int y2, \n                  const vector<Point>& mack, const vector<Point>& sard) {\n    int a = 0, b = 0;\n    for (const auto& p : mack) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) a++;\n    }\n    for (const auto& p : sard) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) b++;\n    }\n    return max(0, a - b + 1);\n}\n\n// Try to create an L-shaped polygon by combining two rectangles\ntuple<int, int, int, int, int, bool> try_l_shape(int x1, int x2, int y1, int y2,\n                                                 int score1,\n                                                 const vector<Point>& mack,\n                                                 const vector<Point>& sard,\n                                                 const vector<int>& xs,\n                                                 const vector<int>& ys) {\n    if (score1 <= 0) return {x1, x2, y1, y2, score1, false};\n    \n    // Try adding a vertical extension on the right side\n    for (int ext_x : xs) {\n        if (ext_x > x2 && ext_x <= min(MAX_COORD, x2 + 10000)) {\n            int new_score = compute_score(x1, ext_x, y1, y2, mack, sard);\n            if (new_score > score1) {\n                return {x1, ext_x, y1, y2, new_score, true};\n            }\n        }\n    }\n    \n    // Try adding a horizontal extension on the top side\n    for (int ext_y : ys) {\n        if (ext_y > y2 && ext_y <= min(MAX_COORD, y2 + 10000)) {\n            int new_score = compute_score(x1, x2, y1, ext_y, mack, sard);\n            if (new_score > score1) {\n                return {x1, x2, y1, ext_y, new_score, true};\n            }\n        }\n    }\n    \n    // Try adding a vertical extension on the left side\n    for (int ext_x : xs) {\n        if (ext_x < x1 && ext_x >= max(0, x1 - 10000)) {\n            int new_score = compute_score(ext_x, x2, y1, y2, mack, sard);\n            if (new_score > score1) {\n                return {ext_x, x2, y1, y2, new_score, true};\n            }\n        }\n    }\n    \n    // Try adding a horizontal extension on the bottom side\n    for (int ext_y : ys) {\n        if (ext_y < y1 && ext_y >= max(0, y1 - 10000)) {\n            int new_score = compute_score(x1, x2, ext_y, y2, mack, sard);\n            if (new_score > score1) {\n                return {x1, x2, ext_y, y2, new_score, true};\n            }\n        }\n    }\n    \n    return {x1, x2, y1, y2, score1, false};\n}\n\n// Try to create a U-shaped or more complex polygon by indenting to avoid sardines\ntuple<int, int, int, int, int, bool> try_indent_polygon(int x1, int x2, int y1, int y2,\n                                                        int score1,\n                                                        const vector<Point>& mack,\n                                                        const vector<Point>& sard,\n                                                        const vector<int>& xs,\n                                                        const vector<int>& ys) {\n    if (score1 <= 5) return {x1, x2, y1, y2, score1, false};\n    \n    // Count sardines in each region of the rectangle\n    int total_sardines = 0;\n    for (const auto& p : sard) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) total_sardines++;\n    }\n    \n    // If there are many sardines, try to create indentations\n    if (total_sardines > 3) {\n        // Try creating a vertical indentation on the right side\n        for (int indent_x : xs) {\n            if (indent_x > x1 && indent_x < x2) {\n                // Try indenting from the right\n                int new_score_right = compute_score(x1, indent_x, y1, y2, mack, sard);\n                if (new_score_right > score1 * 1.2) { // 20% improvement threshold\n                    return {x1, indent_x, y1, y2, new_score_right, true};\n                }\n                \n                // Try indenting from the left\n                int new_score_left = compute_score(indent_x, x2, y1, y2, mack, sard);\n                if (new_score_left > score1 * 1.2) {\n                    return {indent_x, x2, y1, y2, new_score_left, true};\n                }\n            }\n        }\n        \n        // Try creating a horizontal indentation\n        for (int indent_y : ys) {\n            if (indent_y > y1 && indent_y < y2) {\n                // Try indenting from the top\n                int new_score_top = compute_score(x1, x2, y1, indent_y, mack, sard);\n                if (new_score_top > score1 * 1.2) {\n                    return {x1, x2, y1, indent_y, new_score_top, true};\n                }\n                \n                // Try indenting from the bottom\n                int new_score_bottom = compute_score(x1, x2, indent_y, y2, mack, sard);\n                if (new_score_bottom > score1 * 1.2) {\n                    return {x1, x2, indent_y, y2, new_score_bottom, true};\n                }\n            }\n        }\n    }\n    \n    return {x1, x2, y1, y2, score1, false};\n}\n\ntuple<int, int, int, int, int> process_cell_size(int cell_size,\n                                                 const vector<Point>& mack,\n                                                 const vector<Point>& sard,\n                                                 const vector<int>& xs,\n                                                 const vector<int>& ys) {\n    int num_cells_x = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    int num_cells_y = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    vector<vector<int>> mack_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<vector<int>> sard_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<pair<int, int>> mack_cells(mack.size());\n\n    for (size_t i = 0; i < mack.size(); i++) {\n        int cx = mack[i].x / cell_size;\n        int cy = mack[i].y / cell_size;\n        mack_count[cx][cy]++;\n        mack_cells[i] = {cx, cy};\n    }\n    for (size_t i = 0; i < sard.size(); i++) {\n        int cx = sard[i].x / cell_size;\n        int cy = sard[i].y / cell_size;\n        sard_count[cx][cy]++;\n    }\n\n    vector<vector<int>> weight(num_cells_x, vector<int>(num_cells_y, 0));\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            weight[i][j] = mack_count[i][j] - sard_count[i][j];\n        }\n    }\n\n    auto count_mack = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : mack) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) cnt++;\n        }\n        return cnt;\n    };\n\n    auto count_sard = [&](int x1, int x2, int y1, int y2) {\n        int cnt = 0;\n        for (const auto& p : sard) {\n            if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) cnt++;\n        }\n        return cnt;\n    };\n\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 0, best_y1 = 0, best_y2 = 0;\n\n    // Cell rectangles\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0) {\n                int x1 = i * cell_size;\n                int x2 = min(MAX_COORD, (i + 1) * cell_size);\n                int y1 = j * cell_size;\n                int y2 = min(MAX_COORD, (j + 1) * cell_size);\n                if (x1 < x2 && y1 < y2) {\n                    int a = count_mack(x1, x2, y1, y2);\n                    int b = count_sard(x1, x2, y1, y2);\n                    int score = max(0, a - b + 1);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_x1 = x1;\n                        best_x2 = x2;\n                        best_y1 = y1;\n                        best_y2 = y2;\n                    }\n                }\n            }\n        }\n    }\n\n    // Connected components using BFS\n    vector<vector<bool>> visited(num_cells_x, vector<bool>(num_cells_y, false));\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0 && !visited[i][j]) {\n                // BFS to find component\n                vector<pair<int, int>> comp;\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();\n                    q.pop();\n                    comp.push_back({x, y});\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 < num_cells_x && ny >= 0 && ny < num_cells_y &&\n                            weight[nx][ny] > 0 && !visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n\n                // Get bounding box of mackerels in this component\n                int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n                for (size_t k = 0; k < mack.size(); k++) {\n                    int cx = mack_cells[k].first, cy = mack_cells[k].second;\n                    for (const auto& cell : comp) {\n                        if (cell.first == cx && cell.second == cy) {\n                            min_x = min(min_x, mack[k].x);\n                            max_x = max(max_x, mack[k].x);\n                            min_y = min(min_y, mack[k].y);\n                            max_y = max(max_y, mack[k].y);\n                            break;\n                        }\n                    }\n                }\n\n                // Expand if degenerate\n                if (min_x == max_x) {\n                    min_x = max(0, min_x - 1);\n                    max_x = min(MAX_COORD, max_x + 1);\n                }\n                if (min_y == max_y) {\n                    min_y = max(0, min_y - 1);\n                    max_y = min(MAX_COORD, max_y + 1);\n                }\n\n                if (min_x < max_x && min_y < max_y) {\n                    int a = count_mack(min_x, max_x, min_y, max_y);\n                    int b = count_sard(min_x, max_x, min_y, max_y);\n                    int score = max(0, a - b + 1);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_x1 = min_x;\n                        best_x2 = max_x;\n                        best_y1 = min_y;\n                        best_y2 = max_y;\n                    }\n                }\n            }\n        }\n    }\n\n    // Try L-shape if we have a decent rectangle\n    if (best_score > 10) {\n        auto [new_x1, new_x2, new_y1, new_y2, new_score, improved] = \n            try_l_shape(best_x1, best_x2, best_y1, best_y2, best_score, mack, sard, xs, ys);\n        if (improved && new_score > best_score) {\n            best_score = new_score;\n            best_x1 = new_x1;\n            best_x2 = new_x2;\n            best_y1 = new_y1;\n            best_y2 = new_y2;\n        }\n    }\n\n    return {best_x1, best_x2, best_y1, best_y2, best_score};\n}\n\nvoid smart_local_optimize(int& x1, int& x2, int& y1, int& y2,\n                          const vector<Point>& mack, const vector<Point>& sard) {\n    vector<int> xs, ys;\n    for (const auto& p : mack) {\n        xs.push_back(p.x);\n        ys.push_back(p.y);\n    }\n    for (const auto& p : sard) {\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    int current_score = compute_score(x1, x2, y1, y2, mack, sard);\n    bool improved = true;\n    int iterations = 0;\n    \n    // Try to expand in all directions first\n    while (improved && iterations < 15) {\n        improved = false;\n        iterations++;\n        \n        // Try left expansion\n        auto it_left = lower_bound(xs.begin(), xs.end(), x1);\n        if (it_left != xs.begin()) {\n            int new_x1 = *(--it_left);\n            int new_score = compute_score(new_x1, x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = new_x1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try right expansion\n        auto it_right = upper_bound(xs.begin(), xs.end(), x2);\n        if (it_right != xs.end()) {\n            int new_x2 = *it_right;\n            int new_score = compute_score(x1, new_x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x2 = new_x2;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try bottom expansion\n        auto it_bottom = lower_bound(ys.begin(), ys.end(), y1);\n        if (it_bottom != ys.begin()) {\n            int new_y1 = *(--it_bottom);\n            int new_score = compute_score(x1, x2, new_y1, y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = new_y1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try top expansion\n        auto it_top = upper_bound(ys.begin(), ys.end(), y2);\n        if (it_top != ys.end()) {\n            int new_y2 = *it_top;\n            int new_score = compute_score(x1, x2, y1, new_y2, mack, sard);\n            if (new_score > current_score) {\n                y2 = new_y2;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n    }\n    \n    // Then try to contract to exclude sardines\n    improved = true;\n    iterations = 0;\n    while (improved && iterations < 10) {\n        improved = false;\n        iterations++;\n        \n        // Try left contraction\n        auto it_left = upper_bound(xs.begin(), xs.end(), x1);\n        if (it_left != xs.end() && *it_left < x2) {\n            int new_x1 = *it_left;\n            int new_score = compute_score(new_x1, x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = new_x1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try right contraction\n        auto it_right = lower_bound(xs.begin(), xs.end(), x2);\n        if (it_right != xs.begin()) {\n            int new_x2 = *(--it_right);\n            if (new_x2 > x1) {\n                int new_score = compute_score(x1, new_x2, y1, y2, mack, sard);\n                if (new_score > current_score) {\n                    x2 = new_x2;\n                    current_score = new_score;\n                    improved = true;\n                    continue;\n                }\n            }\n        }\n        \n        // Try bottom contraction\n        auto it_bottom = upper_bound(ys.begin(), ys.end(), y1);\n        if (it_bottom != ys.end() && *it_bottom < y2) {\n            int new_y1 = *it_bottom;\n            int new_score = compute_score(x1, x2, new_y1, y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = new_y1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try top contraction\n        auto it_top = lower_bound(ys.begin(), ys.end(), y2);\n        if (it_top != ys.begin()) {\n            int new_y2 = *(--it_top);\n            if (new_y2 > y1) {\n                int new_score = compute_score(x1, x2, y1, new_y2, mack, sard);\n                if (new_score > current_score) {\n                    y2 = new_y2;\n                    current_score = new_score;\n                    improved = true;\n                    continue;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mack(N), sard(N);\n    for (int i = 0; i < N; i++) {\n        cin >> mack[i].x >> mack[i].y;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sard[i].x >> sard[i].y;\n    }\n\n    // Precompute sorted unique coordinates\n    vector<int> xs, ys;\n    for (const auto& p : mack) {\n        xs.push_back(p.x);\n        ys.push_back(p.y);\n    }\n    for (const auto& p : sard) {\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    // Try multiple grid sizes\n    vector<int> cell_sizes = {1500, 2000, 3000, 5000, 7500, 10000, 12000, 15000};\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 0, best_y1 = 0, best_y2 = 0;\n\n    for (int cell_size : cell_sizes) {\n        auto [x1, x2, y1, y2, score] = process_cell_size(cell_size, mack, sard, xs, ys);\n        if (score > best_score) {\n            best_score = score;\n            best_x1 = x1;\n            best_x2 = x2;\n            best_y1 = y1;\n            best_y2 = y2;\n        }\n    }\n\n    // Apply smart local optimization\n    if (best_score > 0) {\n        smart_local_optimize(best_x1, best_x2, best_y1, best_y2, mack, sard);\n        best_score = compute_score(best_x1, best_x2, best_y1, best_y2, mack, sard);\n    }\n\n    // Try L-shape with the best rectangle\n    if (best_score > 0) {\n        auto [new_x1, new_x2, new_y1, new_y2, new_score, improved] = \n            try_l_shape(best_x1, best_x2, best_y1, best_y2, best_score, mack, sard, xs, ys);\n        if (improved && new_score > best_score) {\n            best_score = new_score;\n            best_x1 = new_x1;\n            best_x2 = new_x2;\n            best_y1 = new_y1;\n            best_y2 = new_y2;\n        }\n    }\n\n    // Try indent polygon for better sardine avoidance\n    if (best_score > 5) {\n        auto [new_x1, new_x2, new_y1, new_y2, new_score, improved] = \n            try_indent_polygon(best_x1, best_x2, best_y1, best_y2, best_score, mack, sard, xs, ys);\n        if (improved && new_score > best_score) {\n            best_score = new_score;\n            best_x1 = new_x1;\n            best_x2 = new_x2;\n            best_y1 = new_y1;\n            best_y2 = new_y2;\n        }\n    }\n\n    // Fallback if no good rectangle found\n    if (best_score == 0) {\n        // Try to find a small rectangle around a mackerel\n        for (const auto& mp : mack) {\n            int x1 = max(0, mp.x - 1);\n            int x2 = min(MAX_COORD, mp.x + 1);\n            int y1 = max(0, mp.y - 1);\n            int y2 = min(MAX_COORD, mp.y + 1);\n            int score = compute_score(x1, x2, y1, y2, mack, sard);\n            if (score > best_score) {\n                best_score = score;\n                best_x1 = x1;\n                best_x2 = x2;\n                best_y1 = y1;\n                best_y2 = y2;\n            }\n        }\n    }\n\n    // Ultimate fallback\n    if (best_score == 0) {\n        best_x1 = 0;\n        best_x2 = 1;\n        best_y1 = 0;\n        best_y2 = 1;\n        best_score = 1;\n    }\n\n    // Output as rectangle (4 vertices)\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n#include <limits>\n\nusing namespace std;\n\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference rectangle, -1 for boundary\n};\n\nstruct PlacedRect {\n    int idx; // original index\n    long long x, y, w, h;\n};\n\n// Hybrid packing: tries all possibilities for each rectangle\nvector<Placement> generate_hybrid_packing(const vector<int>& w, const vector<int>& h,\n                                          mt19937& rng, double noise, double skip_threshold) {\n    int n = w.size();\n    vector<Placement> res;\n    vector<PlacedRect> placed;\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        double best_increase = numeric_limits<double>::max();\n        Placement best_placement;\n        PlacedRect best_rect;\n\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            for (char d : {'L', 'U'}) {\n                // Try b = -1 and all placed rectangles\n                vector<int> b_candidates = {-1};\n                for (int j = 0; j < (int)placed.size(); ++j) {\n                    b_candidates.push_back(j); // index in placed vector\n                }\n\n                for (int b_idx : b_candidates) {\n                    long long left, top;\n\n                    if (d == 'L') {\n                        // Determine top from b\n                        if (b_idx == -1) {\n                            top = 0;\n                        } else {\n                            top = placed[b_idx].y + placed[b_idx].h;\n                        }\n                        // Compute left as the maximum right edge of rectangles that overlap vertically\n                        left = 0;\n                        for (const PlacedRect& rect : placed) {\n                            if (top < rect.y + rect.h && top + hc > rect.y) {\n                                left = max(left, rect.x + rect.w);\n                            }\n                        }\n                    } else { // d == 'U'\n                        // Determine left from b\n                        if (b_idx == -1) {\n                            left = 0;\n                        } else {\n                            left = placed[b_idx].x + placed[b_idx].w;\n                        }\n                        // Compute top as the maximum bottom edge of rectangles that overlap horizontally\n                        top = 0;\n                        for (const PlacedRect& rect : placed) {\n                            if (left < rect.x + rect.w && left + wc > rect.x) {\n                                top = max(top, rect.y + rect.h);\n                            }\n                        }\n                    }\n\n                    // Check for overlap (should not happen by construction, but double-check)\n                    bool overlap = false;\n                    for (const PlacedRect& rect : placed) {\n                        if (left < rect.x + rect.w && left + wc > rect.x &&\n                            top < rect.y + rect.h && top + hc > rect.y) {\n                            overlap = true;\n                            break;\n                        }\n                    }\n                    if (overlap) {\n                        continue;\n                    }\n\n                    // Compute new overall width and height\n                    long long new_width = 0, new_height = 0;\n                    for (const PlacedRect& rect : placed) {\n                        new_width = max(new_width, rect.x + rect.w);\n                        new_height = max(new_height, rect.y + rect.h);\n                    }\n                    new_width = max(new_width, left + wc);\n                    new_height = max(new_height, top + hc);\n\n                    // Current overall width and height\n                    long long cur_width = 0, cur_height = 0;\n                    if (!placed.empty()) {\n                        for (const PlacedRect& rect : placed) {\n                            cur_width = max(cur_width, rect.x + rect.w);\n                            cur_height = max(cur_height, rect.y + rect.h);\n                        }\n                    }\n\n                    double increase = (new_width - cur_width) + (new_height - cur_height) + dist(rng);\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        int actual_b = (b_idx == -1) ? -1 : placed[b_idx].idx;\n                        best_placement = {i, r, d, actual_b};\n                        best_rect = {i, left, top, wc, hc};\n                    }\n                }\n            }\n        }\n\n        // If no valid placement found, skip the rectangle\n        if (best_increase == numeric_limits<double>::max()) {\n            continue;\n        }\n\n        // Check skipping condition\n        long long penalty = w[i] + h[i];\n        if (best_increase > skip_threshold * penalty) {\n            continue;\n        }\n\n        // Place the rectangle\n        res.push_back(best_placement);\n        placed.push_back(best_rect);\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<long long> sum_w(N), sum_h(N);\n    vector<int> cnt(N, 1); // start with the given noisy measurements\n    for (int i = 0; i < N; ++i) {\n        int wp, hp;\n        cin >> wp >> hp;\n        sum_w[i] = wp;\n        sum_h[i] = hp;\n    }\n\n    // Estimate true sizes from the given data (already one sample)\n    vector<int> est_w(N), est_h(N);\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n    }\n\n    // Order rectangles by estimated area to prioritize measurement\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return (long long)est_w[a] * est_h[a] > (long long)est_w[b] * est_h[b];\n    });\n\n    // Number of packing attempts: 30, but ensure at least 5 measurement turns if possible\n    const int PACK_TURNS = min(30, max(1, T - 5));\n    int M = T - PACK_TURNS; // number of measurement turns\n\n    // ---------- Measurement phase ----------\n    for (int t = 0; t < M; ++t) {\n        int idx = order[t % N]; // cycle through rectangles, most important first\n        cout << \"1\\n\";\n        cout << idx << \" 0 U -1\\n\";\n        cout << flush;\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Update measurements\n        sum_w[idx] += Wp;\n        sum_h[idx] += Hp;\n        cnt[idx]++;\n        // Update estimates on the fly\n        est_w[idx] = (sum_w[idx] + cnt[idx]/2) / cnt[idx];\n        est_h[idx] = (sum_h[idx] + cnt[idx]/2) / cnt[idx];\n    }\n\n    // Recompute all estimates after measurement phase\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n        if (est_w[i] < 1) est_w[i] = 1;\n        if (est_h[i] < 1) est_h[i] = 1;\n    }\n\n    // ---------- Packing phase ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    const double noise = 0.1;\n    const double skip_threshold = 2.0; // fixed, less aggressive\n\n    for (int t = M; t < T; ++t) {\n        vector<Placement> placements = generate_hybrid_packing(est_w, est_h, rng, noise, skip_threshold);\n\n        // Output the placement\n        cout << placements.size() << \"\\n\";\n        for (const auto& pl : placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << \"\\n\";\n        }\n        cout << flush;\n\n        // Read the measurement (ignored for further decisions)\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <tuple>\n#include <numeric>\nusing namespace std;\n\n// Enhanced SA parameters\nconst int MAX_ITER = 600000;\nconst double START_TEMP = 60.0;\nconst double COOLING = 0.99998;\nconst double START_PENALTY = 1.0;\nconst double END_PENALTY = 20000.0;\nconst int RESTART_INTERVAL = 100000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\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    // PROVEN WORKING INITIALIZATION: BFS from low-beauty roots\n    vector<int> depth(N, -1);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });\n\n    for (int v : order) {\n        if (depth[v] != -1) continue;\n        depth[v] = 0;\n        queue<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [u, d] = q.front(); q.pop();\n            if (d == H) continue;\n            for (int w : adj[u]) {\n                if (depth[w] == -1) {\n                    depth[w] = d + 1;\n                    q.emplace(w, d + 1);\n                }\n            }\n        }\n    }\n\n    // Compute initial support and score\n    vector<int> support(N, 0);\n    int unsatisfied_cnt = 0;\n    long long current_score = 0;\n    for (int v = 0; v < N; ++v) {\n        current_score += (long long)depth[v] * A[v];\n        if (depth[v] > 0) {\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v] - 1) {\n                    support[v]++;\n                }\n            }\n            if (support[v] == 0) unsatisfied_cnt++;\n        }\n    }\n\n    // Best feasible solution\n    long long best_score = current_score;\n    vector<int> best_depths = depth;\n    int best_unsatisfied = unsatisfied_cnt;\n\n    // Random number generators\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_vertex(0, N - 1);\n    uniform_int_distribution<int> rand_depth(0, H);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    // SA variables\n    double temp = START_TEMP;\n    double penalty_weight = START_PENALTY;\n    const double penalty_inc = (END_PENALTY - START_PENALTY) / MAX_ITER;\n    int last_improvement = 0;\n\n    // Precompute vertices sorted by beauty for biased selection\n    vector<int> vertices_by_beauty(N);\n    iota(vertices_by_beauty.begin(), vertices_by_beauty.end(), 0);\n    sort(vertices_by_beauty.begin(), vertices_by_beauty.end(), \n         [&](int i, int j) { return A[i] > A[j]; });\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        // Occasionally restart from best with perturbation\n        if (iter - last_improvement > RESTART_INTERVAL && iter > 0) {\n            depth = best_depths;\n            // Recompute support and score\n            fill(support.begin(), support.end(), 0);\n            current_score = 0;\n            unsatisfied_cnt = 0;\n            for (int v = 0; v < N; ++v) {\n                current_score += (long long)depth[v] * A[v];\n                if (depth[v] > 0) {\n                    for (int u : adj[v]) {\n                        if (depth[u] == depth[v] - 1) {\n                            support[v]++;\n                        }\n                    }\n                    if (support[v] == 0) unsatisfied_cnt++;\n                }\n            }\n            // Small perturbation: randomly change a few vertices\n            for (int i = 0; i < 10; ++i) {\n                int v = rand_vertex(rng);\n                int old_d = depth[v];\n                int new_d = rand_depth(rng);\n                if (old_d != new_d) {\n                    depth[v] = new_d;\n                    // Update support for v and neighbors\n                    for (int w : {v}) {\n                        if (depth[w] > 0) {\n                            support[w] = 0;\n                            for (int x : adj[w]) {\n                                if (depth[x] == depth[w] - 1) support[w]++;\n                            }\n                        }\n                    }\n                    for (int u : adj[v]) {\n                        if (depth[u] > 0) {\n                            support[u] = 0;\n                            for (int x : adj[u]) {\n                                if (depth[x] == depth[u] - 1) support[u]++;\n                            }\n                        }\n                    }\n                }\n            }\n            // Recompute score and unsatisfied\n            current_score = 0;\n            unsatisfied_cnt = 0;\n            for (int v = 0; v < N; ++v) {\n                current_score += (long long)depth[v] * A[v];\n                if (depth[v] > 0 && support[v] == 0) unsatisfied_cnt++;\n            }\n            last_improvement = iter;\n        }\n\n        // Choose move type with bias\n        double move_type = rand_real(rng);\n        bool is_swap = false;\n        int v, u, old_d_v, old_d_u, new_d_v, new_d_u;\n        vector<int> affected;\n\n        if (move_type < 0.5) {  // Single vertex depth change (50%)\n            // Bias toward high-beauty vertices\n            if (rand_real(rng) < 0.7) {  // 70% chance to pick high-beauty\n                int idx = rand_vertex(rng) % (N / 10);  // Top 10%\n                v = vertices_by_beauty[idx];\n            } else {\n                v = rand_vertex(rng);\n            }\n            \n            old_d_v = depth[v];\n            \n            // Choose new depth with strong bias toward increasing\n            if (rand_real(rng) < 0.65) {  // 65% chance to try increment\n                if (old_d_v < H) new_d_v = old_d_v + 1;\n                else new_d_v = rand_depth(rng);\n            } else if (rand_real(rng) < 0.8) {  // 15% chance to try decrement\n                if (old_d_v > 0) new_d_v = old_d_v - 1;\n                else new_d_v = rand_depth(rng);\n            } else {  // 20% chance random\n                new_d_v = rand_depth(rng);\n            }\n            \n            if (old_d_v == new_d_v) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            affected = {v};\n            for (int w : adj[v]) affected.push_back(w);\n        } \n        else if (move_type < 0.8) {  // Swap moves (30%)\n            // Bias toward beneficial swaps: high A with low depth swapped with low A with high depth\n            if (rand_real(rng) < 0.6) {  // 60% beneficial swap\n                // Pick high A vertex with relatively low depth\n                int idx1 = rand_vertex(rng) % (N / 5);  // Top 20%\n                v = vertices_by_beauty[idx1];\n                // Pick low A vertex with relatively high depth\n                int idx2 = N - 1 - (rand_vertex(rng) % (N / 5));  // Bottom 20%\n                u = vertices_by_beauty[idx2];\n                if (v == u) u = vertices_by_beauty[(idx2 + 1) % N];\n            } else {  // 40% random swap\n                v = rand_vertex(rng);\n                u = rand_vertex(rng);\n                while (u == v) u = rand_vertex(rng);\n            }\n            \n            old_d_v = depth[v];\n            old_d_u = depth[u];\n            if (old_d_v == old_d_u) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            new_d_v = old_d_u;\n            new_d_u = old_d_v;\n            is_swap = true;\n            \n            affected = {v, u};\n            for (int w : adj[v]) affected.push_back(w);\n            for (int w : adj[u]) {\n                if (find(affected.begin(), affected.end(), w) == affected.end()) {\n                    affected.push_back(w);\n                }\n            }\n        }\n        else {  // Chain extension move (20%)\n            // Try to extend a chain for a high-beauty vertex\n            int idx = rand_vertex(rng) % (N / 3);  // Top 33%\n            v = vertices_by_beauty[idx];\n            old_d_v = depth[v];\n            \n            if (old_d_v >= H) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            // Check if we can extend: need a neighbor with depth = old_d_v\n            bool can_extend = false;\n            for (int u : adj[v]) {\n                if (depth[u] == old_d_v) {\n                    can_extend = true;\n                    break;\n                }\n            }\n            \n            if (!can_extend) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            new_d_v = old_d_v + 1;\n            affected = {v};\n            for (int w : adj[v]) affected.push_back(w);\n        }\n\n        // Compute delta\n        long long delta_score = 0;\n        double delta_penalty = 0.0;\n        int delta_unsatisfied = 0;\n        vector<pair<int, int>> updates; // (vertex, new_support)\n\n        if (is_swap) {\n            delta_score = (long long)(new_d_v - old_d_v) * A[v] + \n                         (long long)(new_d_u - old_d_u) * A[u];\n        } else {\n            delta_score = (long long)(new_d_v - old_d_v) * A[v];\n        }\n\n        for (int w : affected) {\n            int depth_w_old = depth[w];\n            int depth_w_new = depth_w_old;\n            if (w == v) depth_w_new = new_d_v;\n            else if (is_swap && w == u) depth_w_new = new_d_u;\n            \n            bool old_sat = (depth_w_old == 0) || (support[w] > 0);\n\n            // Compute new support for w\n            int new_support_w = 0;\n            for (int x : adj[w]) {\n                int depth_x = depth[x];\n                if (x == v) depth_x = new_d_v;\n                else if (is_swap && x == u) depth_x = new_d_u;\n                \n                if (depth_x == depth_w_new - 1) {\n                    new_support_w++;\n                }\n            }\n            bool new_sat = (depth_w_new == 0) || (new_support_w > 0);\n\n            delta_penalty += penalty_weight * ((new_sat ? 0 : A[w]) - (old_sat ? 0 : A[w]));\n            delta_unsatisfied += (new_sat ? 0 : 1) - (old_sat ? 0 : 1);\n            updates.emplace_back(w, new_support_w);\n        }\n\n        double delta_total = delta_score - delta_penalty;\n\n        if (delta_total > 0.0 || rand_real(rng) < exp(delta_total / temp)) {\n            // Accept move\n            depth[v] = new_d_v;\n            if (is_swap) depth[u] = new_d_u;\n            \n            for (auto& [w, ns] : updates) {\n                support[w] = ns;\n            }\n            current_score += delta_score;\n            unsatisfied_cnt += delta_unsatisfied;\n\n            // Update best feasible solution\n            if (unsatisfied_cnt == 0 && current_score > best_score) {\n                best_score = current_score;\n                best_depths = depth;\n                last_improvement = iter;\n            }\n        }\n\n        temp *= COOLING;\n        penalty_weight += penalty_inc;\n    }\n\n    // Final local search: try to improve best solution by greedy increments\n    depth = best_depths;\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int v : vertices_by_beauty) {  // Process high-beauty first\n            if (depth[v] >= H) continue;\n            // Check if we can increment depth\n            bool has_support = false;\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v]) {\n                    has_support = true;\n                    break;\n                }\n            }\n            if (!has_support) continue;\n            \n            // Temporarily increment\n            int old_d = depth[v];\n            depth[v]++;\n            // Update support for v and neighbors\n            vector<int> to_update = {v};\n            for (int u : adj[v]) to_update.push_back(u);\n            bool feasible = true;\n            for (int w : to_update) {\n                if (depth[w] > 0) {\n                    int sup = 0;\n                    for (int x : adj[w]) {\n                        if (depth[x] == depth[w] - 1) sup++;\n                    }\n                    if (sup == 0) {\n                        feasible = false;\n                        break;\n                    }\n                }\n            }\n            if (feasible) {\n                improved = true;\n                // Update best\n                long long new_score = 0;\n                for (int i = 0; i < N; ++i) new_score += (long long)depth[i] * A[i];\n                if (new_score > best_score) {\n                    best_score = new_score;\n                    best_depths = depth;\n                }\n            } else {\n                depth[v] = old_d;  // Revert\n            }\n        }\n    }\n\n    depth = best_depths;\n\n    // Assign parents\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (depth[v] == 0) continue;\n        for (int u : adj[v]) {\n            if (depth[u] == depth[v] - 1) {\n                parent[v] = u;\n                break;\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nvector<string> simulate_columns_first(vector<string> board) {\n    int N = board.size();\n    vector<string> ops;\n    \n    // Process columns with double shifts\n    for (int j = 0; j < N; ++j) {\n        int top_f = N, bottom_f = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                top_f = min(top_f, i);\n                bottom_f = max(bottom_f, i);\n            }\n        }\n        \n        // Check for oni in top zone\n        bool has_top_oni = false;\n        for (int i = 0; i < top_f; ++i) {\n            if (board[i][j] == 'x') {\n                has_top_oni = true;\n                break;\n            }\n        }\n        \n        // Check for oni in bottom zone\n        bool has_bottom_oni = false;\n        for (int i = bottom_f + 1; i < N; ++i) {\n            if (board[i][j] == 'x') {\n                has_bottom_oni = true;\n                break;\n            }\n        }\n        \n        if (has_top_oni && has_bottom_oni) {\n            // Both zones have oni - choose the order that minimizes operations\n            int cost_up_first = 2 * top_f + 2 * (N - 1 - bottom_f);\n            int cost_down_first = 2 * (N - 1 - bottom_f) + 2 * top_f;\n            // They are equal, so just do top first\n            int t = top_f;\n            for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int i = 0; i < t; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n            \n            int b = N - 1 - bottom_f;\n            for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int i = bottom_f + 1; i < N; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n        } else if (has_top_oni) {\n            int t = top_f;\n            for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int i = 0; i < t; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n        } else if (has_bottom_oni) {\n            int b = N - 1 - bottom_f;\n            for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int i = bottom_f + 1; i < N; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n        }\n    }\n    \n    // Process rows with single shifts\n    for (int i = 0; i < N; ++i) {\n        int left_f = N, right_f = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                left_f = min(left_f, j);\n                right_f = max(right_f, j);\n            }\n        }\n        \n        // Process left zone\n        bool has_left_oni = false;\n        for (int j = 0; j < left_f; ++j) {\n            if (board[i][j] == 'x') {\n                has_left_oni = true;\n                break;\n            }\n        }\n        \n        if (has_left_oni) {\n            int l = left_f;\n            for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n            // Shift row i left by l\n            string new_row(N, '.');\n            for (int j = l; j < N; ++j) {\n                new_row[j - l] = board[i][j];\n            }\n            board[i] = new_row;\n        }\n        \n        // Recompute right_f after left shift\n        right_f = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                right_f = max(right_f, j);\n            }\n        }\n        \n        // Process right zone\n        bool has_right_oni = false;\n        for (int j = right_f + 1; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                has_right_oni = true;\n                break;\n            }\n        }\n        \n        if (has_right_oni) {\n            int r = N - 1 - right_f;\n            for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n            // Shift row i right by r\n            string new_row(N, '.');\n            for (int j = 0; j < N - r; ++j) {\n                new_row[j + r] = board[i][j];\n            }\n            board[i] = new_row;\n        }\n    }\n    \n    return ops;\n}\n\nvector<string> simulate_rows_first(vector<string> board) {\n    int N = board.size();\n    vector<string> ops;\n    \n    // Process rows with double shifts\n    for (int i = 0; i < N; ++i) {\n        int left_f = N, right_f = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                left_f = min(left_f, j);\n                right_f = max(right_f, j);\n            }\n        }\n        \n        bool has_left_oni = false;\n        for (int j = 0; j < left_f; ++j) {\n            if (board[i][j] == 'x') {\n                has_left_oni = true;\n                break;\n            }\n        }\n        \n        bool has_right_oni = false;\n        for (int j = right_f + 1; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                has_right_oni = true;\n                break;\n            }\n        }\n        \n        if (has_left_oni && has_right_oni) {\n            int l = left_f;\n            for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n            for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n            for (int j = 0; j < l; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n            \n            int r = N - 1 - right_f;\n            for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n            for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n            for (int j = right_f + 1; j < N; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n        } else if (has_left_oni) {\n            int l = left_f;\n            for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n            for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n            for (int j = 0; j < l; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n        } else if (has_right_oni) {\n            int r = N - 1 - right_f;\n            for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n            for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n            for (int j = right_f + 1; j < N; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n        }\n    }\n    \n    // Process columns with single shifts\n    for (int j = 0; j < N; ++j) {\n        int top_f = N, bottom_f = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                top_f = min(top_f, i);\n                bottom_f = max(bottom_f, i);\n            }\n        }\n        \n        // Process top zone\n        bool has_top_oni = false;\n        for (int i = 0; i < top_f; ++i) {\n            if (board[i][j] == 'x') {\n                has_top_oni = true;\n                break;\n            }\n        }\n        \n        if (has_top_oni) {\n            int t = top_f;\n            for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n            // Shift column j up by t\n            for (int i = 0; i < N - t; ++i) {\n                board[i][j] = board[i + t][j];\n            }\n            for (int i = N - t; i < N; ++i) {\n                board[i][j] = '.';\n            }\n        }\n        \n        // Recompute bottom_f after up shift\n        bottom_f = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                bottom_f = max(bottom_f, i);\n            }\n        }\n        \n        // Process bottom zone\n        bool has_bottom_oni = false;\n        for (int i = bottom_f + 1; i < N; ++i) {\n            if (board[i][j] == 'x') {\n                has_bottom_oni = true;\n                break;\n            }\n        }\n        \n        if (has_bottom_oni) {\n            int b = N - 1 - bottom_f;\n            for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n            // Shift column j down by b\n            for (int i = N - 1; i >= b; --i) {\n                board[i][j] = board[i - b][j];\n            }\n            for (int i = 0; i < b; ++i) {\n                board[i][j] = '.';\n            }\n        }\n    }\n    \n    return ops;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    \n    auto ops1 = simulate_columns_first(board);\n    auto ops2 = simulate_rows_first(board);\n    \n    // Choose the shorter sequence\n    if (ops1.size() <= ops2.size()) {\n        for (const string& op : ops1) cout << op << '\\n';\n    } else {\n        for (const string& op : ops2) cout << op << '\\n';\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint best_a[N], best_b[N];\nint best_error;\n\n// Fast simulation\nint simulate(const int a[], const int b[]) {\n    int count[N] = {0};\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int next;\n        if (count[current] & 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\n// Flow-based greedy initialization\nvoid flow_based_init() {\n    // Compute required outflows\n    int out_a[N], out_b[N];\n    for (int i = 0; i < N; i++) {\n        out_a[i] = (T[i] + 1) / 2;  // ceil(T_i/2)\n        out_b[i] = T[i] / 2;        // floor(T_i/2)\n    }\n    \n    // Compute required inflows\n    int in_demand[N];\n    for (int i = 0; i < N; i++) {\n        in_demand[i] = T[i];\n    }\n    in_demand[0]--;  // Subtract the initial visit\n    \n    // Create items: (weight, employee, is_a_edge)\n    vector<tuple<int, int, bool>> items;\n    for (int i = 0; i < N; i++) {\n        items.push_back({out_a[i], i, true});\n        items.push_back({out_b[i], i, false});\n    }\n    \n    // Sort by weight descending\n    sort(items.rbegin(), items.rend());\n    \n    // Initialize assignments\n    fill(a, a + N, -1);\n    fill(b, b + N, -1);\n    \n    // Assign edges to meet inflow demands\n    for (auto& [weight, i, is_a] : items) {\n        // Find employee with highest remaining demand\n        int best_j = -1;\n        int best_demand = -1;\n        for (int j = 0; j < N; j++) {\n            if (in_demand[j] > best_demand) {\n                best_demand = in_demand[j];\n                best_j = j;\n            }\n        }\n        \n        if (best_j == -1) {\n            best_j = 0;  // Fallback\n        }\n        \n        if (is_a) {\n            a[i] = best_j;\n        } else {\n            b[i] = best_j;\n        }\n        \n        // Update demand\n        in_demand[best_j] -= weight;\n        if (in_demand[best_j] < 0) {\n            in_demand[best_j] = 0;\n        }\n    }\n    \n    // Fill any unset edges\n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n}\n\n// Online greedy initialization\nvoid online_greedy_init() {\n    int count[N] = {0};\n    fill(a, a + N, -1);\n    fill(b, b + N, -1);\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int next;\n        if (count[current] & 1) {\n            if (a[current] == -1) {\n                int best_j = 0;\n                int best_val = T[0] - count[0];\n                for (int j = 1; j < N; j++) {\n                    int val = T[j] - count[j];\n                    if (val > best_val) {\n                        best_val = val;\n                        best_j = j;\n                    }\n                }\n                a[current] = best_j;\n            }\n            next = a[current];\n        } else {\n            if (b[current] == -1) {\n                int best_j = 0;\n                int best_val = T[0] - count[0];\n                for (int j = 1; j < N; j++) {\n                    int val = T[j] - count[j];\n                    if (val > best_val) {\n                        best_val = val;\n                        best_j = j;\n                    }\n                }\n                b[current] = best_j;\n            }\n            next = b[current];\n        }\n        current = next;\n    }\n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n}\n\nvoid solve() {\n    // Try multiple initializations and keep the best\n    int temp_a[N], temp_b[N];\n    int errors[2];\n    \n    // Flow-based initialization\n    flow_based_init();\n    errors[0] = simulate(a, b);\n    memcpy(temp_a, a, sizeof(a));\n    memcpy(temp_b, b, sizeof(b));\n    \n    // Online greedy initialization\n    online_greedy_init();\n    errors[1] = simulate(a, b);\n    \n    // Choose the better one\n    int best_init_idx = (errors[0] < errors[1]) ? 0 : 1;\n    if (best_init_idx == 0) {\n        memcpy(a, temp_a, sizeof(a));\n        memcpy(b, temp_b, sizeof(b));\n    }\n    \n    int current_error = simulate(a, b);\n    best_error = current_error;\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis_emp(0, N - 1);\n    uniform_real_distribution<> dis_real(0, 1);\n    \n    double temperature = 30.0;\n    double cooling_rate = 0.993;\n    int max_iter = 450;\n    auto start_time = chrono::steady_clock::now();\n    \n    for (int iter = 0; iter < max_iter; iter++) {\n        // Time check\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 1.8) break;\n        \n        int new_a[N], new_b[N];\n        memcpy(new_a, a, sizeof(a));\n        memcpy(new_b, b, sizeof(b));\n        \n        // Adaptive move selection\n        double move_type = dis_real(gen);\n        \n        // Focus more on swaps as we progress\n        if (iter < max_iter / 3) {\n            // Early: more single changes for exploration\n            if (move_type < 0.8) {\n                int i = dis_emp(gen);\n                int which = dis_real(gen) < 0.5 ? 0 : 1;\n                int new_val = dis_emp(gen);\n                if (which == 0) {\n                    new_a[i] = new_val;\n                } else {\n                    new_b[i] = new_val;\n                }\n            } else {\n                // Swap\n                int i = dis_emp(gen);\n                int j = dis_emp(gen);\n                while (i == j) j = dis_emp(gen);\n                int swap_type = dis_real(gen) * 4;\n                if (swap_type == 0) swap(new_a[i], new_a[j]);\n                else if (swap_type == 1) swap(new_b[i], new_b[j]);\n                else if (swap_type == 2) swap(new_a[i], new_b[j]);\n                else swap(new_b[i], new_a[j]);\n            }\n        } else if (iter < 2 * max_iter / 3) {\n            // Middle: balanced\n            if (move_type < 0.5) {\n                int i = dis_emp(gen);\n                int which = dis_real(gen) < 0.5 ? 0 : 1;\n                int new_val = dis_emp(gen);\n                if (which == 0) {\n                    new_a[i] = new_val;\n                } else {\n                    new_b[i] = new_val;\n                }\n            } else if (move_type < 0.9) {\n                // Swap\n                int i = dis_emp(gen);\n                int j = dis_emp(gen);\n                while (i == j) j = dis_emp(gen);\n                int swap_type = dis_real(gen) * 4;\n                if (swap_type == 0) swap(new_a[i], new_a[j]);\n                else if (swap_type == 1) swap(new_b[i], new_b[j]);\n                else if (swap_type == 2) swap(new_a[i], new_b[j]);\n                else swap(new_b[i], new_a[j]);\n            } else {\n                // Change both\n                int i = dis_emp(gen);\n                new_a[i] = dis_emp(gen);\n                new_b[i] = dis_emp(gen);\n            }\n        } else {\n            // Late: mostly swaps for fine-tuning\n            if (move_type < 0.2) {\n                int i = dis_emp(gen);\n                int which = dis_real(gen) < 0.5 ? 0 : 1;\n                int new_val = dis_emp(gen);\n                if (which == 0) {\n                    new_a[i] = new_val;\n                } else {\n                    new_b[i] = new_val;\n                }\n            } else if (move_type < 0.95) {\n                // Swap\n                int i = dis_emp(gen);\n                int j = dis_emp(gen);\n                while (i == j) j = dis_emp(gen);\n                int swap_type = dis_real(gen) * 4;\n                if (swap_type == 0) swap(new_a[i], new_a[j]);\n                else if (swap_type == 1) swap(new_b[i], new_b[j]);\n                else if (swap_type == 2) swap(new_a[i], new_b[j]);\n                else swap(new_b[i], new_a[j]);\n            } else {\n                // Change both\n                int i = dis_emp(gen);\n                new_a[i] = dis_emp(gen);\n                new_b[i] = dis_emp(gen);\n            }\n        }\n        \n        int new_error = simulate(new_a, new_b);\n        int diff = new_error - current_error;\n        \n        // Acceptance criterion\n        if (diff < 0 || dis_real(gen) < exp(-diff / temperature)) {\n            memcpy(a, new_a, sizeof(a));\n            memcpy(b, new_b, sizeof(b));\n            current_error = new_error;\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, new_a, sizeof(new_a));\n                memcpy(best_b, new_b, sizeof(new_b));\n            }\n        }\n        \n        temperature *= cooling_rate;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int n, l;\n    cin >> n >> l;\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n#include <functional>\n#include <set>\n#include <queue>\n#include <map>\n#include <random>\n\nusing namespace std;\n\n// Query function with limit checking\nvector<pair<int, int>> query(const vector<int>& cities, int &queries_used, int Q) {\n    if (queries_used >= Q) {\n        return {};\n    }\n    \n    int l = cities.size();\n    cout << \"? \" << l;\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    queries_used++;\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(min(a, b), max(a, b));\n    }\n    return edges;\n}\n\n// Calculate expected squared distance between two uniform distributions in rectangles\ndouble expected_squared_distance(int i, int j, const vector<int>& lx, const vector<int>& rx, \n                                 const vector<int>& ly, const vector<int>& ry) {\n    double center_x_i = (lx[i] + rx[i]) / 2.0;\n    double center_y_i = (ly[i] + ry[i]) / 2.0;\n    double center_x_j = (lx[j] + rx[j]) / 2.0;\n    double center_y_j = (ly[j] + ry[j]) / 2.0;\n    \n    double width_i = rx[i] - lx[i];\n    double height_i = ry[i] - ly[i];\n    double width_j = rx[j] - lx[j];\n    double height_j = ry[j] - ry[j];\n    \n    // Expected squared distance = squared distance between centers + variances\n    double dx_center = center_x_i - center_x_j;\n    double dy_center = center_y_i - center_y_j;\n    double variance_x = (width_i * width_i + width_j * width_j) / 12.0;\n    double variance_y = (height_i * height_i + height_j * height_j) / 12.0;\n    \n    return dx_center * dx_center + dy_center * dy_center + variance_x + variance_y;\n}\n\n// Calculate expected distance (approximation)\ndouble expected_distance(int i, int j, const vector<int>& lx, const vector<int>& rx, \n                         const vector<int>& ly, const vector<int>& ry) {\n    return sqrt(expected_squared_distance(i, j, lx, rx, ly, ry));\n}\n\n// Disjoint Set Union for Kruskal's algorithm\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Sort groups by size (largest first)\n    vector<int> group_order(M);\n    for (int i = 0; i < M; i++) group_order[i] = i;\n    sort(group_order.begin(), group_order.end(), [&](int i, int j) {\n        return G[i] > G[j];\n    });\n    \n    // Compute all centers\n    vector<pair<double, double>> centers(N);\n    for (int i = 0; i < N; i++) {\n        centers[i].first = (lx[i] + rx[i]) / 2.0;\n        centers[i].second = (ly[i] + ry[i]) / 2.0;\n    }\n    \n    // Initialize groups using a more sophisticated clustering\n    vector<vector<int>> groups(M);\n    vector<bool> assigned(N, false);\n    \n    // Use a priority queue to build groups by adding the closest city to the current group\n    for (int gi : group_order) {\n        int needed = G[gi];\n        \n        // Find the best seed: city with smallest rectangle (most precise)\n        int best_seed = -1;\n        double best_area = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double area = (rx[i] - lx[i]) * (ry[i] - ly[i]);\n                if (area < best_area) {\n                    best_area = area;\n                    best_seed = i;\n                }\n            }\n        }\n        \n        if (best_seed == -1) continue;\n        \n        // Start group with seed\n        groups[gi].push_back(best_seed);\n        assigned[best_seed] = true;\n        needed--;\n        \n        // Use a priority queue to add cities that minimize the maximum distance to the group\n        while (needed > 0) {\n            int best_city = -1;\n            double best_score = 1e18;\n            \n            for (int i = 0; i < N; i++) {\n                if (assigned[i]) continue;\n                \n                // Calculate the maximum distance to any city in the group\n                double max_dist = 0;\n                for (int c : groups[gi]) {\n                    double dist = expected_distance(i, c, lx, rx, ly, ry);\n                    max_dist = max(max_dist, dist);\n                }\n                \n                // Also consider the area of the rectangle (smaller is better)\n                double area = (rx[i] - lx[i]) * (ry[i] - ly[i]);\n                double score = max_dist + area * 1e-6;  // Small weight for area\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_city = i;\n                }\n            }\n            \n            if (best_city == -1) break;\n            \n            groups[gi].push_back(best_city);\n            assigned[best_city] = true;\n            needed--;\n        }\n    }\n    \n    // Store all discovered edges with their heuristic scores\n    vector<vector<pair<double, pair<int, int>>>> group_edges_with_score(M);\n    int queries_used = 0;\n    \n    // Process each group with efficient query strategy\n    for (int g = 0; g < M && queries_used < Q; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        set<pair<int, int>> discovered_edges;\n        \n        // Strategy 1: Query entire group if small enough\n        if (sz <= L && queries_used < Q) {\n            auto edges = query(groups[g], queries_used, Q);\n            for (auto& e : edges) {\n                if (discovered_edges.find(e) == discovered_edges.end()) {\n                    double dist = expected_distance(e.first, e.second, lx, rx, ly, ry);\n                    group_edges_with_score[g].push_back({dist, e});\n                    discovered_edges.insert(e);\n                }\n            }\n        }\n        \n        // Strategy 2: Use overlapping windows with multiple sorting strategies\n        if (sz > L && queries_used < Q) {\n            // Try different sorting strategies to discover diverse edges\n            vector<function<bool(int, int)>> sort_functions = {\n                [&](int i, int j) { return centers[i].first < centers[j].first; },\n                [&](int i, int j) { return centers[i].second < centers[j].second; },\n                [&](int i, int j) { \n                    return (centers[i].first + centers[i].second) < \n                           (centers[j].first + centers[j].second);\n                }\n            };\n            \n            for (auto& sort_func : sort_functions) {\n                if (queries_used >= Q) break;\n                \n                vector<int> sorted_group = groups[g];\n                sort(sorted_group.begin(), sorted_group.end(), sort_func);\n                \n                int start = 0;\n                while (start < sz - 1 && queries_used < Q) {\n                    int end = min(start + L, sz);\n                    vector<int> window(sorted_group.begin() + start, sorted_group.begin() + end);\n                    \n                    if (window.size() >= 2) {\n                        auto edges = query(window, queries_used, Q);\n                        for (auto& e : edges) {\n                            if (discovered_edges.find(e) == discovered_edges.end()) {\n                                double dist = expected_distance(e.first, e.second, lx, rx, ly, ry);\n                                group_edges_with_score[g].push_back({dist, e});\n                                discovered_edges.insert(e);\n                            }\n                        }\n                    }\n                    \n                    // Move forward by L/2 for more overlap\n                    start = start + max(1, L / 2);\n                }\n            }\n        }\n        \n        // Strategy 3: For large groups, use random subsets\n        if (sz > 2 * L && queries_used < Q) {\n            random_device rd;\n            mt19937 gen(rd());\n            \n            int attempts = min(2, (Q - queries_used));\n            for (int attempt = 0; attempt < attempts && queries_used < Q; attempt++) {\n                shuffle(groups[g].begin(), groups[g].end(), gen);\n                vector<int> subset(groups[g].begin(), groups[g].begin() + min(L, sz));\n                \n                auto edges = query(subset, queries_used, Q);\n                for (auto& e : edges) {\n                    if (discovered_edges.find(e) == discovered_edges.end()) {\n                        double dist = expected_distance(e.first, e.second, lx, rx, ly, ry);\n                        group_edges_with_score[g].push_back({dist, e});\n                        discovered_edges.insert(e);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        // Output cities in group\n        for (int j = 0; j < (int)groups[g].size(); j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[g][j];\n        }\n        cout << endl;\n        \n        // Build MST using Kruskal's algorithm\n        vector<pair<double, pair<int, int>>> edges_for_kruskal = group_edges_with_score[g];\n        \n        // Sort by expected distance (heuristic for true distance)\n        sort(edges_for_kruskal.begin(), edges_for_kruskal.end());\n        \n        // Create mapping from global city index to local index in group\n        map<int, int> global_to_local;\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            global_to_local[groups[g][i]] = i;\n        }\n        \n        // Run Kruskal's algorithm\n        DSU dsu(groups[g].size());\n        vector<pair<int, int>> mst_edges;\n        \n        for (auto& we : edges_for_kruskal) {\n            auto& e = we.second;\n            int u = global_to_local[e.first];\n            int v = global_to_local[e.second];\n            if (dsu.unite(u, v)) {\n                mst_edges.push_back(e);\n                if (mst_edges.size() == groups[g].size() - 1) break;\n            }\n        }\n        \n        // If we don't have enough edges, add all possible edges with expected distances\n        if (mst_edges.size() < groups[g].size() - 1) {\n            // Generate all possible edges with expected distances\n            vector<pair<double, pair<int, int>>> all_edges;\n            for (int i = 0; i < groups[g].size(); i++) {\n                for (int j = i + 1; j < groups[g].size(); j++) {\n                    int city_i = groups[g][i];\n                    int city_j = groups[g][j];\n                    double dist = expected_distance(city_i, city_j, lx, rx, ly, ry);\n                    all_edges.push_back({dist, {city_i, city_j}});\n                }\n            }\n            \n            // Sort by expected distance and add to MST\n            sort(all_edges.begin(), all_edges.end());\n            for (auto& we : all_edges) {\n                auto& e = we.second;\n                // Check if edge already exists in mst_edges\n                bool exists = false;\n                for (auto& edge : mst_edges) {\n                    if (edge == e) {\n                        exists = true;\n                        break;\n                    }\n                }\n                if (!exists) {\n                    int u = global_to_local[e.first];\n                    int v = global_to_local[e.second];\n                    if (dsu.unite(u, v)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == groups[g].size() - 1) break;\n                    }\n                }\n            }\n        }\n        \n        // Output edges\n        for (auto& e : mst_edges) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    vector<string> actions;\n    int cx = targets[0].first, cy = targets[0].second;\n    const int MAX_ACTIONS = 800;\n\n    for (int k = 1; k < M; ++k) {\n        int tx = targets[k].first, ty = targets[k].second;\n        while ((cx != tx || cy != ty) && actions.size() < MAX_ACTIONS) {\n            if (cx == tx) {\n                if (ty == 0 && cy > 0) {\n                    actions.push_back(\"S L\");\n                    cy = 0;\n                } else if (ty == N - 1 && cy < N - 1) {\n                    actions.push_back(\"S R\");\n                    cy = N - 1;\n                } else {\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            } else if (cy == ty) {\n                if (tx == 0 && cx > 0) {\n                    actions.push_back(\"S U\");\n                    cx = 0;\n                } else if (tx == N - 1 && cx < N - 1) {\n                    actions.push_back(\"S D\");\n                    cx = N - 1;\n                } else {\n                    if (cx < tx) {\n                        actions.push_back(\"M D\");\n                        cx++;\n                    } else {\n                        actions.push_back(\"M U\");\n                        cx--;\n                    }\n                }\n            } else {\n                if (tx == 0 || tx == N - 1 || ty == 0 || ty == N - 1) {\n                    // Target at boundary: prioritize aligning with the boundary direction\n                    if (ty == 0 || ty == N - 1) {\n                        // Horizontal boundary: move vertically to align row first\n                        if (cx < tx) {\n                            actions.push_back(\"M D\");\n                            cx++;\n                        } else if (cx > tx) {\n                            actions.push_back(\"M U\");\n                            cx--;\n                        }\n                    } else {\n                        // Vertical boundary: move horizontally to align column first\n                        if (cy < ty) {\n                            actions.push_back(\"M R\");\n                            cy++;\n                        } else if (cy > ty) {\n                            actions.push_back(\"M L\");\n                            cy--;\n                        }\n                    }\n                } else {\n                    // Target not at boundary: move in the direction of larger difference\n                    if (abs(cx - tx) >= abs(cy - ty)) {\n                        if (cx < tx) {\n                            actions.push_back(\"M D\");\n                            cx++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            cx--;\n                        }\n                    } else {\n                        if (cy < ty) {\n                            actions.push_back(\"M R\");\n                            cy++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            cy--;\n                        }\n                    }\n                }\n            }\n        }\n        if (actions.size() >= MAX_ACTIONS) {\n            break;\n        }\n    }\n\n    // Output actions\n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n\n    return 0;\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <functional>\n\nusing namespace std;\n\nstruct Company {\n    int x, y, r;\n};\n\nstruct Rect {\n    int a, b, c, d;\n};\n\nvector<Company> comps;\nvector<Rect> rects;\nint n;\n\nbool overlaps(const Rect& r1, const Rect& r2) {\n    return !(r1.c <= r2.a || r2.c <= r1.a || r1.d <= r2.b || r2.d <= r1.b);\n}\n\ndouble company_score(int i, const Rect& rect) {\n    int area = (rect.c - rect.a) * (rect.d - rect.b);\n    int r = comps[i].r;\n    if (area == 0) return 0;\n    double t = min(r, area) / (double)max(r, area);\n    return 1 - (1 - t) * (1 - t);\n}\n\nbool contains_point(int i, const Rect& rect) {\n    return rect.a <= comps[i].x && rect.c >= comps[i].x + 1 &&\n           rect.b <= comps[i].y && rect.d >= comps[i].y + 1;\n}\n\ndouble total_score() {\n    double sum = 0;\n    for (int i = 0; i < n; ++i) {\n        sum += company_score(i, rects[i]);\n    }\n    return sum;\n}\n\nvoid simulated_annealing() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    uniform_int_distribution<int> rect_dist(0, n - 1);\n    \n    double current_total = total_score();\n    vector<Rect> best_rects = rects;\n    double best_total = current_total;\n    \n    double temperature = 2.0;  // Increased initial temperature\n    double cooling_rate = 0.99998;\n    int max_iter = 800000;\n    int step = 30;\n    \n    for (int iter = 0; iter < max_iter; ++iter) {\n        if (temperature < 1e-6) break;\n        \n        int i = rect_dist(gen);\n        Rect old_rect = rects[i];\n        Rect new_rect = old_rect;\n        \n        // Choose a move type (0-4: single side moves, 5: scaling)\n        uniform_int_distribution<int> move_dist(0, 5);\n        int move_type = move_dist(gen);\n        \n        if (move_type == 0) {\n            // Move left side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.a = max(0, old_rect.a + delta);\n            new_rect.a = min(new_rect.a, comps[i].x);\n            new_rect.a = min(new_rect.a, old_rect.c - 1);\n        } else if (move_type == 1) {\n            // Move right side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.c = min(10000, old_rect.c + delta);\n            new_rect.c = max(new_rect.c, comps[i].x + 1);\n            new_rect.c = max(new_rect.c, old_rect.a + 1);\n        } else if (move_type == 2) {\n            // Move bottom side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.b = max(0, old_rect.b + delta);\n            new_rect.b = min(new_rect.b, comps[i].y);\n            new_rect.b = min(new_rect.b, old_rect.d - 1);\n        } else if (move_type == 3) {\n            // Move top side\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int delta = delta_dist(gen);\n            new_rect.d = min(10000, old_rect.d + delta);\n            new_rect.d = max(new_rect.d, comps[i].y + 1);\n            new_rect.d = max(new_rect.d, old_rect.b + 1);\n        } else if (move_type == 4) {\n            // Shift entire rectangle\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int dx = delta_dist(gen);\n            int dy = delta_dist(gen);\n            new_rect.a = max(0, min(10000, old_rect.a + dx));\n            new_rect.c = max(0, min(10000, old_rect.c + dx));\n            new_rect.b = max(0, min(10000, old_rect.b + dy));\n            new_rect.d = max(0, min(10000, old_rect.d + dy));\n            \n            if (new_rect.a > comps[i].x) new_rect.a = comps[i].x;\n            if (new_rect.c < comps[i].x + 1) new_rect.c = comps[i].x + 1;\n            if (new_rect.b > comps[i].y) new_rect.b = comps[i].y;\n            if (new_rect.d < comps[i].y + 1) new_rect.d = comps[i].y + 1;\n            \n            if (new_rect.a >= new_rect.c) {\n                if (new_rect.a == comps[i].x) {\n                    new_rect.c = new_rect.a + 1;\n                } else {\n                    new_rect.a = new_rect.c - 1;\n                }\n            }\n            if (new_rect.b >= new_rect.d) {\n                if (new_rect.b == comps[i].y) {\n                    new_rect.d = new_rect.b + 1;\n                } else {\n                    new_rect.b = new_rect.d - 1;\n                }\n            }\n        } else {\n            // Scale rectangle: move left/right by dw, bottom/top by dh\n            uniform_int_distribution<int> delta_dist(-step, step);\n            int dw = delta_dist(gen);\n            int dh = delta_dist(gen);\n            \n            new_rect.a = max(0, old_rect.a - dw);\n            new_rect.c = min(10000, old_rect.c + dw);\n            new_rect.b = max(0, old_rect.b - dh);\n            new_rect.d = min(10000, old_rect.d + dh);\n            \n            // Ensure point containment\n            if (new_rect.a > comps[i].x) new_rect.a = comps[i].x;\n            if (new_rect.c < comps[i].x + 1) new_rect.c = comps[i].x + 1;\n            if (new_rect.b > comps[i].y) new_rect.b = comps[i].y;\n            if (new_rect.d < comps[i].y + 1) new_rect.d = comps[i].y + 1;\n            \n            if (new_rect.a >= new_rect.c) {\n                if (new_rect.a == comps[i].x) {\n                    new_rect.c = new_rect.a + 1;\n                } else {\n                    new_rect.a = new_rect.c - 1;\n                }\n            }\n            if (new_rect.b >= new_rect.d) {\n                if (new_rect.b == comps[i].y) {\n                    new_rect.d = new_rect.b + 1;\n                } else {\n                    new_rect.b = new_rect.d - 1;\n                }\n            }\n        }\n        \n        // Check validity\n        if (new_rect.a >= new_rect.c || new_rect.b >= new_rect.d) continue;\n        if (!contains_point(i, new_rect)) continue;\n        \n        // Check overlaps\n        bool overlap = false;\n        for (int j = 0; j < n; ++j) {\n            if (i == j) continue;\n            if (overlaps(new_rect, rects[j])) {\n                overlap = true;\n                break;\n            }\n        }\n        if (overlap) continue;\n        \n        double old_score = company_score(i, old_rect);\n        double new_score = company_score(i, new_rect);\n        double delta_score = new_score - old_score;\n        \n        if (delta_score > 0 || prob_dist(gen) < exp(delta_score / temperature)) {\n            rects[i] = new_rect;\n            current_total += delta_score;\n            \n            if (current_total > best_total) {\n                best_total = current_total;\n                best_rects = rects;\n            }\n        }\n        \n        temperature *= cooling_rate;\n        \n        if (iter % 2000 == 0 && step > 1) {\n            step = max(1, step - 1);\n        }\n    }\n    \n    rects = best_rects;\n}\n\nvoid rec(vector<int>& idx, int x_min, int x_max, int y_min, int y_max) {\n    if (idx.empty()) return;\n    if (idx.size() == 1) {\n        int i = idx[0];\n        int W = x_max - x_min;\n        int H = y_max - y_min;\n        int r = comps[i].r;\n        int best_w = 1, best_h = 1;\n        int best_diff = abs(1 - r);\n        for (int w = 1; w <= W; ++w) {\n            int h1 = max(1, min(H, (int)(r / w)));\n            int h2 = max(1, min(H, (int)ceil((double)r / w)));\n            int area1 = w * h1;\n            int diff1 = abs(area1 - r);\n            if (diff1 < best_diff) {\n                best_diff = diff1;\n                best_w = w;\n                best_h = h1;\n            }\n            int area2 = w * h2;\n            int diff2 = abs(area2 - r);\n            if (diff2 < best_diff) {\n                best_diff = diff2;\n                best_w = w;\n                best_h = h2;\n            }\n        }\n        int a = max(x_min, comps[i].x - (best_w - 1));\n        a = min(a, x_max - best_w);\n        int b = max(y_min, comps[i].y - (best_h - 1));\n        b = min(b, y_max - best_h);\n        int c = a + best_w;\n        int d = b + best_h;\n        rects[i] = {a, b, c, d};\n        return;\n    }\n\n    long long total_r = 0;\n    for (int i : idx) total_r += comps[i].r;\n\n    double best_diff = 1e18;\n    int best_dir = -1;\n    int best_c = -1;\n\n    // Try vertical split\n    vector<int> sorted_x = idx;\n    sort(sorted_x.begin(), sorted_x.end(), [&](int i, int j) { return comps[i].x < comps[j].x; });\n    if (comps[sorted_x.front()].x != comps[sorted_x.back()].x) {\n        vector<long long> prefix_x(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_x.size(); ++j) {\n            prefix_x[j + 1] = prefix_x[j] + comps[sorted_x[j]].r;\n        }\n        for (int p = 1; p < sorted_x.size(); ++p) {\n            long long left_sum = prefix_x[p];\n            double desired_width = (left_sum / (double)total_r) * (x_max - x_min);\n            double ideal_c = x_min + desired_width;\n            int c_min = comps[sorted_x[p - 1]].x + 1;\n            int c_max = comps[sorted_x[p]].x;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_width = c - x_min;\n            double diff = fabs(actual_width - desired_width);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 0;\n                best_c = c;\n            }\n        }\n    }\n\n    // Try horizontal split\n    vector<int> sorted_y = idx;\n    sort(sorted_y.begin(), sorted_y.end(), [&](int i, int j) { return comps[i].y < comps[j].y; });\n    if (comps[sorted_y.front()].y != comps[sorted_y.back()].y) {\n        vector<long long> prefix_y(idx.size() + 1, 0);\n        for (int j = 0; j < sorted_y.size(); ++j) {\n            prefix_y[j + 1] = prefix_y[j] + comps[sorted_y[j]].r;\n        }\n        for (int p = 1; p < sorted_y.size(); ++p) {\n            long long left_sum = prefix_y[p];\n            double desired_height = (left_sum / (double)total_r) * (y_max - y_min);\n            double ideal_c = y_min + desired_height;\n            int c_min = comps[sorted_y[p - 1]].y + 1;\n            int c_max = comps[sorted_y[p]].y;\n            if (c_min > c_max) continue;\n            int c = (int)round(ideal_c);\n            c = max(c_min, min(c, c_max));\n            double actual_height = c - y_min;\n            double diff = fabs(actual_height - desired_height);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_dir = 1;\n                best_c = c;\n            }\n        }\n    }\n\n    if (best_dir == 0) {\n        vector<int> left_idx, right_idx;\n        for (int i : idx) {\n            if (comps[i].x < best_c) left_idx.push_back(i);\n            else right_idx.push_back(i);\n        }\n        rec(left_idx, x_min, best_c, y_min, y_max);\n        rec(right_idx, best_c, x_max, y_min, y_max);\n    } else {\n        vector<int> bottom_idx, top_idx;\n        for (int i : idx) {\n            if (comps[i].y < best_c) bottom_idx.push_back(i);\n            else top_idx.push_back(i);\n        }\n        rec(bottom_idx, x_min, x_max, y_min, best_c);\n        rec(top_idx, x_min, x_max, best_c, y_max);\n    }\n}\n\nvoid compute_expansions(int i, int& L_max, int& R_max, int& D_max, int& U_max) {\n    int a = rects[i].a, b = rects[i].b, c = rects[i].c, d = rects[i].d;\n    L_max = a;\n    R_max = 10000 - c;\n    D_max = b;\n    U_max = 10000 - d;\n\n    for (int j = 0; j < rects.size(); ++j) {\n        if (i == j) continue;\n        int a2 = rects[j].a, b2 = rects[j].b, c2 = rects[j].c, d2 = rects[j].d;\n        if (!(d <= b2 || d2 <= b)) {\n            if (c2 <= a) {\n                L_max = min(L_max, a - c2);\n            }\n            if (a2 >= c) {\n                R_max = min(R_max, a2 - c);\n            }\n        }\n        if (!(c <= a2 || c2 <= a)) {\n            if (d2 <= b) {\n                D_max = min(D_max, b - d2);\n            }\n            if (b2 >= d) {\n                U_max = min(U_max, b2 - d);\n            }\n        }\n    }\n    L_max = max(0, L_max);\n    R_max = max(0, R_max);\n    D_max = max(0, D_max);\n    U_max = max(0, U_max);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> n;\n    comps.resize(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> comps[i].x >> comps[i].y >> comps[i].r;\n    }\n\n    rects.resize(n);\n    vector<int> all_idx(n);\n    for (int i = 0; i < n; ++i) all_idx[i] = i;\n    rec(all_idx, 0, 10000, 0, 10000);\n\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 g(seed);\n    \n    for (int pass = 0; pass < 50; ++pass) {\n        vector<pair<int, int>> deficit_idx;\n        for (int i = 0; i < n; ++i) {\n            int w = rects[i].c - rects[i].a;\n            int h = rects[i].d - rects[i].b;\n            int s = w * h;\n            int deficit = abs(s - comps[i].r);\n            deficit_idx.emplace_back(deficit, i);\n        }\n        sort(deficit_idx.begin(), deficit_idx.end(), greater<pair<int, int>>());\n        \n        bool changed = false;\n        for (auto& p : deficit_idx) {\n            int i = p.second;\n            int w = rects[i].c - rects[i].a;\n            int h = rects[i].d - rects[i].b;\n            int s = w * h;\n            int r = comps[i].r;\n            int x = comps[i].x, y = comps[i].y;\n            \n            if (s < r) {\n                // Try to expand\n                int L_max, R_max, D_max, U_max;\n                compute_expansions(i, L_max, R_max, D_max, U_max);\n                int w_max = w + L_max + R_max;\n                int h_max = h + D_max + U_max;\n                int best_w = w, best_h = h;\n                int best_diff = abs(s - r);\n                \n                int w_ideal = max(1, (int)sqrt(r));\n                // Dynamic search range based on deficit\n                int deficit = r - s;\n                int search_range = min(500, max(300, deficit / 1000));\n                int w_start = max(w, w_ideal - search_range);\n                int w_end = min(w_max, w_ideal + search_range);\n                if (w_start > w_end) {\n                    w_start = w;\n                    w_end = w_max;\n                }\n                \n                for (int w2 = w_start; w2 <= w_end; ++w2) {\n                    double h_ideal = (double)r / w2;\n                    int h1 = max(h, min(h_max, (int)floor(h_ideal)));\n                    int h2 = max(h, min(h_max, (int)ceil(h_ideal)));\n                    int area1 = w2 * h1;\n                    int diff1 = abs(area1 - r);\n                    if (diff1 < best_diff) {\n                        best_diff = diff1;\n                        best_w = w2;\n                        best_h = h1;\n                    }\n                    int area2 = w2 * h2;\n                    int diff2 = abs(area2 - r);\n                    if (diff2 < best_diff) {\n                        best_diff = diff2;\n                        best_w = w2;\n                        best_h = h2;\n                    }\n                }\n                \n                if (best_w == w && best_h == h) continue;\n                \n                int need_w = best_w - w;\n                int need_h = best_h - h;\n                int L = min(need_w, L_max);\n                int R = need_w - L;\n                if (R > R_max) {\n                    R = R_max;\n                    L = need_w - R;\n                }\n                int D = min(need_h, D_max);\n                int U = need_h - D;\n                if (U > U_max) {\n                    U = U_max;\n                    D = need_h - U;\n                }\n                \n                Rect candidate = {rects[i].a - L, rects[i].b - D, rects[i].c + R, rects[i].d + U};\n                bool overlap = false;\n                for (int j = 0; j < n; ++j) {\n                    if (i == j) continue;\n                    if (overlaps(candidate, rects[j])) {\n                        overlap = true;\n                        break;\n                    }\n                }\n                if (overlap) continue;\n                \n                if (candidate.a <= x && candidate.c >= x + 1 && \n                    candidate.b <= y && candidate.d >= y + 1) {\n                    rects[i] = candidate;\n                    changed = true;\n                }\n            } else if (s > r) {\n                // Try to shrink\n                int L_shrink = x - rects[i].a;\n                int R_shrink = rects[i].c - (x + 1);\n                int D_shrink = y - rects[i].b;\n                int U_shrink = rects[i].d - (y + 1);\n                int w_min = max(1, w - L_shrink - R_shrink);\n                int h_min = max(1, h - D_shrink - U_shrink);\n                int best_w = w, best_h = h;\n                int best_diff = abs(s - r);\n                \n                int w_ideal = max(1, (int)sqrt(r));\n                int deficit = s - r;\n                int search_range = min(500, max(300, deficit / 1000));\n                int w_start = max(w_min, w_ideal - search_range);\n                int w_end = min(w, w_ideal + search_range);\n                if (w_start > w_end) {\n                    w_start = w_min;\n                    w_end = w;\n                }\n                \n                for (int w2 = w_start; w2 <= w_end; ++w2) {\n                    double h_ideal = (double)r / w2;\n                    int h1 = max(h_min, min(h, (int)floor(h_ideal)));\n                    int h2 = max(h_min, min(h, (int)ceil(h_ideal)));\n                    int area1 = w2 * h1;\n                    int diff1 = abs(area1 - r);\n                    if (diff1 < best_diff) {\n                        best_diff = diff1;\n                        best_w = w2;\n                        best_h = h1;\n                    }\n                    int area2 = w2 * h2;\n                    int diff2 = abs(area2 - r);\n                    if (diff2 < best_diff) {\n                        best_diff = diff2;\n                        best_w = w2;\n                        best_h = h2;\n                    }\n                }\n                \n                if (best_w == w && best_h == h) continue;\n                \n                int need_w = w - best_w;\n                int need_h = h - best_h;\n                int L = min(need_w, L_shrink);\n                int R = need_w - L;\n                if (R > R_shrink) {\n                    R = R_shrink;\n                    L = need_w - R;\n                }\n                int D = min(need_h, D_shrink);\n                int U = need_h - D;\n                if (U > U_shrink) {\n                    U = U_shrink;\n                    D = need_h - U;\n                }\n                \n                Rect candidate = {rects[i].a + L, rects[i].b + D, rects[i].c - R, rects[i].d - U};\n                if (candidate.a <= x && candidate.c >= x + 1 && \n                    candidate.b <= y && candidate.d >= y + 1) {\n                    rects[i] = candidate;\n                    changed = true;\n                }\n            }\n        }\n        if (!changed) break;\n    }\n\n    // Apply simulated annealing\n    simulated_annealing();\n\n    for (int i = 0; i < n; ++i) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <utility>\n#include <tuple>\n#include <cassert>\n\nusing namespace std;\n\nconst int N = 50;\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    cin >> si >> sj;\n\n    vector<vector<int>> t(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> t[i][j];\n\n    vector<vector<int>> p(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> p[i][j];\n\n    int M = 0;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            M = max(M, t[i][j] + 1);\n\n    // Precompute neighbor information and tile values\n    vector<vector<int>> max_neighbor(N, vector<int>(N, 0));\n    vector<vector<int>> second_max_neighbor(N, vector<int>(N, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            vector<int> neighbor_values;\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) {\n                    neighbor_values.push_back(p[ni][nj]);\n                }\n            }\n            sort(neighbor_values.rbegin(), neighbor_values.rend());\n            max_neighbor[i][j] = neighbor_values.empty() ? 0 : neighbor_values[0];\n            second_max_neighbor[i][j] = neighbor_values.size() < 2 ? 0 : neighbor_values[1];\n        }\n    }\n\n    random_device rd;\n    mt19937 rng(rd());\n    auto start_time = chrono::steady_clock::now();\n    const double time_limit = 1.95;\n\n    int best_score = p[si][sj];\n    string best_path;\n\n    // Helper to count unvisited neighbors\n    auto count_unvisited = [&](int i, int j, const vector<char>& visited) {\n        int cnt = 0;\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 && !visited[t[ni][nj]])\n                ++cnt;\n        }\n        return cnt;\n    };\n\n    struct State {\n        int i, j;\n        int score;\n        vector<tuple<int, int, int>> candidates;\n        int next_idx;\n        int depth;\n    };\n\n    // Eight diverse strategies with different heuristic weightings\n    vector<tuple<int, int, int, int, int>> strategy_params = {\n        {8, 3, 0, 0, 0},   // Strategy 0: balanced\n        {12, 5, 0, 0, 0},  // Strategy 1: high neighbor weight\n        {10, 4, 1, 0, 0},  // Strategy 2: limited branching\n        {6, 2, 0, 0, 0},   // Strategy 3: focus on value\n        {15, 6, 0, 0, 0},  // Strategy 4: aggressive expansion\n        {5, 1, 0, 1, 0},   // Strategy 5: no pruning, more exploration\n        {20, 8, 0, 1, 0},  // Strategy 6: very aggressive, no pruning\n        {3, 1, 0, 0, 1}    // Strategy 7: conservative with deep lookahead\n    };\n\n    // Adaptive time allocation: start with equal time, then adjust\n    vector<double> strategy_times(8, time_limit / 8.0);\n    vector<int> strategy_scores(8, 0);\n    int completed_strategies = 0;\n\n    for (int strategy = 0; strategy < 8; ++strategy) {\n        double strategy_start_time = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        double allocated_time = strategy_times[strategy];\n        \n        if (strategy_start_time + allocated_time > time_limit) {\n            // Not enough time for this strategy\n            continue;\n        }\n\n        auto [coeff1, coeff2, limit_branching, no_prune, deep_lookahead] = strategy_params[strategy];\n\n        vector<char> visited(M, 0);\n        visited[t[si][sj]] = 1;\n        int visited_count = 1;\n\n        vector<State> stack;\n        string current_path;\n        int strategy_best_score = p[si][sj];\n\n        // Initialize start state\n        vector<tuple<int, int, int>> start_candidates;\n        for (int d = 0; d < 4; ++d) {\n            int ni = si + di[d], nj = sj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[t[ni][nj]]) {\n                int cnt = count_unvisited(ni, nj, visited);\n                \n                // Lookahead: consider the best neighbor of this candidate\n                int lookahead_bonus = 0;\n                if (deep_lookahead) {\n                    for (int dd = 0; dd < 4; ++dd) {\n                        int nni = ni + di[dd], nnj = nj + dj[dd];\n                        if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && \n                            !visited[t[nni][nnj]] && !(nni == si && nnj == sj)) {\n                            lookahead_bonus = max(lookahead_bonus, p[nni][nnj]);\n                        }\n                    }\n                }\n                \n                int weight = p[ni][nj] + coeff1 * cnt + coeff2 * max_neighbor[ni][nj] / 4 + lookahead_bonus / 2;\n                start_candidates.emplace_back(ni, nj, weight);\n            }\n        }\n\n        // Sort candidates by weight\n        sort(start_candidates.begin(), start_candidates.end(),\n             [](const auto& a, const auto& b) { return get<2>(a) > get<2>(b); });\n\n        // For strategy 2, limit to top 3 candidates\n        if (strategy == 2 && start_candidates.size() > 3) {\n            start_candidates.resize(3);\n        }\n\n        stack.push_back({si, sj, p[si][sj], start_candidates, 0, 0});\n\n        while (!stack.empty() &&\n               chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < time_limit &&\n               chrono::duration<double>(chrono::steady_clock::now() - start_time).count() - strategy_start_time < allocated_time) {\n            State& top = stack.back();\n\n            if (top.next_idx >= (int)top.candidates.size()) {\n                // Backtrack\n                if (t[top.i][top.j] != t[si][sj])\n                    visited[t[top.i][top.j]] = 0;\n                --visited_count;\n                stack.pop_back();\n                if (!current_path.empty())\n                    current_path.pop_back();\n                continue;\n            }\n\n            auto [ni, nj, w] = top.candidates[top.next_idx++];\n            int tile = t[ni][nj];\n            if (visited[tile]) continue;\n\n            visited[tile] = 1;\n            ++visited_count;\n            int new_score = top.score + p[ni][nj];\n            int new_depth = top.depth + 1;\n\n            char move;\n            if (ni == top.i - 1 && nj == top.j) move = 'U';\n            else if (ni == top.i + 1 && nj == top.j) move = 'D';\n            else if (ni == top.i && nj == top.j - 1) move = 'L';\n            else if (ni == top.i && nj == top.j + 1) move = 'R';\n            else assert(false);\n\n            current_path.push_back(move);\n\n            if (new_score > strategy_best_score) {\n                strategy_best_score = new_score;\n                if (new_score > best_score) {\n                    best_score = new_score;\n                    best_path = current_path;\n                }\n            }\n\n            // Optimistic bound pruning (less aggressive)\n            if (!no_prune) {\n                // Use 50 instead of 99 for a more conservative bound\n                int optimistic_bound = new_score + 50 * (M - visited_count);\n                if (optimistic_bound <= best_score) {\n                    visited[tile] = 0;\n                    --visited_count;\n                    current_path.pop_back();\n                    continue;\n                }\n            }\n\n            // Generate candidates for next state with lookahead\n            vector<tuple<int, int, int>> next_candidates;\n            for (int d = 0; d < 4; ++d) {\n                int nni = ni + di[d], nnj = nj + dj[d];\n                if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && !visited[t[nni][nnj]]) {\n                    int cnt = count_unvisited(nni, nnj, visited);\n                    \n                    // Lookahead: consider the best unvisited neighbor of this candidate\n                    int lookahead_bonus = 0;\n                    for (int dd = 0; dd < 4; ++dd) {\n                        int nnni = nni + di[dd], nnnj = nnj + dj[dd];\n                        if (nnni >= 0 && nnni < N && nnnj >= 0 && nnnj < N && \n                            !visited[t[nnni][nnnj]] && !(nnni == ni && nnnj == nj)) {\n                            lookahead_bonus = max(lookahead_bonus, p[nnni][nnnj]);\n                        }\n                    }\n                    \n                    int weight = p[nni][nnj] + coeff1 * cnt + coeff2 * max_neighbor[nni][nnj] / 4 + lookahead_bonus / 3;\n                    next_candidates.emplace_back(nni, nnj, weight);\n                }\n            }\n\n            // Sort candidates\n            sort(next_candidates.begin(), next_candidates.end(),\n                 [](const auto& a, const auto& b) { return get<2>(a) > get<2>(b); });\n\n            // For strategy 2, limit to top 3 candidates\n            if (strategy == 2 && next_candidates.size() > 3) {\n                next_candidates.resize(3);\n            }\n\n            stack.push_back({ni, nj, new_score, next_candidates, 0, new_depth});\n        }\n\n        // Update strategy scores and adjust time allocation for remaining strategies\n        strategy_scores[strategy] = strategy_best_score;\n        completed_strategies++;\n        \n        // Adaptive time allocation: if this strategy did well, give more time to similar strategies\n        if (completed_strategies < 8) {\n            double remaining_time = time_limit - chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n            double avg_time_per_remaining = remaining_time / (8 - completed_strategies);\n            \n            // If this strategy found a good score, allocate more time to strategies with similar parameters\n            if (strategy_best_score > best_score * 0.8) {\n                for (int i = strategy + 1; i < 8; ++i) {\n                    // Simple heuristic: if coefficients are similar, allocate more time\n                    auto [c1, c2, lb, np, dl] = strategy_params[i];\n                    if (abs(c1 - coeff1) <= 5 && abs(c2 - coeff2) <= 2) {\n                        strategy_times[i] = min(time_limit / 4.0, avg_time_per_remaining * 1.5);\n                    }\n                }\n            }\n        }\n    }\n\n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int ROWS = 30;\nconst int COLS = 30;\nconst int MAX_QUERIES = 1000;\n\n// Direction vectors: U, D, L, R\nconst int dr[4] = {-1, 1, 0, 0};\nconst int dc[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Edge weight estimation with confidence\nvector<vector<double>> h_est(ROWS, vector<double>(COLS-1));\nvector<vector<double>> v_est(ROWS-1, vector<double>(COLS));\nvector<vector<int>> h_count(ROWS, vector<int>(COLS-1, 0));\nvector<vector<int>> v_count(ROWS-1, vector<int>(COLS, 0));\nvector<vector<double>> h_confidence(ROWS, vector<double>(COLS-1, 0.0));\nvector<vector<double>> v_confidence(ROWS-1, vector<double>(COLS, 0.0));\n\n// Track row and column base values\nvector<double> row_base(ROWS, 5000.0);\nvector<double> col_base(COLS, 5000.0);\nvector<int> row_count(ROWS, 0);\nvector<int> col_count(COLS, 0);\n\n// For random number generation\nrandom_device rd;\nmt19937 gen(rd());\nuniform_real_distribution<> dis(0.0, 1.0);\n\nvoid initialize_estimates() {\n    // Initialize with row/column bases\n    for (int i = 0; i < ROWS; i++) {\n        for (int j = 0; j < COLS-1; j++) {\n            h_est[i][j] = row_base[i];\n            h_confidence[i][j] = 0.0;\n        }\n    }\n    for (int i = 0; i < ROWS-1; i++) {\n        for (int j = 0; j < COLS; j++) {\n            v_est[i][j] = col_base[j];\n            v_confidence[i][j] = 0.0;\n        }\n    }\n}\n\npair<string, double> find_path(int si, int sj, int ti, int tj, bool explore) {\n    vector<vector<double>> dist(ROWS, vector<double>(COLS, 1e18));\n    vector<vector<pair<int,int>>> parent(ROWS, vector<pair<int,int>>(COLS, {-1,-1}));\n    vector<vector<int>> dir_used(ROWS, vector<int>(COLS, -1));\n    \n    dist[si][sj] = 0;\n    using Node = pair<double, pair<int,int>>;\n    priority_queue<Node, vector<Node>, greater<Node>> pq;\n    pq.push({0.0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, node] = pq.top(); pq.pop();\n        auto [i, j] = node;\n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n        \n        // Standard Dijkstra with optional direction shuffling for exploration\n        vector<int> dirs = {0, 1, 2, 3};\n        if (explore) {\n            shuffle(dirs.begin(), dirs.end(), gen);\n        }\n        \n        for (int dir : dirs) {\n            int ni = i + dr[dir];\n            int nj = j + dc[dir];\n            if (ni < 0 || ni >= ROWS || nj < 0 || nj >= COLS) continue;\n            \n            double w;\n            if (dir == 0) w = v_est[ni][nj]; // U\n            else if (dir == 1) w = v_est[i][j]; // D\n            else if (dir == 2) w = h_est[i][nj]; // L\n            else w = h_est[i][j]; // R\n            \n            if (dist[ni][nj] > d + w + 1e-9) {\n                dist[ni][nj] = d + w;\n                parent[ni][nj] = {i, j};\n                dir_used[ni][nj] = dir;\n                pq.push({dist[ni][nj], {ni, nj}});\n            }\n        }\n    }\n    \n    string path;\n    double est_len = 0;\n    int ci = ti, cj = tj;\n    \n    while (ci != si || cj != sj) {\n        int dir = dir_used[ci][cj];\n        path += dir_char[dir];\n        \n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        \n        if (dir == 0) { // U\n            est_len += v_est[ci][cj];\n        } else if (dir == 1) { // D\n            est_len += v_est[pi][pj];\n        } else if (dir == 2) { // L\n            est_len += h_est[ci][cj];\n        } else { // R\n            est_len += h_est[pi][pj];\n        }\n        \n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, est_len};\n}\n\nvoid update_weights(const string& path, int si, int sj, double observed, int query_num) {\n    int i = si, j = sj;\n    double est_len = 0;\n    vector<tuple<int,int,bool,double>> edges; // r, c, is_horiz, edge_weight\n    \n    for (char c : path) {\n        int dir;\n        if (c == 'U') dir = 0;\n        else if (c == 'D') dir = 1;\n        else if (c == 'L') dir = 2;\n        else dir = 3;\n        \n        int ni = i + dr[dir];\n        int nj = j + dc[dir];\n        \n        if (dir == 0) {\n            double w = v_est[ni][nj];\n            edges.emplace_back(ni, nj, false, w);\n            est_len += w;\n        } else if (dir == 1) {\n            double w = v_est[i][j];\n            edges.emplace_back(i, j, false, w);\n            est_len += w;\n        } else if (dir == 2) {\n            double w = h_est[i][nj];\n            edges.emplace_back(i, nj, true, w);\n            est_len += w;\n        } else {\n            double w = h_est[i][j];\n            edges.emplace_back(i, j, true, w);\n            est_len += w;\n        }\n        \n        i = ni;\n        j = nj;\n    }\n    \n    double error = observed - est_len;\n    int edge_count = edges.size();\n    if (edge_count == 0) return;\n    \n    // Even more refined learning rate schedule with faster early learning\n    double base_lr;\n    if (query_num < 50) {\n        base_lr = 0.99 * exp(-query_num / 100.0);  // Ultra-fast early learning\n    } else if (query_num < 150) {\n        base_lr = 0.95 * exp(-(query_num - 50) / 200.0);  // Extremely fast learning\n    } else if (query_num < 300) {\n        base_lr = 0.85 * exp(-(query_num - 150) / 500.0);  // Very fast learning\n    } else if (query_num < 600) {\n        base_lr = 0.75 * exp(-(query_num - 300) / 800.0);  // Fast learning\n    } else {\n        base_lr = 0.65 * exp(-(query_num - 600) / 1500.0);  // Slower decay later\n    }\n    \n    // Adjust by error magnitude - more aggressive for larger errors\n    double error_ratio = abs(error) / (est_len + 1e-9);\n    double error_boost = min(0.5, 0.5 * error_ratio * error_ratio);  // Quadratic scaling\n    base_lr = min(0.99, base_lr + error_boost);\n    \n    for (auto [r, c, is_horiz, edge_weight] : edges) {\n        int count = is_horiz ? h_count[r][c] : v_count[r][c];\n        double confidence = is_horiz ? h_confidence[r][c] : v_confidence[r][c];\n        \n        // Learning rate based on confidence and count - even more aggressive\n        double lr = base_lr / (1.0 + 0.02 * count) * (1.5 - 1.2 * confidence);\n        \n        // Distribute error proportionally to edge weight\n        double proportion = edge_weight / (est_len + 1e-9);\n        double delta = lr * error * proportion;\n        \n        if (is_horiz) {\n            double old_est = h_est[r][c];\n            h_est[r][c] += delta;\n            h_est[r][c] = max(1000.0, min(9000.0, h_est[r][c]));\n            h_count[r][c]++;\n            \n            // Update confidence - ultra-responsive\n            double change_ratio = abs(h_est[r][c] - old_est) / (old_est + 1e-9);\n            h_confidence[r][c] = 0.7 * h_confidence[r][c] + 0.3 * (1.0 - min(1.0, change_ratio * 4.0));\n            \n            // Update row base estimate - very strong updates\n            double alpha = 0.35 / (1.0 + 0.0015 * row_count[r]);\n            row_base[r] = (1 - alpha) * row_base[r] + alpha * h_est[r][c];\n            row_count[r]++;\n        } else {\n            double old_est = v_est[r][c];\n            v_est[r][c] += delta;\n            v_est[r][c] = max(1000.0, min(9000.0, v_est[r][c]));\n            v_count[r][c]++;\n            \n            // Update confidence - ultra-responsive\n            double change_ratio = abs(v_est[r][c] - old_est) / (old_est + 1e-9);\n            v_confidence[r][c] = 0.7 * v_confidence[r][c] + 0.3 * (1.0 - min(1.0, change_ratio * 4.0));\n            \n            // Update column base estimate - very strong updates\n            double alpha = 0.35 / (1.0 + 0.0015 * col_count[c]);\n            col_base[c] = (1 - alpha) * col_base[c] + alpha * v_est[r][c];\n            col_count[c]++;\n        }\n    }\n    \n    // Re-initialize poorly learned edges very frequently early on\n    int reinit_freq;\n    if (query_num < 100) {\n        reinit_freq = 25;  // Very frequent early\n    } else if (query_num < 300) {\n        reinit_freq = 50;  // Frequent\n    } else {\n        reinit_freq = 75;  // Less frequent later\n    }\n    \n    if (query_num % reinit_freq == reinit_freq - 1) {\n        for (int i = 0; i < ROWS; i++) {\n            for (int j = 0; j < COLS-1; j++) {\n                if (h_count[i][j] < 2 || h_confidence[i][j] < 0.12) {\n                    h_est[i][j] = row_base[i] + (dis(gen) - 0.5) * 1000.0;\n                    h_confidence[i][j] = 0.0;\n                }\n            }\n        }\n        for (int i = 0; i < ROWS-1; i++) {\n            for (int j = 0; j < COLS; j++) {\n                if (v_count[i][j] < 2 || v_confidence[i][j] < 0.12) {\n                    v_est[i][j] = col_base[j] + (dis(gen) - 0.5) * 1000.0;\n                    v_confidence[i][j] = 0.0;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_estimates();\n    \n    for (int q = 0; q < MAX_QUERIES; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        // Refined exploration schedule with higher early exploration\n        double explore_prob;\n        if (q < 50) {\n            explore_prob = 0.8;  // Ultra-high exploration early\n        } else if (q < 150) {\n            explore_prob = 0.65 * exp(-(q - 50) / 200.0);  // Very high exploration\n        } else if (q < 300) {\n            explore_prob = 0.5 * exp(-(q - 150) / 400.0);  // High exploration\n        } else if (q < 500) {\n            explore_prob = 0.35 * exp(-(q - 300) / 600.0);  // Medium exploration\n        } else {\n            explore_prob = 0.2 * exp(-(q - 500) / 800.0);  // Lower exploration later\n        }\n        bool explore = (dis(gen) < explore_prob);\n        \n        auto [path, est_len] = find_path(si, sj, ti, tj, explore);\n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_weights(path, si, sj, observed, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int ALPHABET = 8;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    int dummy;\n    cin >> dummy >> M;\n    \n    vector<string> strs(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> strs[i];\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Sort strings by length descending\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return strs[a].size() > strs[b].size();\n    });\n    \n    // Initialize grid with random letters\n    char grid[N][N];\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            grid[i][j] = 'A' + rng() % ALPHABET;\n        }\n    }\n    \n    vector<bool> covered(M, false);\n    auto start_time = chrono::steady_clock::now();\n    \n    // Phase 1: Cover strings with minimal conflicts\n    for (int idx : order) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 1.0) {\n            break;\n        }\n        \n        const string& s = strs[idx];\n        int L = s.size();\n        \n        // Adaptive threshold: allow more mismatches for longer strings\n        int threshold = min(3, (L + 1) / 2);\n        \n        int best_i = -1, best_j = -1, best_dir = -1, best_conflicts = L + 1;\n        \n        // Find placement with fewest conflicts\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                for (int dir = 0; dir < 2; ++dir) {\n                    int conflicts = 0;\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        if (grid[ni][nj] != s[p]) {\n                            conflicts++;\n                        }\n                    }\n                    if (conflicts < best_conflicts) {\n                        best_conflicts = conflicts;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = dir;\n                    }\n                }\n            }\n        }\n        \n        // If conflicts are low, place the string\n        if (best_conflicts <= threshold && best_i != -1) {\n            for (int p = 0; p < L; ++p) {\n                int ni, nj;\n                if (best_dir == 0) {\n                    ni = best_i;\n                    nj = (best_j + p) % N;\n                } else {\n                    ni = (best_i + p) % N;\n                    nj = best_j;\n                }\n                grid[ni][nj] = s[p];\n            }\n            covered[idx] = true;\n        }\n    }\n    \n    // Phase 2: Try to cover remaining strings with minimal disruption\n    // First, compute for each cell how many covered strings depend on it\n    vector<vector<int>> cell_importance(N, vector<int>(N, 0));\n    for (int idx = 0; idx < M; ++idx) {\n        if (!covered[idx]) continue;\n        \n        const string& s = strs[idx];\n        int L = s.size();\n        \n        // Find one valid placement for this covered string\n        bool found = false;\n        for (int i = 0; i < N && !found; ++i) {\n            for (int j = 0; j < N && !found; ++j) {\n                for (int dir = 0; dir < 2 && !found; ++dir) {\n                    bool valid = true;\n                    for (int p = 0; p < L; ++p) {\n                        int ni, nj;\n                        if (dir == 0) {\n                            ni = i;\n                            nj = (j + p) % N;\n                        } else {\n                            ni = (i + p) % N;\n                            nj = j;\n                        }\n                        if (grid[ni][nj] != s[p]) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                    if (valid) {\n                        // Mark cells used by this placement\n                        for (int p = 0; p < L; ++p) {\n                            int ni, nj;\n                            if (dir == 0) {\n                                ni = i;\n                                nj = (j + p) % N;\n                            } else {\n                                ni = (i + p) % N;\n                                nj = j;\n                            }\n                            cell_importance[ni][nj]++;\n                        }\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Now try to cover uncovered strings\n    for (int iteration = 0; iteration < 2; ++iteration) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.5) {\n            break;\n        }\n        \n        for (int idx = 0; idx < M; ++idx) {\n            if (covered[idx]) continue;\n            if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() > 2.7) {\n                break;\n            }\n            \n            const string& s = strs[idx];\n            int L = s.size();\n            \n            int best_i = -1, best_j = -1, best_dir = -1, best_cost = 1000000;\n            \n            // Find placement with minimum disruption cost\n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    for (int dir = 0; dir < 2; ++dir) {\n                        int cost = 0;\n                        bool possible = true;\n                        for (int p = 0; p < L; ++p) {\n                            int ni, nj;\n                            if (dir == 0) {\n                                ni = i;\n                                nj = (j + p) % N;\n                            } else {\n                                ni = (i + p) % N;\n                                nj = j;\n                            }\n                            if (grid[ni][nj] != s[p]) {\n                                cost += cell_importance[ni][nj];\n                                if (cost >= best_cost) {\n                                    possible = false;\n                                    break;\n                                }\n                            }\n                        }\n                        if (possible && cost < best_cost) {\n                            best_cost = cost;\n                            best_i = i;\n                            best_j = j;\n                            best_dir = dir;\n                        }\n                    }\n                }\n            }\n            \n            // Adaptive threshold based on string length\n            int threshold = 5 + L/2;\n            \n            if (best_cost <= threshold && best_i != -1) {\n                for (int p = 0; p < L; ++p) {\n                    int ni, nj;\n                    if (best_dir == 0) {\n                        ni = best_i;\n                        nj = (best_j + p) % N;\n                    } else {\n                        ni = (best_i + p) % N;\n                        nj = best_j;\n                    }\n                    grid[ni][nj] = s[p];\n                }\n                covered[idx] = true;\n                \n                // Update importance scores\n                for (int p = 0; p < L; ++p) {\n                    int ni, nj;\n                    if (best_dir == 0) {\n                        ni = best_i;\n                        nj = (best_j + p) % N;\n                    } else {\n                        ni = (best_i + p) % N;\n                        nj = best_j;\n                    }\n                    cell_importance[ni][nj]++;\n                }\n            }\n        }\n    }\n    \n    // Final pass: try to cover any remaining strings with up to 2 mismatches\n    if (chrono::duration<double>(chrono::steady_clock::now() - start_time).count() < 2.9) {\n        for (int idx = 0; idx < M; ++idx) {\n            if (covered[idx]) continue;\n            \n            const string& s = strs[idx];\n            int L = s.size();\n            \n            for (int i = 0; i < N; ++i) {\n                for (int j = 0; j < N; ++j) {\n                    for (int dir = 0; dir < 2; ++dir) {\n                        int mismatches = 0;\n                        for (int p = 0; p < L; ++p) {\n                            int ni, nj;\n                            if (dir == 0) {\n                                ni = i;\n                                nj = (j + p) % N;\n                            } else {\n                                ni = (i + p) % N;\n                                nj = j;\n                            }\n                            if (grid[ni][nj] != s[p]) {\n                                mismatches++;\n                            }\n                        }\n                        if (mismatches <= 2) {\n                            for (int p = 0; p < L; ++p) {\n                                int ni, nj;\n                                if (dir == 0) {\n                                    ni = i;\n                                    nj = (j + p) % N;  // Fixed: was best_j, should be j\n                                } else {\n                                    ni = (i + p) % N;\n                                    nj = j;\n                                }\n                                grid[ni][nj] = s[p];\n                            }\n                            covered[idx] = true;\n                            goto next_uncovered;\n                        }\n                    }\n                }\n            }\n            next_uncovered:;\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        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<int>> cost;               // -1 for obstacle, else digit 5-9\nvector<vector<int>> row_seg, col_seg;   // segment ids for each cell\nint R_cnt, C_cnt;                       // number of row/column segments\nvector<vector<pair<int, int>>> row_cells, col_cells; // cells in each segment\nvector<unordered_map<int, pair<int, int>>> cell_of;  // (r,c) -> (i,j)\n\n// Directions: up, down, left, right\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// Linear index for a cell\ninline int to_id(int i, int j) { return i * N + j; }\ninline pair<int, int> from_id(int id) { return {id / N, id % N}; }\n\n// ----------------------------------------------------------------------\n// Dijkstra from a source, returns distances and predecessors\nstruct DijkstraResult {\n    vector<vector<int>> dist;\n    vector<vector<int>> prev;   // previous cell as linear id\n    DijkstraResult() : dist(N, vector<int>(N, INF)), prev(N, vector<int>(N, -1)) {}\n};\n\nDijkstraResult run_dijkstra(int si, int sj) {\n    DijkstraResult res;\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    res.dist[si][sj] = 0;\n    pq.push({0, to_id(si, sj)});\n    while (!pq.empty()) {\n        auto [d, id] = pq.top(); pq.pop();\n        auto [i, j] = from_id(id);\n        if (d != res.dist[i][j]) continue;\n        for (int k = 0; k < 4; ++k) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (cost[ni][nj] == -1) continue;   // obstacle\n            int nd = d + cost[ni][nj];\n            if (nd < res.dist[ni][nj]) {\n                res.dist[ni][nj] = nd;\n                res.prev[ni][nj] = id;\n                pq.push({nd, to_id(ni, nj)});\n            }\n        }\n    }\n    return res;\n}\n\n// ----------------------------------------------------------------------\n// Hopcroft\u2013Karp for bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> matchL, matchR, dist;\n    HopcroftKarp(int nL, int nR) : nL(nL), nR(nR), adj(nL), matchL(nL, -1), matchR(nR, -1), dist(nL) {}\n    void addEdge(int u, int v) { adj[u].push_back(v); }\n    bool bfs() {\n        queue<int> q;\n        for (int u = 0; u < nL; ++u) {\n            if (matchL[u] == -1) {\n                dist[u] = 0;\n                q.push(u);\n            } else dist[u] = INF;\n        }\n        bool found = false;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : adj[u]) {\n                if (matchR[v] == -1) found = true;\n                else if (dist[matchR[v]] == INF) {\n                    dist[matchR[v]] = dist[u] + 1;\n                    q.push(matchR[v]);\n                }\n            }\n        }\n        return found;\n    }\n    bool dfs(int u) {\n        for (int v : adj[u]) {\n            if (matchR[v] == -1 || (dist[matchR[v]] == dist[u] + 1 && dfs(matchR[v]))) {\n                matchL[u] = v;\n                matchR[v] = u;\n                return true;\n            }\n        }\n        dist[u] = INF;\n        return false;\n    }\n    int maxMatching() {\n        int matching = 0;\n        while (bfs()) {\n            for (int u = 0; u < nL; ++u)\n                if (matchL[u] == -1 && dfs(u))\n                    ++matching;\n        }\n        return matching;\n    }\n};\n\n// ----------------------------------------------------------------------\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input --------------------------------------------------------\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    cost.assign(N, vector<int>(N, -1));\n    vector<pair<int, int>> road_cells;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') {\n                cost[i][j] = grid[i][j] - '0';\n                road_cells.emplace_back(i, j);\n            }\n        }\n    }\n\n    // ----- Row segments -------------------------------------------------\n    row_seg.assign(N, vector<int>(N, -1));\n    R_cnt = 0;\n    row_cells.clear();\n    for (int i = 0; i < N; ++i) {\n        int j = 0;\n        while (j < N) {\n            if (cost[i][j] != -1) {\n                int start_j = j;\n                while (j < N && cost[i][j] != -1) {\n                    row_seg[i][j] = R_cnt;\n                    ++j;\n                }\n                row_cells.emplace_back();\n                for (int k = start_j; k < j; ++k)\n                    row_cells.back().emplace_back(i, k);\n                ++R_cnt;\n            } else {\n                ++j;\n            }\n        }\n    }\n\n    // ----- Column segments ----------------------------------------------\n    col_seg.assign(N, vector<int>(N, -1));\n    C_cnt = 0;\n    col_cells.clear();\n    for (int j = 0; j < N; ++j) {\n        int i = 0;\n        while (i < N) {\n            if (cost[i][j] != -1) {\n                int start_i = i;\n                while (i < N && cost[i][j] != -1) {\n                    col_seg[i][j] = C_cnt;\n                    ++i;\n                }\n                col_cells.emplace_back();\n                for (int k = start_i; k < i; ++k)\n                    col_cells.back().emplace_back(k, j);\n                ++C_cnt;\n            } else {\n                ++i;\n            }\n        }\n    }\n\n    // ----- Build full bipartite graph (row segments vs column segments) -\n    HopcroftKarp hk_full(R_cnt, C_cnt);\n    cell_of.resize(R_cnt);\n    for (auto [i, j] : road_cells) {\n        int r = row_seg[i][j];\n        int c = col_seg[i][j];\n        hk_full.addEdge(r, c);\n        cell_of[r][c] = {i, j};\n    }\n\n    // ----- Maximum matching and minimum vertex cover --------------------\n    hk_full.maxMatching();\n\n    vector<bool> visL(R_cnt, false), visR(C_cnt, false);\n    function<void(int)> dfs_cover = [&](int u) {\n        visL[u] = true;\n        for (int v : hk_full.adj[u]) {\n            if (!visR[v] && hk_full.matchL[u] != v) {\n                visR[v] = true;\n                if (hk_full.matchR[v] != -1 && !visL[hk_full.matchR[v]])\n                    dfs_cover(hk_full.matchR[v]);\n            }\n        }\n    };\n    for (int u = 0; u < R_cnt; ++u)\n        if (hk_full.matchL[u] == -1)\n            dfs_cover(u);\n\n    vector<bool> inX(R_cnt, false), inY(C_cnt, false);\n    for (int u = 0; u < R_cnt; ++u) if (!visL[u]) inX[u] = true;\n    for (int v = 0; v < C_cnt; ++v) if (visR[v]) inY[v] = true;\n\n    // ----- Remove start's own segments ----------------------------------\n    int r_start = row_seg[si][sj];\n    int c_start = col_seg[si][sj];\n    if (r_start != -1) inX[r_start] = false;\n    if (c_start != -1) inY[c_start] = false;\n\n    // ----- Collect vertices that still need covering --------------------\n    vector<int> X_list, Y_list;\n    for (int u = 0; u < R_cnt; ++u) if (inX[u]) X_list.push_back(u);\n    for (int v = 0; v < C_cnt; ++v) if (inY[v]) Y_list.push_back(v);\n    int nX = X_list.size(), nY = Y_list.size();\n\n    // If nothing left to cover, we only need to start and return.\n    if (nX == 0 && nY == 0) {\n        // Trivial tour: go to an adjacent road cell and back.\n        for (int d = 0; d < 4; ++d) {\n            int ni = si + di[d], nj = sj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && cost[ni][nj] != -1) {\n                cout << dir_char[d];\n                // Opposite direction\n                if (d == 0) cout << 'D';\n                else if (d == 1) cout << 'U';\n                else if (d == 2) cout << 'R';\n                else cout << 'L';\n                cout << endl;\n                return 0;\n            }\n        }\n        // Should not happen (graph is connected), but fallback:\n        cout << endl;\n        return 0;\n    }\n\n    // ----- Build subgraph between X_list and Y_list --------------------\n    vector<int> X_index(R_cnt, -1), Y_index(C_cnt, -1);\n    for (int i = 0; i < nX; ++i) X_index[X_list[i]] = i;\n    for (int i = 0; i < nY; ++i) Y_index[Y_list[i]] = i;\n\n    HopcroftKarp hk_sub(nX, nY);\n    vector<unordered_map<int, pair<int, int>>> sub_cell_of(nX);\n    for (int r : X_list) {\n        int i = X_index[r];\n        for (auto &[c, coord] : cell_of[r]) {\n            if (inY[c]) {\n                int j = Y_index[c];\n                hk_sub.addEdge(i, j);\n                sub_cell_of[i][j] = {r, c};\n            }\n        }\n    }\n\n    // ----- Maximum matching in subgraph ---------------------------------\n    hk_sub.maxMatching();\n\n    // ----- Precompute distances from start (for picking close cells) ----\n    auto dist_start_res = run_dijkstra(si, sj);\n    auto &dist_start = dist_start_res.dist;\n\n    // ----- Construct set S of cells to visit ----------------------------\n    set<pair<int, int>> S_set;\n\n    // Cells from the matching\n    for (int i = 0; i < nX; ++i) {\n        int j = hk_sub.matchL[i];\n        if (j != -1) {\n            auto [r, c] = sub_cell_of[i][j];\n            S_set.insert(cell_of[r][c]);\n        }\n    }\n\n    // Unmatched row segments: pick closest cell to start\n    for (int i = 0; i < nX; ++i) {\n        if (hk_sub.matchL[i] == -1) {\n            int r = X_list[i];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : row_cells[r]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    // Unmatched column segments: pick closest cell to start\n    for (int j = 0; j < nY; ++j) {\n        if (hk_sub.matchR[j] == -1) {\n            int c = Y_list[j];\n            pair<int, int> best = {-1, -1};\n            int best_dist = INF;\n            for (auto [ii, jj] : col_cells[c]) {\n                if (dist_start[ii][jj] < best_dist) {\n                    best_dist = dist_start[ii][jj];\n                    best = {ii, jj};\n                }\n            }\n            if (best.first != -1) S_set.insert(best);\n        }\n    }\n\n    vector<pair<int, int>> points(S_set.begin(), S_set.end());\n    int K = points.size();\n\n    // ----- All-pairs shortest paths among points and start -------------\n    int total_nodes = K + 1;          // indices 0..K-1 : points, K : start\n    vector<vector<int>> dist_mat(total_nodes, vector<int>(total_nodes, INF));\n    vector<DijkstraResult> dijkstra_res(total_nodes);\n\n    for (int idx = 0; idx < total_nodes; ++idx) {\n        int i, j;\n        if (idx < K) {\n            i = points[idx].first, j = points[idx].second;\n        } else {\n            i = si, j = sj;\n        }\n        dijkstra_res[idx] = run_dijkstra(i, j);\n        auto &res = dijkstra_res[idx];\n        for (int other = 0; other < total_nodes; ++other) {\n            int oi, oj;\n            if (other < K) {\n                oi = points[other].first, oj = points[other].second;\n            } else {\n                oi = si, oj = sj;\n            }\n            dist_mat[idx][other] = res.dist[oi][oj];\n        }\n    }\n\n    // ----- Helper function for TSP cost --------------------------------\n    auto compute_order_cost = [&](const vector<int>& ord) {\n        if (ord.empty()) return 0;\n        int total = dist_mat[K][ord[0]];\n        for (size_t i = 0; i + 1 < ord.size(); ++i) {\n            total += dist_mat[ord[i]][ord[i+1]];\n        }\n        total += dist_mat[ord.back()][K];\n        return total;\n    };\n\n    // ----- Build initial tours using multiple heuristics ----------------\n    vector<int> best_order;\n    int best_cost = INF;\n    \n    // Heuristic 1: Nearest neighbor\n    {\n        vector<int> order;\n        vector<bool> visited(K, false);\n        int cur = K;  // start index\n        while ((int)order.size() < K) {\n            int nxt = -1;\n            int best = INF;\n            for (int j = 0; j < K; ++j) {\n                if (!visited[j] && dist_mat[cur][j] < best) {\n                    best = dist_mat[cur][j];\n                    nxt = j;\n                }\n            }\n            if (nxt == -1) break;\n            visited[nxt] = true;\n            order.push_back(nxt);\n            cur = nxt;\n        }\n        int cost = compute_order_cost(order);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_order = order;\n        }\n    }\n    \n    // Heuristic 2: Cheapest insertion\n    {\n        vector<int> order;\n        vector<bool> inserted(K, false);\n        \n        if (K > 0) {\n            // Start with the point that minimizes round trip from start\n            int first = -1;\n            int best_round = INF;\n            for (int i = 0; i < K; ++i) {\n                int round_cost = dist_mat[K][i] + dist_mat[i][K];\n                if (round_cost < best_round) {\n                    best_round = round_cost;\n                    first = i;\n                }\n            }\n            order.push_back(first);\n            inserted[first] = true;\n            \n            // Iteratively insert remaining points\n            while ((int)order.size() < K) {\n                int best_point = -1;\n                int best_pos = -1;\n                int best_increase = INF;\n                \n                for (int i = 0; i < K; ++i) {\n                    if (inserted[i]) continue;\n                    \n                    int m = order.size();\n                    // Try insertion at beginning\n                    int increase = dist_mat[K][i] + dist_mat[i][order[0]] - dist_mat[K][order[0]];\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_point = i;\n                        best_pos = 0;\n                    }\n                    \n                    // Try insertion between points\n                    for (int j = 1; j < m; ++j) {\n                        int a = order[j-1];\n                        int b = order[j];\n                        increase = dist_mat[a][i] + dist_mat[i][b] - dist_mat[a][b];\n                        if (increase < best_increase) {\n                            best_increase = increase;\n                            best_point = i;\n                            best_pos = j;\n                        }\n                    }\n                    \n                    // Try insertion at end\n                    increase = dist_mat[order.back()][i] + dist_mat[i][K] - dist_mat[order.back()][K];\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_point = i;\n                        best_pos = m;\n                    }\n                }\n                \n                order.insert(order.begin() + best_pos, best_point);\n                inserted[best_point] = true;\n            }\n        }\n        \n        int cost = compute_order_cost(order);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_order = order;\n        }\n    }\n    \n    // Heuristic 3: Farthest insertion\n    {\n        vector<int> order;\n        vector<bool> inserted(K, false);\n        \n        if (K > 0) {\n            // Start with the point that minimizes round trip from start\n            int first = -1;\n            int best_round = INF;\n            for (int i = 0; i < K; ++i) {\n                int round_cost = dist_mat[K][i] + dist_mat[i][K];\n                if (round_cost < best_round) {\n                    best_round = round_cost;\n                    first = i;\n                }\n            }\n            order.push_back(first);\n            inserted[first] = true;\n            \n            // Iteratively insert farthest points\n            while ((int)order.size() < K) {\n                int farthest_point = -1;\n                int max_min_dist = -1;\n                \n                // Find the uninserted point with maximum minimum distance to any point in the tour\n                for (int i = 0; i < K; ++i) {\n                    if (inserted[i]) continue;\n                    \n                    int min_dist = INF;\n                    // Check distance to start\n                    min_dist = min(min_dist, dist_mat[K][i]);\n                    // Check distance to all points in the current tour\n                    for (int p : order) {\n                        min_dist = min(min_dist, dist_mat[p][i]);\n                    }\n                    \n                    if (min_dist > max_min_dist) {\n                        max_min_dist = min_dist;\n                        farthest_point = i;\n                    }\n                }\n                \n                // Now find the best position to insert this farthest point\n                int best_pos = -1;\n                int best_increase = INF;\n                int m = order.size();\n                \n                // Try insertion at beginning\n                int increase = dist_mat[K][farthest_point] + dist_mat[farthest_point][order[0]] - dist_mat[K][order[0]];\n                if (increase < best_increase) {\n                    best_increase = increase;\n                    best_pos = 0;\n                }\n                \n                // Try insertion between points\n                for (int j = 1; j < m; ++j) {\n                    int a = order[j-1];\n                    int b = order[j];\n                    increase = dist_mat[a][farthest_point] + dist_mat[farthest_point][b] - dist_mat[a][b];\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_pos = j;\n                    }\n                }\n                \n                // Try insertion at end\n                increase = dist_mat[order.back()][farthest_point] + dist_mat[farthest_point][K] - dist_mat[order.back()][K];\n                if (increase < best_increase) {\n                    best_increase = increase;\n                    best_pos = m;\n                }\n                \n                order.insert(order.begin() + best_pos, farthest_point);\n                inserted[farthest_point] = true;\n            }\n        }\n        \n        int cost = compute_order_cost(order);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_order = order;\n        }\n    }\n\n    // ----- Powerful local search: 2-opt (best improvement) + Or-opt + 3-opt -----\n    auto run_local_search = [&](vector<int> order) {\n        // 2-opt with best improvement\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            int best_delta = 0;\n            int best_i = -1, best_j = -1;\n            \n            // Try all possible 2-opt moves and find the best one\n            for (int i = 0; i < K-1; ++i) {\n                for (int j = i+1; j < K; ++j) {\n                    int a = (i == 0) ? K : order[i-1];\n                    int b = order[i];\n                    int c = order[j];\n                    int d = (j == K-1) ? K : order[j+1];\n                    \n                    int old_edges = dist_mat[a][b] + dist_mat[c][d];\n                    int new_edges = dist_mat[a][c] + dist_mat[b][d];\n                    \n                    int old_internal = 0;\n                    for (int k = i; k < j; ++k) {\n                        old_internal += dist_mat[order[k]][order[k+1]];\n                    }\n                    \n                    int new_internal = 0;\n                    for (int k = j; k > i; --k) {\n                        new_internal += dist_mat[order[k]][order[k-1]];\n                    }\n                    \n                    int delta = (new_edges + new_internal) - (old_edges + old_internal);\n                    if (delta < best_delta) {\n                        best_delta = delta;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n            \n            // Apply the best move if it improves\n            if (best_delta < 0) {\n                reverse(order.begin() + best_i, order.begin() + best_j + 1);\n                improved = true;\n            }\n        }\n        \n        // Or-opt: relocate segments of length 1, 2, 3 (first improvement)\n        improved = true;\n        while (improved) {\n            improved = false;\n            for (int len = 1; len <= 3; ++len) {\n                for (int i = 0; i <= K - len; ++i) {\n                    for (int j = 0; j <= K; ++j) {\n                        if (j >= i && j <= i + len) continue;\n                        \n                        // Build new order by removing segment i..i+len-1\n                        vector<int> new_order;\n                        for (int k = 0; k < K; ++k) {\n                            if (k < i || k >= i + len) {\n                                new_order.push_back(order[k]);\n                            }\n                        }\n                        \n                        // Insert segment at position j\n                        int insert_pos = (j > i) ? j - len : j;\n                        new_order.insert(new_order.begin() + insert_pos, \n                                        order.begin() + i, order.begin() + i + len);\n                        \n                        int new_cost = compute_order_cost(new_order);\n                        int old_cost = compute_order_cost(order);\n                        \n                        if (new_cost < old_cost) {\n                            order = new_order;\n                            improved = true;\n                            break;\n                        }\n                    }\n                    if (improved) break;\n                }\n                if (improved) break;\n            }\n        }\n        \n        // Simple 3-opt: try a few random 3-opt moves\n        random_device rd;\n        mt19937 gen(rd());\n        \n        for (int attempt = 0; attempt < 100; ++attempt) {\n            if (K < 4) break;\n            \n            // Generate three random distinct positions\n            uniform_int_distribution<int> dis(0, K-1);\n            int i = dis(gen);\n            int j = dis(gen);\n            int k = dis(gen);\n            \n            // Ensure i < j < k\n            if (i > j) swap(i, j);\n            if (j > k) swap(j, k);\n            if (i > j) swap(i, j);\n            \n            if (i == j || j == k) continue;\n            \n            // Try the simplest 3-opt move: reverse the segment between i and j, and between j and k\n            vector<int> new_order = order;\n            reverse(new_order.begin() + i, new_order.begin() + j);\n            reverse(new_order.begin() + j, new_order.begin() + k);\n            \n            int new_cost = compute_order_cost(new_order);\n            int old_cost = compute_order_cost(order);\n            \n            if (new_cost < old_cost) {\n                order = new_order;\n                // Restart Or-opt after a 3-opt improvement\n                improved = true;\n                break;\n            }\n        }\n        \n        // If 3-opt improved, run Or-opt again\n        if (improved) {\n            // Recursive call might be too deep, so we just return and let the outer loop handle it\n            // Actually, we break out and the outer loop will restart\n        }\n        \n        return order;\n    };\n    \n    // Apply local search to the best initial tour\n    best_order = run_local_search(best_order);\n    best_cost = compute_order_cost(best_order);\n    \n    // Try to improve further with random restarts\n    random_device rd;\n    mt19937 gen(rd());\n    \n    for (int restart = 0; restart < 25; ++restart) {\n        // Generate a random initial tour\n        vector<int> random_order(K);\n        iota(random_order.begin(), random_order.end(), 0);\n        shuffle(random_order.begin(), random_order.end(), gen);\n        \n        // Apply local search\n        random_order = run_local_search(random_order);\n        int random_cost = compute_order_cost(random_order);\n        \n        if (random_cost < best_cost) {\n            best_cost = random_cost;\n            best_order = random_order;\n        }\n    }\n\n    // ----- Build final tour (start -> best_order -> start) -------------\n    vector<int> tour;\n    tour.push_back(K);                 // start\n    for (int x : best_order) tour.push_back(x);\n    tour.push_back(K);                 // return to start\n\n    // ----- Reconstruct the move string ---------------------------------\n    string moves;\n    for (size_t t = 0; t + 1 < tour.size(); ++t) {\n        int from_idx = tour[t], to_idx = tour[t + 1];\n        auto [fi, fj] = (from_idx < K) ? points[from_idx] : make_pair(si, sj);\n        auto [ti, tj] = (to_idx < K) ? points[to_idx] : make_pair(si, sj);\n        auto &res = dijkstra_res[from_idx];\n\n        // Backtrack from (ti,tj) to (fi,fj)\n        vector<pair<int, int>> path;\n        int ci = ti, cj = tj;\n        while (!(ci == fi && cj == fj)) {\n            path.emplace_back(ci, cj);\n            int pid = res.prev[ci][cj];\n            if (pid == -1) break;      // should not happen\n            auto [pi, pj] = from_id(pid);\n            ci = pi; cj = pj;\n        }\n        path.emplace_back(fi, fj);\n        reverse(path.begin(), path.end());\n\n        // Convert path to moves\n        for (size_t i = 0; i + 1 < path.size(); ++i) {\n            auto [cur_i, cur_j] = path[i];\n            auto [nxt_i, nxt_j] = path[i + 1];\n            for (int d = 0; d < 4; ++d) {\n                if (cur_i + di[d] == nxt_i && cur_j + dj[d] == nxt_j) {\n                    moves += dir_char[d];\n                    break;\n                }\n            }\n        }\n    }\n\n    cout << moves << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <set>\n#include <utility>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N+1, vector<int>(K));\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            cin >> d[i][k];\n        }\n    }\n    \n    // Build dependency graph\n    vector<vector<int>> children(N+1), parents(N+1);\n    vector<int> num_children(N+1, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        children[u].push_back(v);\n        parents[v].push_back(u);\n        num_children[u]++;\n    }\n    \n    // Compute critical path length (primary priority)\n    vector<int> priority1(N+1, 1);\n    for (int i = N; i >= 1; i--) {\n        for (int child : children[i]) {\n            priority1[i] = max(priority1[i], priority1[child] + 1);\n        }\n    }\n    \n    // Secondary priority: number of immediate children\n    vector<int> priority2(N+1, 0);\n    for (int i = 1; i <= N; i++) {\n        priority2[i] = children[i].size();\n    }\n    \n    // Tertiary priority: task difficulty\n    vector<int> task_difficulty(N+1, 0);\n    for (int i = 1; i <= N; i++) {\n        for (int k = 0; k < K; k++) {\n            task_difficulty[i] += d[i][k];\n        }\n    }\n    \n    // State tracking\n    vector<int> task_status(N+1, -1); // -1: not started, 0: in progress, 1: completed\n    vector<int> worker_task(M+1, -1); // -1: idle, else: task being worked on\n    vector<vector<int>> worker_skills_lower(M+1, vector<int>(K, 0)); // Lower bounds (from 1-day completions)\n    vector<vector<double>> worker_skills_estimate(M+1, vector<double>(K, 0.0)); // Estimates (from all completions)\n    vector<int> worker_confidence(M+1, 0); // Number of 1-day completions\n    vector<int> start_day(N+1, -1); // Day when task was started\n    vector<int> worker_completion_count(M+1, 0); // Total tasks completed by each worker\n    vector<int> worker_recent_completions(M+1, 0); // Tasks completed in last 40 days\n    \n    // For randomness\n    auto seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    // Learning parameters\n    const double BASE_ALPHA = 0.12;\n    \n    int day = 0;\n    while (true) {\n        day++;\n        \n        // Update recent completions (decay old completions)\n        if (day % 40 == 0) {\n            for (int w = 1; w <= M; w++) {\n                worker_recent_completions[w] = max(0, worker_recent_completions[w] - 1);\n            }\n        }\n        \n        // Find available workers\n        vector<int> available_workers;\n        for (int w = 1; w <= M; w++) {\n            if (worker_task[w] == -1) {\n                available_workers.push_back(w);\n            }\n        }\n        \n        // Find ready tasks (all dependencies completed)\n        vector<int> ready_tasks;\n        for (int t = 1; t <= N; t++) {\n            if (task_status[t] != -1) continue;\n            \n            bool all_deps_completed = true;\n            for (int parent : parents[t]) {\n                if (task_status[parent] != 1) {\n                    all_deps_completed = false;\n                    break;\n                }\n            }\n            \n            if (all_deps_completed) {\n                ready_tasks.push_back(t);\n            }\n        }\n        \n        // Sort ready tasks by combined priority\n        sort(ready_tasks.begin(), ready_tasks.end(), \n             [&](int a, int b) { \n                 if (priority1[a] != priority1[b]) return priority1[a] > priority1[b];\n                 if (priority2[a] != priority2[b]) return priority2[a] > priority2[b];\n                 return task_difficulty[a] > task_difficulty[b];\n             });\n        \n        // Prepare assignments\n        vector<pair<int, int>> assignments;\n        set<int> used_workers;\n        \n        // Dynamic exploration: high at start, then decay\n        double explore_prob = 0.20;\n        if (day > 20) explore_prob = 0.15;\n        if (day > 50) explore_prob = 0.10;\n        if (day > 150) explore_prob = 0.07;\n        if (day > 400) explore_prob = 0.05;\n        \n        // For each task in priority order, assign to best worker\n        for (int task : ready_tasks) {\n            if (available_workers.empty()) break;\n            \n            int best_worker = -1;\n            double best_score = -1e18;\n            \n            // Find best worker by score\n            for (int w : available_workers) {\n                if (used_workers.count(w)) continue;\n                \n                // Estimate completion time based on skill estimates\n                double expected_time = 1.0;\n                double total_deficiency = 0.0;\n                for (int k = 0; k < K; k++) {\n                    if (d[task][k] > worker_skills_estimate[w][k]) {\n                        total_deficiency += d[task][k] - worker_skills_estimate[w][k];\n                    }\n                }\n                if (total_deficiency > 0) {\n                    expected_time = max(1.0, total_deficiency);\n                }\n                \n                // Score calculation\n                double priority_score = priority1[task] * 1200.0 + priority2[task] * 15.0;\n                double time_penalty = expected_time * 2.8;\n                double confidence_bonus = min(worker_confidence[w] * 7.0, 70.0);\n                \n                // Skill match bonus (using lower bounds)\n                double skill_match_bonus = 0.0;\n                for (int k = 0; k < K; k++) {\n                    if (d[task][k] > 0 && worker_skills_lower[w][k] >= d[task][k]) {\n                        skill_match_bonus += 14.0;\n                    }\n                }\n                \n                // Load balancing\n                double load_penalty = worker_recent_completions[w] * 3.0;\n                \n                // Difficulty penalty for low-confidence workers\n                double difficulty_penalty = 0.0;\n                if (worker_confidence[w] < 3 && task_difficulty[task] > 90) {\n                    difficulty_penalty = 30.0;\n                }\n                \n                // Information gain bonus for exploration\n                double info_gain_bonus = 0.0;\n                if (worker_confidence[w] < 2) {\n                    info_gain_bonus = 20.0; // Encourage assigning to low-confidence workers\n                }\n                \n                double score = priority_score - time_penalty + confidence_bonus + \n                               skill_match_bonus - difficulty_penalty - load_penalty + info_gain_bonus;\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_worker = w;\n                }\n            }\n            \n            // With exploration probability, override with strategic exploration\n            uniform_real_distribution<double> explore_dist(0.0, 1.0);\n            if (explore_dist(rng) < explore_prob && available_workers.size() > 1) {\n                // Strategic exploration: assign to worker with lowest confidence\n                // Prefer workers with 0 or 1 completions\n                int min_conf = 1e9;\n                int exploration_worker = -1;\n                for (int w : available_workers) {\n                    if (used_workers.count(w)) continue;\n                    if (worker_confidence[w] < min_conf) {\n                        min_conf = worker_confidence[w];\n                        exploration_worker = w;\n                    }\n                }\n                if (exploration_worker != -1 && min_conf < 3) {\n                    best_worker = exploration_worker;\n                }\n            }\n            \n            if (best_worker != -1) {\n                assignments.emplace_back(best_worker, task);\n                used_workers.insert(best_worker);\n                \n                // Remove from available_workers\n                available_workers.erase(\n                    remove(available_workers.begin(), available_workers.end(), best_worker),\n                    available_workers.end()\n                );\n            }\n        }\n        \n        // Update worker tasks and status\n        for (auto [w, task] : assignments) {\n            worker_task[w] = task;\n            task_status[task] = 0;\n            start_day[task] = day;\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [w, t] : assignments) {\n            cout << \" \" << w << \" \" << t;\n        }\n        cout << endl;\n        cout.flush();\n        \n        // Read completion information\n        int completion_count;\n        cin >> completion_count;\n        \n        if (completion_count == -1) {\n            break; // End of simulation\n        }\n        \n        // Update based on completions\n        for (int i = 0; i < completion_count; i++) {\n            int worker;\n            cin >> worker;\n            \n            int task = worker_task[worker];\n            if (task != -1) {\n                int time_taken = day - start_day[task] + 1;\n                worker_completion_count[worker]++;\n                worker_recent_completions[worker]++;\n                \n                // Adaptive learning rate: decrease with more observations\n                double alpha = BASE_ALPHA / sqrt(worker_completion_count[worker] + 1);\n                \n                if (time_taken == 1) {\n                    // Update skill lower bounds and confidence\n                    for (int k = 0; k < K; k++) {\n                        worker_skills_lower[worker][k] = max(worker_skills_lower[worker][k], d[task][k]);\n                        // Strong update for estimate on 1-day completion\n                        worker_skills_estimate[worker][k] = \n                            0.8 * worker_skills_estimate[worker][k] + 0.2 * d[task][k];\n                    }\n                    worker_confidence[worker]++;\n                } else {\n                    // Update skill estimates based on completion time\n                    int total_req = task_difficulty[task];\n                    if (total_req > 0) {\n                        // Account for noise: w is between time_taken-3 and time_taken+3\n                        // Use the middle estimate: w_est = time_taken\n                        double w_est = time_taken;\n                        for (int k = 0; k < K; k++) {\n                            double estimated_skill = d[task][k] * (1.0 - w_est / total_req);\n                            estimated_skill = max(0.0, estimated_skill);\n                            \n                            // Conservative update: move estimate toward the new estimate\n                            worker_skills_estimate[worker][k] = \n                                (1.0 - alpha) * worker_skills_estimate[worker][k] + alpha * estimated_skill;\n                            \n                            // Ensure estimate doesn't go below lower bound\n                            worker_skills_estimate[worker][k] = \n                                max(worker_skills_estimate[worker][k], (double)worker_skills_lower[worker][k]);\n                        }\n                    }\n                }\n                \n                task_status[task] = 1;\n                worker_task[worker] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <climits>\n\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nPoint center = {400, 400};\n\ninline int manhattan(const Point& a, const Point& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Delta cost for inserting pickup X at position p and dropoff Y at position q (p <= q)\n// into the current sequence seq.\nint delta_insert(const vector<int>& seq, int p, int q, int X, int Y,\n                 const vector<vector<int>>& dist) {\n    int n = seq.size();\n    if (n == 0) {\n        // only possible: p = q = 0\n        return dist[100][X] + dist[X][Y] + dist[Y][100];\n    }\n    int A, B;\n    if (p == 0) A = 100; else A = seq[p-1];\n    if (p == n) B = 100; else B = seq[p];\n    if (q == p) {\n        // dropoff immediately after pickup\n        return dist[A][X] + dist[X][Y] + dist[Y][B] - dist[A][B];\n    } else {\n        // q > p\n        int delta = dist[A][X] + dist[X][B] - dist[A][B];\n        // Determine left and right neighbors for Y after X has been inserted\n        int left, right;\n        if (q == n) {\n            left = seq[q-1];\n            right = 100;\n        } else {\n            left = seq[q-1];\n            right = seq[q];\n        }\n        delta += dist[left][Y] + dist[Y][right] - dist[left][right];\n        return delta;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // ----- Input -----\n    vector<Point> pickup(1000), dropoff(1000);\n    for (int i = 0; i < 1000; ++i) {\n        cin >> pickup[i].x >> pickup[i].y >> dropoff[i].x >> dropoff[i].y;\n    }\n\n    // ----- Order selection -----\n    // Use a score that heavily penalizes long pickup-dropoff distances.\n    // score = d(center, pickup) + d(center, dropoff) + 0.5 * d(pickup, dropoff)\n    vector<int> order_idx(1000);\n    iota(order_idx.begin(), order_idx.end(), 0);\n    vector<double> score(1000);\n    for (int i = 0; i < 1000; ++i) {\n        int d1 = manhattan(center, pickup[i]);\n        int d2 = manhattan(center, dropoff[i]);\n        int d3 = manhattan(pickup[i], dropoff[i]);\n        score[i] = d1 + d2 + 0.5 * d3;\n    }\n    sort(order_idx.begin(), order_idx.end(),\n         [&](int a, int b) { return score[a] < score[b]; });\n    vector<int> selected(order_idx.begin(), order_idx.begin() + 50);  // original 0\u2011based indices\n\n    // ----- Build nodes for selected orders -----\n    // nodes 0..49 : pickups, nodes 50..99 : dropoffs\n    vector<Point> nodes(100);\n    for (int i = 0; i < 50; ++i) {\n        int ord = selected[i];\n        nodes[i] = pickup[ord];\n        nodes[i + 50] = dropoff[ord];\n    }\n\n    // ----- Precompute distances (including center as node 100) -----\n    vector<Point> pts(101);\n    for (int i = 0; i < 100; ++i) pts[i] = nodes[i];\n    pts[100] = center;\n    vector<vector<int>> dist(101, vector<int>(101));\n    for (int i = 0; i < 101; ++i)\n        for (int j = 0; j < 101; ++j)\n            dist[i][j] = manhattan(pts[i], pts[j]);\n\n    // ----- Initial route construction (regret-based insertion) -----\n    vector<int> seq;                     // current sequence of node indices (0..99)\n    vector<bool> used(50, false);        // which orders are already in the route\n    int current_cost = 0;                // total travel time of current route\n\n    for (int step = 0; step < 50; ++step) {\n        int best_order = -1, best_p, best_q, best_delta = INT_MAX;\n        int max_regret = -1;\n        // For each uninserted order, compute best and second best insertion deltas\n        for (int i = 0; i < 50; ++i) {\n            if (used[i]) continue;\n            int X = i;          // pickup node\n            int Y = i + 50;     // dropoff node\n            int n = seq.size();\n            int first_delta = INT_MAX, second_delta = INT_MAX;\n            int first_p, first_q;\n            // Try all insertion positions p (for pickup) and q (for dropoff) with p <= q\n            for (int p = 0; p <= n; ++p) {\n                for (int q = p; q <= n; ++q) {\n                    int delta = delta_insert(seq, p, q, X, Y, dist);\n                    if (delta < first_delta) {\n                        second_delta = first_delta;\n                        first_delta = delta;\n                        first_p = p;\n                        first_q = q;\n                    } else if (delta < second_delta) {\n                        second_delta = delta;\n                    }\n                }\n            }\n            if (first_delta == INT_MAX) continue; // should not happen\n            if (second_delta == INT_MAX) second_delta = first_delta; // only one position (unlikely)\n            int regret = second_delta - first_delta;\n            if (regret > max_regret || (regret == max_regret && first_delta < best_delta)) {\n                max_regret = regret;\n                best_delta = first_delta;\n                best_order = i;\n                best_p = first_p;\n                best_q = first_q;\n            }\n        }\n        // Insert the best order\n        int X = best_order;\n        int Y = best_order + 50;\n        seq.insert(seq.begin() + best_p, X);\n        seq.insert(seq.begin() + best_q + 1, Y);   // after first insertion, index shifts\n        used[best_order] = true;\n        current_cost += best_delta;\n    }\n\n    // ----- Simulated Annealing (swap and move moves) -----\n    int best_cost = current_cost;\n    vector<int> best_seq = seq;\n\n    // Position of each node in the current sequence\n    vector<int> pos(100);\n    for (int i = 0; i < 100; ++i) pos[seq[i]] = i;\n\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> rand_pos(0, 99);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    const int MAX_ITER = 3500000;\n    double temp = 100.0;\n    const double cooling = 0.9999991;   // slow cooling for many iterations\n\n    // Helper: can we swap positions a and b? (a < b)\n    auto can_swap = [&](int a, int b) -> bool {\n        int nodeA = seq[a], nodeB = seq[b];\n        // For nodeA\n        bool pickupA = (nodeA < 50);\n        int new_pos_pickupA, new_pos_dropoffA;\n        if (pickupA) {\n            new_pos_pickupA = b;\n            int dropoffA = nodeA + 50;\n            new_pos_dropoffA = (dropoffA == nodeB) ? a : pos[dropoffA];\n        } else {\n            new_pos_dropoffA = b;\n            int pickupA = nodeA - 50;\n            new_pos_pickupA = (pickupA == nodeB) ? a : pos[pickupA];\n        }\n        if (new_pos_pickupA >= new_pos_dropoffA) return false;\n\n        // For nodeB\n        bool pickupB = (nodeB < 50);\n        int new_pos_pickupB, new_pos_dropoffB;\n        if (pickupB) {\n            new_pos_pickupB = a;\n            int dropoffB = nodeB + 50;\n            new_pos_dropoffB = (dropoffB == nodeA) ? b : pos[dropoffB];\n        } else {\n            new_pos_dropoffB = a;\n            int pickupB = nodeB - 50;\n            new_pos_pickupB = (pickupB == nodeA) ? b : pos[pickupB];\n        }\n        if (new_pos_pickupB >= new_pos_dropoffB) return false;\n\n        return true;\n    };\n\n    // Helper: delta cost for swapping positions a and b (a < b)\n    auto delta_swap = [&](int a, int b) -> int {\n        int n1 = seq[a], n2 = seq[b];\n        int old_cost = 0, new_cost = 0;\n\n        auto get_node = [&](int p) -> int {\n            if (p < 0 || p >= 100) return 100;\n            return seq[p];\n        };\n\n        int lefts[4] = {a-1, a, b-1, b};\n        bool used[4] = {false};\n        for (int i = 0; i < 4; ++i) {\n            if (used[i]) continue;\n            int lp = lefts[i];\n            if (lp < -1 || lp >= 100) continue;\n            for (int j = i+1; j < 4; ++j)\n                if (lefts[j] == lp) used[j] = true;\n\n            int u = get_node(lp);\n            int v = get_node(lp+1);\n            old_cost += dist[u][v];\n\n            int u_new = (lp == a) ? n2 : (lp == b) ? n1 : u;\n            int v_new = (lp+1 == a) ? n2 : (lp+1 == b) ? n1 : v;\n            new_cost += dist[u_new][v_new];\n        }\n        return new_cost - old_cost;\n    };\n\n    // Helper: can we move node at position i to position j? (j != i)\n    auto can_move = [&](int i, int j) -> bool {\n        int node = seq[i];\n        bool pickup = (node < 50);\n        int cp = pickup ? node + 50 : node - 50; // counterpart\n        int cp_pos = pos[cp];\n\n        // Compute new position of counterpart after move\n        int cp_new;\n        if (cp_pos == i) {\n            // Should not happen because node != cp\n            return false;\n        } else if (cp_pos > i) {\n            cp_new = cp_pos - 1; // after removal, shift left\n        } else {\n            cp_new = cp_pos;\n        }\n        // After insertion at j, if j <= cp_new, counterpart shifts right\n        if (j <= cp_new) {\n            cp_new++;\n        }\n\n        if (pickup) {\n            return j < cp_new;\n        } else {\n            return j > cp_new;\n        }\n    };\n\n    // Helper: delta cost for moving node at position i to position j (j != i)\n    auto delta_move = [&](int i, int j) -> int {\n        int n = seq.size();\n        int X = seq[i];\n        int A = (i == 0) ? 100 : seq[i-1];\n        int B = (i == n-1) ? 100 : seq[i+1];\n        int delta1 = dist[A][B] - dist[A][X] - dist[X][B];\n\n        // Now compute C and D in the reduced sequence S' (seq without X)\n        // We insert X at position j in the final sequence, which corresponds to\n        // insertion index j_in_S = j in S' (as reasoned).\n        int j_in_S = j;\n        int C, D;\n        if (j_in_S == 0) {\n            C = 100;\n            if (n == 1) {\n                D = 100; // not happening because n=100\n            } else {\n                // Right neighbor is S'[0]\n                if (0 < i) D = seq[0];\n                else D = seq[1]; // because i=0, S'[0] = seq[1]\n            }\n        } else if (j_in_S == n-1) {\n            D = 100;\n            // Left neighbor is S'[n-2]\n            int idx = n-2; // index in S'\n            if (idx < i) C = seq[idx];\n            else C = seq[idx+1];\n        } else {\n            // General case\n            // Left neighbor: S'[j_in_S-1]\n            int idx_left = j_in_S - 1;\n            if (idx_left < i) C = seq[idx_left];\n            else C = seq[idx_left+1];\n            // Right neighbor: S'[j_in_S]\n            int idx_right = j_in_S;\n            if (idx_right < i) D = seq[idx_right];\n            else D = seq[idx_right+1];\n        }\n        int delta2 = dist[C][X] + dist[X][D] - dist[C][D];\n        return delta1 + delta2;\n    };\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        temp *= cooling;\n        if (rand_real(gen) < 0.5) {\n            // Swap move\n            int a = rand_pos(gen);\n            int b = rand_pos(gen);\n            if (a == b) continue;\n            if (a > b) swap(a, b);\n            if (!can_swap(a, b)) continue;\n\n            int delta = delta_swap(a, b);\n            if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n                int nodeA = seq[a], nodeB = seq[b];\n                seq[a] = nodeB;\n                seq[b] = nodeA;\n                pos[nodeA] = b;\n                pos[nodeB] = a;\n                current_cost += delta;\n                if (current_cost < best_cost) {\n                    best_cost = current_cost;\n                    best_seq = seq;\n                }\n            }\n        } else {\n            // Move move\n            int i = rand_pos(gen);\n            int j = rand_pos(gen);\n            if (i == j) continue;\n            if (!can_move(i, j)) continue;\n\n            int delta = delta_move(i, j);\n            if (delta < 0 || rand_real(gen) < exp(-delta / temp)) {\n                int node = seq[i];\n                // Remove node at i\n                seq.erase(seq.begin() + i);\n                // Insert at j (after removal, indices shift if j > i)\n                if (j > i) j--;\n                seq.insert(seq.begin() + j, node);\n                // Update positions\n                for (int k = 0; k < 100; ++k) pos[seq[k]] = k;\n                current_cost += delta;\n                if (current_cost < best_cost) {\n                    best_cost = current_cost;\n                    best_seq = seq;\n                }\n            }\n        }\n    }\n\n    // ----- Output -----\n    // Selected orders (convert to 1\u2011based)\n    cout << \"50\";\n    for (int idx : selected) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n\n    // Full route: center -> best_seq -> center\n    vector<Point> route;\n    route.push_back(center);\n    for (int id : best_seq) route.push_back(nodes[id]);\n    route.push_back(center);\n\n    cout << route.size();\n    for (Point p : route) cout << \" \" << p.x << \" \" << p.y;\n    cout << endl;\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Edge {\n    int u, v;\n};\n\nclass DSU {\n    vector<int> parent, rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    int unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return x;\n        if (rank[x] < rank[y]) {\n            parent[x] = y;\n            return y;\n        } else if (rank[x] > rank[y]) {\n            parent[y] = x;\n            return x;\n        } else {\n            parent[y] = x;\n            rank[x]++;\n            return x;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges[i] = {u, v};\n    }\n\n    DSU dsu(N);\n    vector<vector<int>> comp_best(N, vector<int>(N, INF));\n    for (int i = 0; i < N; i++) {\n        comp_best[i][i] = INF;\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        int u = edges[i].u, v = edges[i].v;\n        int ru = dsu.find(u);\n        int rv = dsu.find(v);\n        if (ru == rv) {\n            cout << 0 << endl;\n        } else {\n            if (l < comp_best[ru][rv]) {\n                comp_best[ru][rv] = l;\n                comp_best[rv][ru] = l;\n            }\n            if (l <= 2 * comp_best[ru][rv]) {\n                cout << 1 << endl;\n                int new_root = dsu.unite(ru, rv);\n                int old_root = (new_root == ru) ? rv : ru;\n                for (int k = 0; k < N; k++) {\n                    if (k == new_root || k == old_root) continue;\n                    if (comp_best[old_root][k] < comp_best[new_root][k]) {\n                        comp_best[new_root][k] = comp_best[old_root][k];\n                        comp_best[k][new_root] = comp_best[new_root][k];\n                    }\n                }\n                comp_best[new_root][new_root] = INF;\n            } else {\n                cout << 0 << endl;\n            }\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID = 30;\nconst int MAX_TURNS = 300;\n\nint N, M;\nvector<int> pet_x, pet_y, pet_type;\nvector<int> human_x, human_y;\nbool wall[GRID+1][GRID+1] = {false};\n\nconst int dx[4] = {1, -1, 0, 0};\nconst int dy[4] = {0, 0, 1, -1};\n\nbool inside(int x, int y) {\n    return 1 <= x && x <= GRID && 1 <= y && y <= GRID;\n}\n\nbool passable(int x, int y) {\n    return inside(x, y) && !wall[x][y];\n}\n\nbool has_pet_at(int x, int y) {\n    for (int i = 0; i < N; ++i)\n        if (pet_x[i] == x && pet_y[i] == y)\n            return true;\n    return false;\n}\n\nbool has_adjacent_pet(int x, int y) {\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + dx[d], ny = y + dy[d];\n        if (inside(nx, ny) && has_pet_at(nx, ny))\n            return true;\n    }\n    return false;\n}\n\nbool has_human_at(int x, int y) {\n    for (int i = 0; i < M; ++i)\n        if (human_x[i] == x && human_y[i] == y)\n            return true;\n    return false;\n}\n\nbool can_build(int x, int y) {\n    return inside(x, y) && !wall[x][y] && !has_pet_at(x, y) && \n           !has_human_at(x, y) && !has_adjacent_pet(x, y);\n}\n\n// Safe movement: check if target square is passable and not occupied by a pet\nchar safe_move_towards(int cx, int cy, int tx, int ty) {\n    if (cx == tx && cy == ty) return '.';\n    \n    // Try to move in the direction that reduces distance\n    int best_dx = 0, best_dy = 0;\n    int best_dist = abs(cx - tx) + abs(cy - ty);\n    \n    // Check all four directions\n    for (int d = 0; d < 4; ++d) {\n        int nx = cx + dx[d], ny = cy + dy[d];\n        if (passable(nx, ny) && !has_pet_at(nx, ny)) {\n            int dist = abs(nx - tx) + abs(ny - ty);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dx = dx[d];\n                best_dy = dy[d];\n            }\n        }\n    }\n    \n    if (best_dx == 0 && best_dy == 0) return '.'; // No valid move\n    \n    if (best_dx == 1) return 'D';\n    if (best_dx == -1) return 'U';\n    if (best_dy == 1) return 'R';\n    if (best_dy == -1) return 'L';\n    return '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    pet_x.resize(N); pet_y.resize(N); pet_type.resize(N);\n    for (int i = 0; i < N; ++i)\n        cin >> pet_x[i] >> pet_y[i] >> pet_type[i];\n    cin >> M;\n    human_x.resize(M); human_y.resize(M);\n    for (int i = 0; i < M; ++i)\n        cin >> human_x[i] >> human_y[i];\n\n    // Strategy: Build walls around each human to create small safe zones,\n    // and move towards other humans to merge safe zones.\n    \n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\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            \n            // First priority: build walls in the four cardinal directions if safe\n            bool built = false;\n            for (int d = 0; d < 4; ++d) {\n                int wx = hx + dx[d], wy = hy + dy[d];\n                if (can_build(wx, wy)) {\n                    // Determine build action based on direction\n                    if (dx[d] == -1) actions[i] = 'u';  // Build up\n                    else if (dx[d] == 1) actions[i] = 'd'; // Build down\n                    else if (dy[d] == -1) actions[i] = 'l'; // Build left\n                    else if (dy[d] == 1) actions[i] = 'r'; // Build right\n                    \n                    wall[wx][wy] = true;\n                    built = true;\n                    break;\n                }\n            }\n            \n            if (!built) {\n                // Second priority: move towards the nearest other human\n                int nearest_human_dist = 1000;\n                int target_x = hx, target_y = hy;\n                \n                for (int j = 0; j < M; ++j) {\n                    if (i == j) continue;\n                    int dist = abs(hx - human_x[j]) + abs(hy - human_y[j]);\n                    if (dist < nearest_human_dist) {\n                        nearest_human_dist = dist;\n                        target_x = human_x[j];\n                        target_y = human_y[j];\n                    }\n                }\n                \n                if (nearest_human_dist > 1) {  // Only move if not already adjacent\n                    actions[i] = safe_move_towards(hx, hy, target_x, target_y);\n                } else {\n                    // Already adjacent or no other human, try to move away from pets\n                    int max_min_pet_dist = -1;\n                    int best_dx = 0, best_dy = 0;\n                    \n                    for (int d = 0; d < 4; ++d) {\n                        int nx = hx + dx[d], ny = hy + dy[d];\n                        if (passable(nx, ny) && !has_pet_at(nx, ny)) {\n                            int min_pet_dist = 1000;\n                            for (int p = 0; p < N; ++p) {\n                                int dist = abs(nx - pet_x[p]) + abs(ny - pet_y[p]);\n                                min_pet_dist = min(min_pet_dist, dist);\n                            }\n                            \n                            if (min_pet_dist > max_min_pet_dist) {\n                                max_min_pet_dist = min_pet_dist;\n                                best_dx = dx[d];\n                                best_dy = dy[d];\n                            }\n                        }\n                    }\n                    \n                    if (max_min_pet_dist > -1) {\n                        if (best_dx == 1) actions[i] = 'D';\n                        else if (best_dx == -1) actions[i] = 'U';\n                        else if (best_dy == 1) actions[i] = 'R';\n                        else if (best_dy == -1) actions[i] = 'L';\n                    } else {\n                        actions[i] = '.';\n                    }\n                }\n            }\n        }\n        \n        // Output actions\n        for (char c : actions) cout << c;\n        cout << endl;\n        cout.flush();\n        \n        // Update human positions based on actions (movement only)\n        for (int i = 0; i < M; ++i) {\n            if (actions[i] == 'U') human_x[i]--;\n            else if (actions[i] == 'D') human_x[i]++;\n            else if (actions[i] == 'L') human_y[i]--;\n            else if (actions[i] == 'R') human_y[i]++;\n            // Build actions (lowercase) don't move humans\n        }\n        \n        // Read pet movements\n        for (int i = 0; i < N; ++i) {\n            string s; cin >> s;\n            for (char c : s) {\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 20, W = 20;\nconst int N = H * W; // 400\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nint si, sj, ti, tj;\ndouble p;\nint h[H][W - 1]; // horizontal walls: between (i,j) and (i,j+1)\nint v[H - 1][W]; // vertical walls: between (i,j) and (i+1,j)\n\nstruct MoveData {\n    int nxt_idx;      // linear index of neighbor, -1 if blocked\n    float stay;       // probability to stay\n    float move;       // probability to move (0 if blocked)\n    bool is_target;   // does moving lead directly to the office?\n};\nMoveData move_info[N][4];\nint dir_to_idx[256];\n\n// Convert (i,j) to linear index\ninline int to_idx(int i, int j) { return i * W + j; }\n// Convert linear index to (i,j)\ninline pair<int, int> to_pos(int idx) { return {idx / W, idx % W}; }\n\n// Precompute transition data for every cell and direction.\nvoid precompute_move_info() {\n    for (int i = 0; i < H; ++i) {\n        for (int j = 0; j < W; ++j) {\n            int idx = to_idx(i, j);\n            for (int d = 0; d < 4; ++d) {\n                auto& data = move_info[idx][d];\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                bool blocked = false;\n                if (d == 0) { // U\n                    if (i == 0) blocked = true;\n                    else if (v[i - 1][j] == 1) blocked = true;\n                } else if (d == 1) { // D\n                    if (i == H - 1) blocked = true;\n                    else if (v[i][j] == 1) blocked = true;\n                } else if (d == 2) { // L\n                    if (j == 0) blocked = true;\n                    else if (h[i][j - 1] == 1) blocked = true;\n                } else { // R\n                    if (j == W - 1) blocked = true;\n                    else if (h[i][j] == 1) blocked = true;\n                }\n                data.stay = p + (1 - p) * blocked;\n                data.move = blocked ? 0.0f : (1 - p);\n                data.is_target = (!blocked && ni == ti && nj == tj);\n                if (!blocked) {\n                    data.nxt_idx = to_idx(ni, nj);\n                } else {\n                    data.nxt_idx = -1;\n                }\n            }\n        }\n    }\n    dir_to_idx['U'] = 0;\n    dir_to_idx['D'] = 1;\n    dir_to_idx['L'] = 2;\n    dir_to_idx['R'] = 3;\n}\n\n// Compute expected score for a given command string.\ndouble compute_score(const string& s) {\n    float cur[N] = {0};\n    float nxt[N];\n    cur[to_idx(si, sj)] = 1.0f;\n    double score = 0.0;\n    int L = s.size();\n    for (int step = 0; step < L; ++step) {\n        int d = dir_to_idx[s[step]];\n        // Clear nxt array\n        fill(nxt, nxt + N, 0.0f);\n        for (int idx = 0; idx < N; ++idx) {\n            float prob = cur[idx];\n            if (prob == 0.0f) continue;\n            const MoveData& data = move_info[idx][d];\n            nxt[idx] += prob * data.stay;\n            if (data.move > 0) {\n                if (data.is_target) {\n                    score += (401 - (step + 1)) * prob * data.move;\n                } else {\n                    nxt[data.nxt_idx] += prob * data.move;\n                }\n            }\n        }\n        swap(cur, nxt);\n    }\n    return score;\n}\n\n// BFS to find a shortest valid path (ignoring forgetting).\nstring bfs_path() {\n    queue<pair<int, int>> q;\n    vector<vector<bool>> visited(H, vector<bool>(W, false));\n    vector<vector<int>> parent_i(H, vector<int>(W, -1));\n    vector<vector<int>> parent_j(H, vector<int>(W, -1));\n    q.emplace(si, sj);\n    visited[si][sj] = true;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; ++d) {\n            const MoveData& data = move_info[to_idx(i, j)][d];\n            if (data.move > 0) { // move allowed\n                auto [ni, nj] = to_pos(data.nxt_idx);\n                if (!visited[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent_i[ni][nj] = i;\n                    parent_j[ni][nj] = j;\n                    q.emplace(ni, nj);\n                }\n            }\n        }\n    }\n    // Reconstruct path from target to start.\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int pi = parent_i[ci][cj];\n        int pj = parent_j[ci][cj];\n        if (pi == ci - 1) path += 'D';\n        else if (pi == ci + 1) path += 'U';\n        else if (pj == cj - 1) path += 'R';\n        else if (pj == cj + 1) path += 'L';\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Repeat a string to reach length max_len (truncate if longer).\nstring repeat_to_length(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U'); // fallback\n    string result;\n    while (result.size() < max_len) {\n        result += s;\n    }\n    result.resize(max_len);\n    return result;\n}\n\n// Generate a random string biased towards the target.\nstring random_biased_string(int len, mt19937& rng) {\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    string s;\n    int ci = si, cj = sj;\n    for (int i = 0; i < len; ++i) {\n        // With probability 0.6, try to move towards target.\n        if (uniform(rng) < 0.6) {\n            // Choose a direction that reduces Manhattan distance if possible.\n            int best_dir = -1;\n            int best_dist = 1000;\n            for (int d = 0; d < 4; ++d) {\n                const MoveData& data = move_info[to_idx(ci, cj)][d];\n                if (data.move > 0) {\n                    auto [ni, nj] = to_pos(data.nxt_idx);\n                    int dist = abs(ni - ti) + abs(nj - tj);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_dir = d;\n                    }\n                }\n            }\n            if (best_dir != -1) {\n                s += dir_chars[best_dir];\n                auto [ni, nj] = to_pos(move_info[to_idx(ci, cj)][best_dir].nxt_idx);\n                ci = ni; cj = nj;\n                continue;\n            }\n        }\n        // Otherwise random direction.\n        int d = rand_dir(rng);\n        const MoveData& data = move_info[to_idx(ci, cj)][d];\n        if (data.move > 0) {\n            s += dir_chars[d];\n            auto [ni, nj] = to_pos(data.nxt_idx);\n            ci = ni; cj = nj;\n        } else {\n            // If blocked, just add a random direction (will stay).\n            s += dir_chars[d];\n        }\n    }\n    return s;\n}\n\n// Generate a string where each move is duplicated (e.g., DDRR becomes DDRRDDRR).\nstring duplicated_moves(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U');\n    string result;\n    for (char c : s) {\n        result += c;\n        result += c;\n        if (result.size() >= max_len) break;\n    }\n    result.resize(max_len);\n    return result;\n}\n\n// Generate a string where each move is tripled (e.g., DDRR becomes DDDRRRDD).\nstring tripled_moves(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U');\n    string result;\n    for (char c : s) {\n        result += c;\n        result += c;\n        result += c;\n        if (result.size() >= max_len) break;\n    }\n    result.resize(max_len);\n    return result;\n}\n\n// Generate a string where each move is quadrupled (e.g., DDRR becomes DDDDRRRRDDDD).\nstring quadrupled_moves(const string& s, int max_len) {\n    if (s.empty()) return string(max_len, 'U');\n    string result;\n    for (char c : s) {\n        result += c;\n        result += c;\n        result += c;\n        result += c;\n        if (result.size() >= max_len) break;\n    }\n    result.resize(max_len);\n    return result;\n}\n\n// Ensure the string contains only UDLR and length between 1 and 200.\nstring sanitize(const string& s) {\n    if (s.empty()) return \"U\";\n    string res = s;\n    for (char& c : res) {\n        if (c != 'U' && c != 'D' && c != 'L' && c != 'R') {\n            c = 'U'; // replace any invalid char with 'U'\n        }\n    }\n    if (res.size() > 200) res.resize(200);\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> si >> sj >> ti >> tj >> p;\n    for (int i = 0; i < 20; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 19; ++j) h[i][j] = line[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string line; cin >> line;\n        for (int j = 0; j < 20; ++j) v[i][j] = line[j] - '0';\n    }\n\n    precompute_move_info();\n\n    // Random generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_dir(0, 3);\n    auto rand_index = [&](int n) -> int {\n        return uniform_int_distribution<int>(0, n - 1)(rng);\n    };\n\n    // Initial candidates\n    string best_str;\n    double best_score = -1;\n\n    // Candidate 1: BFS path\n    string bfs_str = bfs_path();\n    bfs_str = sanitize(bfs_str);\n    double bfs_score = compute_score(bfs_str);\n    if (bfs_score > best_score) {\n        best_score = bfs_score;\n        best_str = bfs_str;\n    }\n\n    // Candidate 2: doubled BFS path if fits\n    if (bfs_str.size() * 2 <= 200) {\n        string doubled = bfs_str + bfs_str;\n        doubled = sanitize(doubled);\n        double doubled_score = compute_score(doubled);\n        if (doubled_score > best_score) {\n            best_score = doubled_score;\n            best_str = doubled;\n        }\n    }\n\n    // Candidate 3: repeated BFS path to length 200\n    string repeated = repeat_to_length(bfs_str, 200);\n    repeated = sanitize(repeated);\n    double repeated_score = compute_score(repeated);\n    if (repeated_score > best_score) {\n        best_score = repeated_score;\n        best_str = repeated;\n    }\n\n    // Candidate 4: duplicated moves version of BFS path\n    string dup = duplicated_moves(bfs_str, 200);\n    dup = sanitize(dup);\n    double dup_score = compute_score(dup);\n    if (dup_score > best_score) {\n        best_score = dup_score;\n        best_str = dup;\n    }\n\n    // Candidate 5: tripled moves version of BFS path if fits\n    if (bfs_str.size() * 3 <= 200) {\n        string trip = tripled_moves(bfs_str, 200);\n        trip = sanitize(trip);\n        double trip_score = compute_score(trip);\n        if (trip_score > best_score) {\n            best_score = trip_score;\n            best_str = trip;\n        }\n    }\n\n    // Candidate 6: quadrupled moves version of BFS path if fits\n    if (bfs_str.size() * 4 <= 200) {\n        string quad = quadrupled_moves(bfs_str, 200);\n        quad = sanitize(quad);\n        double quad_score = compute_score(quad);\n        if (quad_score > best_score) {\n            best_score = quad_score;\n            best_str = quad;\n        }\n    }\n\n    // Candidate 7-11: random biased strings (5 of them)\n    for (int trial = 0; trial < 5; ++trial) {\n        string rand_str = random_biased_string(200, rng);\n        rand_str = sanitize(rand_str);\n        double rand_score = compute_score(rand_str);\n        if (rand_score > best_score) {\n            best_score = rand_score;\n            best_str = rand_str;\n        }\n    }\n\n    string current = best_str;\n    double current_score = best_score;\n\n    const double time_limit = 1.85; // seconds\n    auto start_time = chrono::steady_clock::now();\n\n    double start_temp = 1.0;\n    double end_temp = 1e-4;\n\n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > time_limit) break;\n        double progress = elapsed / time_limit;\n        double T = start_temp * pow(end_temp / start_temp, progress);\n\n        // Generate neighbour solution\n        string neighbour = current;\n        int L = neighbour.size();\n\n        // Operation probabilities: increase insert a bit\n        double op = uniform(rng);\n        if (op < 0.15) { // replace single\n            int pos = rand_index(L);\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour[pos] = newc;\n        } else if (op < 0.50 && L < 200) { // insert (increased probability)\n            int pos = rand_index(L + 1);\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour.insert(neighbour.begin() + pos, newc);\n        } else if (op < 0.70 && L > 1) { // delete\n            int pos = rand_index(L);\n            neighbour.erase(neighbour.begin() + pos);\n        } else if (op < 0.80 && L >= 2) { // swap adjacent\n            int pos = rand_index(L - 1);\n            swap(neighbour[pos], neighbour[pos + 1]);\n        } else if (op < 0.90 && L >= 5) { // reverse substring\n            int max_len = min(10, L - 1);\n            int len = uniform_int_distribution<int>(2, max_len)(rng);\n            int start = rand_index(L - len + 1);\n            reverse(neighbour.begin() + start, neighbour.begin() + start + len);\n        } else if (L >= 5) { // block replace\n            int max_len = min(5, L);\n            int len = uniform_int_distribution<int>(2, max_len)(rng);\n            int start = rand_index(L - len + 1);\n            string block;\n            for (int i = 0; i < len; ++i) {\n                block += dir_chars[rand_dir(rng)];\n            }\n            neighbour.replace(start, len, block);\n        } else {\n            // fallback: replace\n            int pos = rand_index(L);\n            char newc = dir_chars[rand_dir(rng)];\n            neighbour[pos] = newc;\n        }\n\n        neighbour = sanitize(neighbour);\n        double new_score = compute_score(neighbour);\n        double delta = new_score - current_score;\n        if (delta > 0 || uniform(rng) < exp(delta / T)) {\n            current = move(neighbour);\n            current_score = new_score;\n            if (current_score > best_score) {\n                best_score = current_score;\n                best_str = current;\n            }\n        }\n    }\n\n    best_str = sanitize(best_str);\n    cout << best_str << endl;\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cstring>\n#include <cmath>\n#include <queue>\n\nusing namespace std;\n\nconst int N = 30;\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\nconst int 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 grid[N][N];\nint conn[N][N][4];\n\nvoid compute_conn(int rotations[][N]) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int type = grid[i][j];\n            int r = rotations[i][j];\n            for (int d = 0; d < 4; d++) {\n                int d0 = (d - r + 4) % 4;\n                if (to[type][d0] == -1) {\n                    conn[i][j][d] = -1;\n                } else {\n                    conn[i][j][d] = (to[type][d0] + r) % 4;\n                }\n            }\n        }\n    }\n}\n\n// Fast score computation\nint compute_score_fast(int rotations[][N]) {\n    compute_conn(rotations);\n    static bool visited[3600];\n    memset(visited, 0, sizeof(visited));\n    \n    vector<int> cycle_lengths;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                int start_id = (i*N + j)*4 + d;\n                if (conn[i][j][d] == -1 || visited[start_id]) continue;\n                \n                int current_id = start_id;\n                int prev_id = -1;\n                int length = 0;\n                bool is_cycle = true;\n                \n                while (true) {\n                    if (visited[current_id]) {\n                        is_cycle = (current_id == start_id);\n                        break;\n                    }\n                    \n                    visited[current_id] = true;\n                    length++;\n                    \n                    int tile_id = current_id / 4;\n                    int ci = tile_id / N;\n                    int cj = tile_id % N;\n                    int cd = current_id % 4;\n                    \n                    // Find next half-edge\n                    int d2 = conn[ci][cj][cd];\n                    int internal_id = (ci*N + cj)*4 + d2;\n                    int external_id = -1;\n                    int ni = ci + di[cd];\n                    int nj = cj + dj[cd];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n                        conn[ni][nj][(cd+2)%4] != -1) {\n                        external_id = (ni*N + nj)*4 + (cd+2)%4;\n                    }\n                    \n                    int next_id = -1;\n                    if (internal_id != prev_id) {\n                        next_id = internal_id;\n                    } else if (external_id != -1 && external_id != prev_id) {\n                        next_id = external_id;\n                    } else {\n                        is_cycle = false;\n                        break;\n                    }\n                    \n                    prev_id = current_id;\n                    current_id = next_id;\n                }\n                \n                if (is_cycle && length >= 4) {\n                    cycle_lengths.push_back(length / 2);\n                }\n            }\n        }\n    }\n    \n    if (cycle_lengths.empty()) return 0;\n    sort(cycle_lengths.rbegin(), cycle_lengths.rend());\n    int L1 = cycle_lengths[0];\n    int L2 = cycle_lengths.size() > 1 ? cycle_lengths[1] : 0;\n    return L1 * L2;\n}\n\n// Count connections for a tile (heuristic for greedy)\nint count_connections(int i, int j, int rotations[][N]) {\n    compute_conn(rotations);\n    int connections = 0;\n    for (int d = 0; d < 4; d++) {\n        if (conn[i][j][d] == -1) continue;\n        int ni = i + di[d];\n        int nj = j + dj[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && \n            conn[ni][nj][(d+2)%4] != -1) {\n            connections++;\n        }\n    }\n    return connections;\n}\n\n// Generate a more diverse set of initial solutions\nvoid generate_diverse_initial_solution(int rotations[][N], int strategy) {\n    if (strategy == 0) {\n        // Heuristic: align straight tiles with neighbors\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int type = grid[i][j];\n                if (type == 6) {  // Horizontal straight\n                    rotations[i][j] = 0;\n                    // Check if should be vertical\n                    int vertical_neighbors = 0;\n                    if (i > 0 && (grid[i-1][j] == 7 || grid[i-1][j] == 6)) vertical_neighbors++;\n                    if (i < N-1 && (grid[i+1][j] == 7 || grid[i+1][j] == 6)) vertical_neighbors++;\n                    if (vertical_neighbors > 0) rotations[i][j] = 1;\n                } else if (type == 7) {  // Vertical straight\n                    rotations[i][j] = 0;\n                    // Check if should be horizontal\n                    int horizontal_neighbors = 0;\n                    if (j > 0 && (grid[i][j-1] == 6 || grid[i][j-1] == 7)) horizontal_neighbors++;\n                    if (j < N-1 && (grid[i][j+1] == 6 || grid[i][j+1] == 7)) horizontal_neighbors++;\n                    if (horizontal_neighbors > 0) rotations[i][j] = 1;\n                } else {\n                    rotations[i][j] = rand() % 4;\n                }\n            }\n        }\n    } else if (strategy == 1) {\n        // All horizontal straights\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int type = grid[i][j];\n                if (type == 6) {\n                    rotations[i][j] = 0;  // Horizontal\n                } else if (type == 7) {\n                    rotations[i][j] = 1;  // Horizontal (rotated once from vertical)\n                } else {\n                    rotations[i][j] = rand() % 4;\n                }\n            }\n        }\n    } else if (strategy == 2) {\n        // All vertical straights\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int type = grid[i][j];\n                if (type == 6) {\n                    rotations[i][j] = 1;  // Vertical (rotated once from horizontal)\n                } else if (type == 7) {\n                    rotations[i][j] = 0;  // Vertical\n                } else {\n                    rotations[i][j] = rand() % 4;\n                }\n            }\n        }\n    } else {\n        // Random\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                rotations[i][j] = rand() % 4;\n            }\n        }\n    }\n}\n\n// Run simulated annealing\nvoid run_sa(int rotations[][N], int& current_score, int& best_score, int best_rotations[][N], \n            int steps, double init_temp, double cooling) {\n    double temperature = init_temp;\n    \n    for (int step = 0; step < steps; step++) {\n        // Pick random tile\n        int i = rand() % N;\n        int j = rand() % N;\n        int old_rot = rotations[i][j];\n        int new_rot = rand() % 4;\n        \n        if (new_rot == old_rot) continue;\n        \n        rotations[i][j] = new_rot;\n        int new_score = compute_score_fast(rotations);\n        \n        int score_diff = new_score - current_score;\n        if (score_diff > 0 || \n            (rand() / (double)RAND_MAX) < exp(score_diff / temperature)) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_rotations, rotations, N * N * sizeof(int));\n            }\n        } else {\n            rotations[i][j] = old_rot;\n        }\n        \n        temperature *= cooling;\n    }\n}\n\n// Final greedy optimization over all tiles\nvoid final_greedy(int rotations[][N], int& current_score, int& best_score, int best_rotations[][N]) {\n    for (int pass = 0; pass < 2; pass++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int original = rotations[i][j];\n                int best_local_score = current_score;\n                int best_local_rot = original;\n                \n                for (int r = 0; r < 4; r++) {\n                    if (r == original) continue;\n                    rotations[i][j] = r;\n                    int new_score = compute_score_fast(rotations);\n                    if (new_score > best_local_score) {\n                        best_local_score = new_score;\n                        best_local_rot = r;\n                    }\n                }\n                \n                rotations[i][j] = best_local_rot;\n                if (best_local_score > current_score) {\n                    current_score = best_local_score;\n                    if (current_score > best_score) {\n                        best_score = current_score;\n                        memcpy(best_rotations, rotations, N * N * sizeof(int));\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[j] - '0';\n        }\n    }\n\n    srand(time(0));\n    int current_rotations[N][N];\n    int best_rotations[N][N];\n    int best_score = 0;\n    \n    // Try multiple diverse starting configurations\n    for (int trial = 0; trial < 6; trial++) {\n        generate_diverse_initial_solution(current_rotations, trial % 4);\n        \n        // Quick greedy optimization (2 passes)\n        for (int pass = 0; pass < 2; pass++) {\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    int best_rot = current_rotations[i][j];\n                    int best_connections = count_connections(i, j, current_rotations);\n                    \n                    for (int r = 0; r < 4; r++) {\n                        if (r == current_rotations[i][j]) continue;\n                        current_rotations[i][j] = r;\n                        int connections = count_connections(i, j, current_rotations);\n                        if (connections > best_connections) {\n                            best_connections = connections;\n                            best_rot = r;\n                        }\n                    }\n                    current_rotations[i][j] = best_rot;\n                }\n            }\n        }\n        \n        int score = compute_score_fast(current_rotations);\n        if (score > best_score) {\n            best_score = score;\n            memcpy(best_rotations, current_rotations, sizeof(current_rotations));\n        }\n    }\n    \n    // Run simulated annealing from the best starting point\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    int current_score = best_score;\n    run_sa(current_rotations, current_score, best_score, best_rotations, 20000, 12.0, 0.9998);\n    \n    // Final thorough optimization\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    current_score = best_score;\n    final_greedy(current_rotations, current_score, best_score, best_rotations);\n    \n    // Second SA run with different parameters\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    current_score = best_score;\n    run_sa(current_rotations, current_score, best_score, best_rotations, 10000, 6.0, 0.9996);\n    \n    // Final greedy optimization\n    memcpy(current_rotations, best_rotations, sizeof(current_rotations));\n    current_score = best_score;\n    final_greedy(current_rotations, current_score, best_score, best_rotations);\n\n    // Output best solution found\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <cstring>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\n// Direction arrays: L, R, U, D\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'L', 'R', 'U', 'D'};\nconst int dir_bit[4] = {1, 4, 2, 8};  // L=1, R=4, U=2, D=8\nconst int opposite[4] = {1, 0, 3, 2};  // opposite directions\n\nint N, T;\nvector<vector<int>> board;\nint empty_r, empty_c;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Check if moving in direction d is valid\nbool can_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    return nr >= 0 && nr < N && nc >= 0 && nc < N && board[nr][nc] != 0;\n}\n\n// Execute move in direction d\nvoid make_move(int d) {\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    empty_r = nr;\n    empty_c = nc;\n}\n\n// Enhanced board analysis: returns (max_tree_size, extra_edges, components, total_tree_vertices)\ntuple<int, int, int, int> analyze_board() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree_size = 0;\n    int total_components = 0;\n    int total_vertices = 0;\n    int total_edges = 0;\n    int total_tree_vertices = 0;\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]) {\n                total_components++;\n                // BFS to find component\n                vector<pair<int,int>> component;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [r, c] = q.front();\n                    q.pop();\n                    component.push_back({r, c});\n                    total_vertices++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nr = r + dy[d];\n                        int nc = c + dx[d];\n                        if (nr >= 0 && nr < N && nc >= 0 && nc < N && \n                            board[nr][nc] != 0 && !visited[nr][nc]) {\n                            // Check if connection exists\n                            int curr_bit = dir_bit[d];\n                            int next_bit = dir_bit[opposite[d]];\n                            if ((board[r][c] & curr_bit) && (board[nr][nc] & next_bit)) {\n                                visited[nr][nc] = true;\n                                q.push({nr, nc});\n                            }\n                        }\n                    }\n                }\n                \n                // Count edges in component\n                int V = component.size();\n                int E = 0;\n                vector<vector<bool>> in_comp(N, vector<bool>(N, false));\n                for (auto [r, c] : component) {\n                    in_comp[r][c] = true;\n                }\n                \n                for (auto [r, c] : component) {\n                    // Check right neighbor\n                    if (c + 1 < N && in_comp[r][c+1]) {\n                        if ((board[r][c] & 4) && (board[r][c+1] & 1)) {\n                            E++;\n                        }\n                    }\n                    // Check down neighbor\n                    if (r + 1 < N && in_comp[r+1][c]) {\n                        if ((board[r][c] & 8) && (board[r+1][c] & 2)) {\n                            E++;\n                        }\n                    }\n                }\n                \n                total_edges += E;\n                \n                // Check if this component is a tree\n                if (E == V - 1) {\n                    max_tree_size = max(max_tree_size, V);\n                    total_tree_vertices += V;\n                }\n            }\n        }\n    }\n    \n    // Calculate extra edges (edges that create cycles)\n    int extra_edges = total_edges - (total_vertices - total_components);\n    if (extra_edges < 0) extra_edges = 0;\n    \n    return {max_tree_size, extra_edges, total_components, total_tree_vertices};\n}\n\n// Strategic move evaluation with lookahead\npair<int, int> evaluate_move(int d, int step, bool use_lookahead = true) {\n    // Simulate move\n    int nr = empty_r + dy[d];\n    int nc = empty_c + dx[d];\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    int saved_er = empty_r, saved_ec = empty_c;\n    empty_r = nr;\n    empty_c = nc;\n    \n    auto [new_max, new_extra_edges, new_components, new_total_tree_vertices] = analyze_board();\n    \n    // Get old state for comparison\n    empty_r = saved_er;\n    empty_c = saved_ec;\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    auto [old_max, old_extra_edges, old_components, old_total_tree_vertices] = analyze_board();\n    // Re-simulate\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    empty_r = nr;\n    empty_c = nc;\n    \n    // Calculate score\n    int score = 0;\n    double progress = (double)step / T;\n    \n    if (progress < 0.6) {\n        // Early phase: focus on building large trees\n        score = new_max * 1000000;\n        \n        // Reward for connecting components\n        if (new_components < old_components) {\n            score += 70000;\n        }\n        \n        // Reward for increasing tree size\n        if (new_max > old_max) {\n            score += 40000;\n        }\n        \n        // Reward for increasing total vertices in trees\n        score += (new_total_tree_vertices - old_total_tree_vertices) * 1500;\n    } else if (progress < 0.85) {\n        // Middle phase: balance tree building and cycle reduction\n        score = new_max * 900000;\n        \n        // Reward for connecting components\n        if (new_components < old_components) {\n            score += 60000;\n        }\n        \n        // Penalize extra edges\n        score -= new_extra_edges * 8000;\n    } else {\n        // Late phase: focus on cycle reduction and optimization\n        score = new_max * 800000;\n        \n        // Penalize extra edges heavily\n        score -= new_extra_edges * 12000;\n        \n        // Reward for reducing extra edges\n        if (new_extra_edges < old_extra_edges) {\n            score += 35000;\n        }\n    }\n    \n    // Bonus for achieving full tree\n    if (new_max == N * N - 1) {\n        score += 5000000;\n    }\n    \n    // Penalty for many components\n    score -= new_components * 80;\n    \n    // Optional lookahead (only use occasionally to save time)\n    if (use_lookahead && step % 5 == 0 && progress < 0.8) {\n        int best_future_score = -100000000;\n        for (int d2 = 0; d2 < 4; d2++) {\n            if (!can_move(d2)) continue;\n            \n            // Simulate second move\n            int nr2 = empty_r + dy[d2];\n            int nc2 = empty_c + dx[d2];\n            swap(board[empty_r][empty_c], board[nr2][nc2]);\n            int saved_er2 = empty_r, saved_ec2 = empty_c;\n            empty_r = nr2;\n            empty_c = nc2;\n            \n            auto [future_max, future_extra, future_comp, future_tree_vertices] = analyze_board();\n            int future_score = future_max * 1000000 - future_extra * 10000 - future_comp * 100;\n            \n            if (future_max == N * N - 1) {\n                future_score += 5000000;\n            }\n            \n            best_future_score = max(best_future_score, future_score);\n            \n            // Restore\n            empty_r = saved_er2;\n            empty_c = saved_ec2;\n            swap(board[empty_r][empty_c], board[nr2][nc2]);\n        }\n        \n        // Combine current and future scores\n        score = score * 0.8 + best_future_score * 0.2;\n    }\n    \n    // Restore board\n    empty_r = saved_er;\n    empty_c = saved_ec;\n    swap(board[empty_r][empty_c], board[nr][nc]);\n    \n    return {score, new_max};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    board.resize(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] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_r = i;\n                empty_c = j;\n            }\n        }\n    }\n    \n    string moves;\n    auto [current_max, current_extra_edges, current_components, current_total_tree_vertices] = analyze_board();\n    \n    // Adaptive parameters\n    double random_prob = 0.07;\n    int stagnation_count = 0;\n    int last_best_tree_size = current_max;\n    int no_improvement_count = 0;\n    \n    for (int step = 0; step < T; step++) {\n        if (current_max == N * N - 1) {\n            break;  // Already achieved full tree\n        }\n        \n        // Adapt randomization based on progress\n        if (current_max == last_best_tree_size) {\n            stagnation_count++;\n            no_improvement_count++;\n            if (stagnation_count > 12) {\n                random_prob = min(0.22, random_prob * 1.25);\n                stagnation_count = 0;\n            }\n            if (no_improvement_count > 25) {\n                random_prob = min(0.3, random_prob * 1.4);\n                no_improvement_count = 0;\n            }\n        } else {\n            stagnation_count = 0;\n            no_improvement_count = 0;\n            last_best_tree_size = current_max;\n            random_prob = max(0.05, random_prob * 0.9);\n        }\n        \n        // Random move to escape local optima\n        if (rng() % 1000 < random_prob * 1000) {\n            vector<int> valid_moves;\n            for (int d = 0; d < 4; d++) {\n                if (can_move(d)) valid_moves.push_back(d);\n            }\n            if (!valid_moves.empty()) {\n                int random_d = valid_moves[rng() % valid_moves.size()];\n                make_move(random_d);\n                moves += dir_char[random_d];\n                tie(current_max, current_extra_edges, current_components, current_total_tree_vertices) = analyze_board();\n                continue;\n            }\n        }\n        \n        int best_d = -1;\n        int best_score = -100000000;\n        int best_tree_size = current_max;\n        \n        // Evaluate all possible moves\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(d)) continue;\n            \n            // Use lookahead occasionally\n            bool use_lookahead = (step % 8 == 0);\n            auto [score, tree_size] = evaluate_move(d, step, use_lookahead);\n            \n            // Small random factor to break ties\n            score += rng() % 30;\n            \n            // Update best move\n            if (score > best_score || \n                (score == best_score && tree_size > best_tree_size)) {\n                best_score = score;\n                best_tree_size = tree_size;\n                best_d = d;\n            }\n        }\n        \n        if (best_d == -1) {\n            // No valid moves, try any move\n            for (int d = 0; d < 4; d++) {\n                if (can_move(d)) {\n                    best_d = d;\n                    break;\n                }\n            }\n            if (best_d == -1) break;\n        }\n        \n        // Execute best move\n        make_move(best_d);\n        moves += dir_char[best_d];\n        tie(current_max, current_extra_edges, current_components, current_total_tree_vertices) = analyze_board();\n    }\n    \n    // Last resort: aggressive component connection if not full tree\n    if (current_max < N * N - 1 && moves.size() < T) {\n        for (int attempt = 0; attempt < 25 && moves.size() < T; attempt++) {\n            bool improved = false;\n            \n            // Try to find a move that increases tree size or connects components\n            for (int d = 0; d < 4; d++) {\n                if (!can_move(d)) continue;\n                \n                // Simulate move\n                int nr = empty_r + dy[d];\n                int nc = empty_c + dx[d];\n                swap(board[empty_r][empty_c], board[nr][nc]);\n                int saved_er = empty_r, saved_ec = empty_c;\n                empty_r = nr;\n                empty_c = nc;\n                \n                auto [new_max, new_extra_edges, new_components, new_total_tree_vertices] = analyze_board();\n                \n                // Restore\n                empty_r = saved_er;\n                empty_c = saved_ec;\n                swap(board[empty_r][empty_c], board[nr][nc]);\n                \n                // Check if this move improves the situation\n                if (new_max > current_max || \n                    new_components < current_components ||\n                    (new_total_tree_vertices > current_total_tree_vertices && new_extra_edges <= current_extra_edges)) {\n                    make_move(d);\n                    moves += dir_char[d];\n                    tie(current_max, current_extra_edges, current_components, current_total_tree_vertices) = analyze_board();\n                    improved = true;\n                    break;\n                }\n            }\n            \n            if (!improved) break;\n        }\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\nstruct Pt { ll x, y; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K = 100;\n    cin >> N >> K;\n    int a[11] = {};\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    vector<Pt> pts(N);\n    for (int i = 0; i < N; i++) cin >> pts[i].x >> pts[i].y;\n\n    auto calc = [&](const vector<array<ll,4>>& L) {\n        int cnt[11] = {};\n        for (int i = 0; i < N; i++) {\n            int s = 0;\n            for (auto& l : L) {\n                ll d = (l[2]-l[0])*(pts[i].y-l[1]) - (l[3]-l[1])*(pts[i].x-l[0]);\n                if (d < 0) s |= 1; else if (d > 0) s |= 2;\n            }\n            if (s) { int b = __builtin_popcount(s); if (b >= 1 && b <= 10) cnt[b]++; }\n        }\n        int sc = 0, tot = 0;\n        for (int d = 1; d <= 10; d++) { sc += min(a[d], cnt[d]); tot += a[d]; }\n        return tot ? (int)round(1e6 * sc / (double)tot) : 0;\n    };\n\n    vector<array<ll,4>> best;\n    int bs = -1;\n\n    // Sort orderings to try\n    vector<array<int,2>> sorts;\n    sorts.push_back({0, 0}); // x asc, y asc\n    sorts.push_back({1, 1}); // x desc, y desc\n    sorts.push_back({2, 3}); // x+y asc, x-y asc\n    sorts.push_back({3, 2}); // x-y asc, x+y asc\n    sorts.push_back({0, 1}); // x asc, y desc\n    sorts.push_back({1, 0}); // x desc, y asc\n\n    // Grid ratios to try\n    vector<int> ratios;\n    for (int h : {50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,\n                  30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,\n                  55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,\n                  10,80,85,90})\n        ratios.push_back(h);\n\n    for (auto& so : sorts) {\n        vector<int> sx(N), sy(N);\n        iota(sx.begin(), sx.end(), 0);\n        iota(sy.begin(), sy.end(), 0);\n        if (so[0] == 0) sort(sx.begin(), sx.end(), [&](int i,int j){return pts[i].x<pts[j].x||(pts[i].x==pts[j].x&&pts[i].y<pts[j].y);});\n        else if (so[0] == 1) sort(sx.begin(), sx.end(), [&](int i,int j){return pts[i].x>pts[j].x||(pts[i].x==pts[j].x&&pts[i].y>pts[j].y);});\n        else if (so[0] == 2) sort(sx.begin(), sx.end(), [&](int i,int j){return pts[i].x+pts[i].y<pts[j].x+pts[j].y;});\n        else sort(sx.begin(), sx.end(), [&](int i,int j){return pts[i].x-pts[i].y<pts[j].x-pts[j].y;});\n        if (so[1] == 0) sort(sy.begin(), sy.end(), [&](int i,int j){return pts[i].y<pts[j].y||(pts[i].y==pts[j].y&&pts[i].x<pts[j].x);});\n        else if (so[1] == 1) sort(sy.begin(), sy.end(), [&](int i,int j){return pts[i].y>pts[j].y||(pts[i].y==pts[j].y&&pts[i].x>pts[j].x);});\n        else if (so[1] == 2) sort(sy.begin(), sy.end(), [&](int i,int j){return pts[i].x+pts[i].y<pts[j].x+pts[j].y;});\n        else sort(sy.begin(), sy.end(), [&](int i,int j){return pts[i].x-pts[i].y<pts[j].x-pts[j].y;});\n\n        for (int h : ratios) {\n            int v = K - h;\n            if (v < 1 || h < 1) continue;\n            vector<array<ll,4>> sol;\n            for (int i = 1; i <= h; i++) {\n                int idx = i * N / (h + 1);\n                if (idx > N - 2) idx = N - 2;\n                if (idx < 0) idx = 0;\n                ll mx = (pts[sx[idx]].x + pts[sx[idx+1]].x) / 2;\n                sol.push_back({mx, -20000, mx, 20000});\n            }\n            for (int i = 1; i <= v; i++) {\n                int idx = i * N / (v + 1);\n                if (idx > N - 2) idx = N - 2;\n                if (idx < 0) idx = 0;\n                ll my = (pts[sy[idx]].y + pts[sy[idx+1]].y) / 2;\n                sol.push_back({-20000, my, 20000, my});\n            }\n            int sc = calc(sol);\n            if (sc > bs) { bs = sc; best = sol; }\n        }\n    }\n\n    // K-d tree with multiple sort orders\n    for (int rev = 0; rev < 2; rev++) {\n        vector<int> sx(N), sy(N);\n        iota(sx.begin(), sx.end(), 0);\n        iota(sy.begin(), sy.end(), 0);\n        if (rev == 0) {\n            sort(sx.begin(), sx.end(), [&](int i,int j){return pts[i].x<pts[j].x;});\n            sort(sy.begin(), sy.end(), [&](int i,int j){return pts[i].y<pts[j].y;});\n        } else {\n            sort(sx.begin(), sx.end(), [&](int i,int j){return pts[i].x>pts[j].x;});\n            sort(sy.begin(), sy.end(), [&](int i,int j){return pts[i].y>pts[j].y;});\n        }\n        vector<vector<int>> seg;\n        { vector<int> av(N); iota(av.begin(), av.end(), 0); seg.push_back(av); }\n        vector<array<ll,4>> sol;\n        for (int cut = 0; cut < K; cut++) {\n            int bi = -1, bsz = 0;\n            for (int i = 0; i < (int)seg.size(); i++)\n                if ((int)seg[i].size() > bsz) { bsz = seg[i].size(); bi = i; }\n            if (bsz <= 1) break;\n            auto& cur = seg[bi];\n            unordered_set<int> cs(cur.begin(), cur.end());\n            ll xr = 0, yr = 0;\n            { ll x0=1e18,x1=-1e18; for(int j:cur){x0=min(x0,pts[j].x);x1=max(x1,pts[j].x);} xr=x1-x0; }\n            { ll y0=1e18,y1=-1e18; for(int j:cur){y0=min(y0,pts[j].y);y1=max(y1,pts[j].y);} yr=y1-y0; }\n            int dim = (xr >= yr) ? 0 : 1;\n            auto& ord = (dim == 0) ? sx : sy;\n            vector<int> idx;\n            for (int j = 0; j < N; j++) if (cs.count(ord[j])) idx.push_back(ord[j]);\n            int mid = bsz / 2;\n            ll coord;\n            if (dim == 0) coord = (pts[idx[mid-1]].x + pts[idx[mid]].x) / 2;\n            else coord = (pts[idx[mid-1]].y + pts[idx[mid]].y) / 2;\n            vector<int> s1, s2;\n            for (int j = 0; j < mid; j++) s1.push_back(idx[j]);\n            for (int j = mid; j < bsz; j++) s2.push_back(idx[j]);\n            seg.erase(seg.begin() + bi);\n            seg.push_back(s1); seg.push_back(s2);\n            if (dim == 0) sol.push_back({coord, -20000, coord, 20000});\n            else sol.push_back({-20000, coord, 20000, coord});\n        }\n        int sc = calc(sol);\n        if (sc > bs) { bs = sc; best = sol; }\n    }\n\n    int k = min((int)best.size(), K);\n    cout << k << \"\\n\";\n    for (int i = 0; i < k; i++)\n        cout << best[i][0]<<\" \"<<best[i][1]<<\" \"<<best[i][2]<<\" \"<<best[i][3]<<\"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint main(){\n    int N, M;\n    scanf(\"%d%d\",&N,&M);\n    const int MX = 62;\n    bool g0[MX][MX] = {};\n    vector<pair<int,int>> dots0;\n    for(int i = 0; i < M; i++){\n        int x, y; scanf(\"%d%d\",&x,&y);\n        g0[x][y] = true;\n        dots0.push_back({x, y});\n    }\n    double cc = (N-1)/2.0;\n    double w[MX][MX];\n    for(int x = 0; x < N; x++)\n        for(int y = 0; y < N; y++)\n            w[x][y] = (x-cc)*(x-cc) + (y-cc)*(y-cc) + 1;\n\n    auto t0 = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        return chrono::duration<double>(\n            chrono::steady_clock::now() - t0).count();\n    };\n\n    mt19937 rng(12345);\n    vector<array<int,8>> bestOps;\n    double bestWS = -1;\n\n    for(int restart = 0; restart < 80 && elapsed() < 4.3; restart++){\n        bool g[MX][MX]; memcpy(g, g0, sizeof(g));\n        auto dots = dots0;\n        bool hz[MX][MX] = {}, vt[MX][MX] = {};\n        vector<array<int,8>> ops;\n\n        while(elapsed() < 4.3){\n            using Cand = tuple<double,int,int,int,int,int,int,int,int>;\n            vector<Cand> cands;\n\n            for(int di = 0; di < (int)dots.size(); di++){\n                for(int dj = di+1; dj < (int)dots.size(); dj++){\n                    int x1 = dots[di].first, y1 = dots[di].second;\n                    int x2 = dots[dj].first, y2 = dots[dj].second;\n                    if(x1 == x2 || y1 == y2) continue;\n\n                    if(x1>=0&&x1<N&&y2>=0&&y2<N&&!g[x1][y2]&&g[x2][y1]){\n                        bool ok = true;\n                        for(int y=min(y1,y2)+1;y<max(y1,y2)&&ok;y++) if(g[x1][y]) ok=false;\n                        for(int x=min(x1,x2)+1;x<max(x1,x2)&&ok;x++) if(g[x][y1]) ok=false;\n                        for(int y=min(y1,y2)+1;y<max(y1,y2)&&ok;y++) if(g[x2][y]) ok=false;\n                        for(int x=min(x1,x2)+1;x<max(x1,x2)&&ok;x++) if(g[x][y2]) ok=false;\n                        if(ok) cands.push_back(make_tuple(w[x1][y2],x1,y2,x1,y1,x2,y1,x2,y2));\n                    }\n                    if(x2>=0&&x2<N&&y1>=0&&y1<N&&!g[x2][y1]&&g[x1][y2]){\n                        bool ok = true;\n                        for(int y=min(y1,y2)+1;y<max(y1,y2)&&ok;y++) if(g[x2][y]) ok=false;\n                        for(int x=min(x1,x2)+1;x<max(x1,x2)&&ok;x++) if(g[x][y2]) ok=false;\n                        for(int y=min(y1,y2)+1;y<max(y1,y2)&&ok;y++) if(g[x1][y]) ok=false;\n                        for(int x=min(x1,x2)+1;x<max(x1,x2)&&ok;x++) if(g[x][y1]) ok=false;\n                        if(ok) cands.push_back(make_tuple(w[x2][y1],x2,y1,x2,y2,x1,y2,x1,y1));\n                    }\n                }\n            }\n\n            sort(cands.begin(), cands.end(),\n                [](auto& a, auto& b){ return get<0>(a) > get<0>(b); });\n            int jj = 0;\n            while(jj < (int)cands.size()){\n                int kk = jj;\n                while(kk < (int)cands.size() && get<0>(cands[kk]) == get<0>(cands[jj])) kk++;\n                if(kk - jj > 1) shuffle(cands.begin()+jj, cands.begin()+kk, rng);\n                jj = kk;\n            }\n\n            bool found = false;\n            for(auto& cd : cands){\n                int nx=get<1>(cd),ny=get<2>(cd);\n                int p1x=get<3>(cd),p1y=get<4>(cd);\n                int p2x=get<5>(cd),p2y=get<6>(cd);\n                int p3x=get<7>(cd),p3y=get<8>(cd);\n\n                // Four edges in CCW order around rectangle perimeter:\n                // Edge A: (nx,ny) -> (p1x,p1y)\n                // Edge B: (p1x,p1y) -> (p2x,p2y)\n                // Edge C: (p2x,p2y) -> (p3x,p3y)\n                // Edge D: (p3x,p3y) -> (nx,ny)\n                // For axis-aligned: each edge is either horizontal or vertical\n\n                bool overlap = false;\n\n                // Edge A: (nx,ny) to (p1x,p1y)\n                if(ny == p1y){\n                    for(int x = min(nx,p1x); x < max(nx,p1x); x++)\n                        if(hz[x][ny]){ overlap=true; break; }\n                } else {\n                    for(int y = min(ny,p1y); y < max(ny,p1y); y++)\n                        if(vt[nx][y]){ overlap=true; break; }\n                }\n                if(overlap) continue;\n\n                // Edge B: (p1x,p1y) to (p2x,p2y)\n                if(p1y == p2y){\n                    for(int x = min(p1x,p2x); x < max(p1x,p2x); x++)\n                        if(hz[x][p1y]){ overlap=true; break; }\n                } else {\n                    for(int y = min(p1y,p2y); y < max(p1y,p2y); y++)\n                        if(vt[p1x][y]){ overlap=true; break; }\n                }\n                if(overlap) continue;\n\n                // Edge C: (p2x,p2y) to (p3x,p3y)\n                if(p2y == p3y){\n                    for(int x = min(p2x,p3x); x < max(p2x,p3x); x++)\n                        if(hz[x][p2y]){ overlap=true; break; }\n                } else {\n                    for(int y = min(p2y,p3y); y < max(p2y,p3y); y++)\n                        if(vt[p2x][y]){ overlap=true; break; }\n                }\n                if(overlap) continue;\n\n                // Edge D: (p3x,p3y) to (nx,ny)\n                if(p3y == ny){\n                    for(int x = min(p3x,nx); x < max(p3x,nx); x++)\n                        if(hz[x][p3y]){ overlap=true; break; }\n                } else {\n                    for(int y = min(p3y,ny); y < max(p3y,ny); y++)\n                        if(vt[p3x][y]){ overlap=true; break; }\n                }\n                if(overlap) continue;\n\n                // Mark all edges\n                if(ny == p1y){\n                    for(int x = min(nx,p1x); x < max(nx,p1x); x++) hz[x][ny]=true;\n                } else {\n                    for(int y = min(ny,p1y); y < max(ny,p1y); y++) vt[nx][y]=true;\n                }\n                if(p1y == p2y){\n                    for(int x = min(p1x,p2x); x < max(p1x,p2x); x++) hz[x][p1y]=true;\n                } else {\n                    for(int y = min(p1y,p2y); y < max(p1y,p2y); y++) vt[p1x][y]=true;\n                }\n                if(p2y == p3y){\n                    for(int x = min(p2x,p3x); x < max(p2x,p3x); x++) hz[x][p2y]=true;\n                } else {\n                    for(int y = min(p2y,p3y); y < max(p2y,p3y); y++) vt[p2x][y]=true;\n                }\n                if(p3y == ny){\n                    for(int x = min(p3x,nx); x < max(p3x,nx); x++) hz[x][p3y]=true;\n                } else {\n                    for(int y = min(p3y,ny); y < max(p3y,ny); y++) vt[p3x][y]=true;\n                }\n\n                g[nx][ny] = true;\n                dots.push_back({nx, ny});\n                ops.push_back({nx,ny,p1x,p1y,p2x,p2y,p3x,p3y});\n                found = true;\n                break;\n            }\n            if(!found) break;\n        }\n\n        double ws = 0;\n        for(int x = 0; x < N; x++)\n            for(int y = 0; y < N; y++)\n                if(g[x][y]) ws += w[x][y];\n        if(ws > bestWS){\n            bestWS = ws;\n            bestOps = ops;\n        }\n    }\n\n    printf(\"%d\\n\", (int)bestOps.size());\n    for(auto& o : bestOps)\n        printf(\"%d %d %d %d %d %d %d %d\\n\",\n            o[0],o[1],o[2],o[3],o[4],o[5],o[6],o[7]);\n\n    double S = 0;\n    for(int x = 0; x < N; x++)\n        for(int y = 0; y < N; y++) S += w[x][y];\n    fprintf(stderr, \"Score: %lld\\n\", (ll)llround(1e6*N*N/M*bestWS/S));\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <cstring>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint grid[10][10];\nint flavors[100];\n\nmt19937 rng(12345);\n\nvoid tilt(char dir, int g[10][10]) {\n    if (dir == 'F') {\n        for (int j = 0; j < 10; ++j) {\n            int write = 0;\n            for (int i = 0; i < 10; ++i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int i = write; i < 10; ++i) g[i][j] = 0;\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < 10; ++j) {\n            int write = 9;\n            for (int i = 9; i >= 0; --i) {\n                if (g[i][j] != 0) {\n                    g[write][j] = g[i][j];\n                    --write;\n                }\n            }\n            for (int i = write; i >= 0; --i) g[i][j] = 0;\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < 10; ++i) {\n            int write = 0;\n            for (int j = 0; j < 10; ++j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    ++write;\n                }\n            }\n            for (int j = write; j < 10; ++j) g[i][j] = 0;\n        }\n    } else if (dir == 'R') {\n        for (int i = 0; i < 10; ++i) {\n            int write = 9;\n            for (int j = 9; j >= 0; --j) {\n                if (g[i][j] != 0) {\n                    g[i][write] = g[i][j];\n                    --write;\n                }\n            }\n            for (int j = write; j >= 0; --j) g[i][j] = 0;\n        }\n    }\n}\n\nint compute_score(int g[10][10]) {\n    bool visited[10][10] = {};\n    int total = 0;\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            if (g[i][j] != 0 && !visited[i][j]) {\n                int flavor = g[i][j];\n                queue<pair<int, int>> q;\n                q.push({i, j});\n                visited[i][j] = true;\n                int size = 0;\n                while (!q.empty()) {\n                    auto [r, c] = q.front(); q.pop();\n                    ++size;\n                    if (r > 0 && g[r-1][c] == flavor && !visited[r-1][c]) {\n                        visited[r-1][c] = true;\n                        q.push({r-1, c});\n                    }\n                    if (r < 9 && g[r+1][c] == flavor && !visited[r+1][c]) {\n                        visited[r+1][c] = true;\n                        q.push({r+1, c});\n                    }\n                    if (c > 0 && g[r][c-1] == flavor && !visited[r][c-1]) {\n                        visited[r][c-1] = true;\n                        q.push({r, c-1});\n                    }\n                    if (c < 9 && g[r][c+1] == flavor && !visited[r][c+1]) {\n                        visited[r][c+1] = true;\n                        q.push({r, c+1});\n                    }\n                }\n                total += size * size;\n            }\n        }\n    }\n    return total;\n}\n\nvector<pair<int, int>> get_empty_cells(int g[10][10]) {\n    vector<pair<int, int>> empties;\n    for (int i = 0; i < 10; ++i) {\n        for (int j = 0; j < 10; ++j) {\n            if (g[i][j] == 0) {\n                empties.push_back({i, j});\n            }\n        }\n    }\n    return empties;\n}\n\n// Stratified sampling: divide empty cells into 5 groups and sample one from each\nvector<pair<int, int>> stratified_sample(const vector<pair<int, int>>& empties, int num_samples) {\n    int n = empties.size();\n    if (n <= num_samples) {\n        return empties;\n    }\n    \n    // Sort by row then column to create groups\n    vector<pair<int, int>> sorted = empties;\n    sort(sorted.begin(), sorted.end());\n    \n    vector<pair<int, int>> samples;\n    int group_size = n / num_samples;\n    int remainder = n % num_samples;\n    \n    int start = 0;\n    for (int i = 0; i < num_samples; ++i) {\n        int end = start + group_size + (i < remainder ? 1 : 0);\n        // Randomly pick one from this group\n        uniform_int_distribution<int> dist(start, end - 1);\n        int idx = dist(rng);\n        samples.push_back(sorted[idx]);\n        start = end;\n    }\n    \n    return samples;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n\n    memset(grid, 0, sizeof(grid));\n\n    for (int t = 0; t < 100; ++t) {\n        int p;\n        cin >> p;\n\n        vector<pair<int, int>> empties = get_empty_cells(grid);\n        auto [r, c] = empties[p - 1];\n        grid[r][c] = flavors[t];\n\n        if (t == 99) {\n            int best_score = -1;\n            char best_dir = 'F';\n            for (char dir : {'F', 'B', 'L', 'R'}) {\n                int temp[10][10];\n                memcpy(temp, grid, sizeof(temp));\n                tilt(dir, temp);\n                int score = compute_score(temp);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n            cout << best_dir << endl;\n            tilt(best_dir, grid);\n            continue;\n        }\n\n        int next_flavor = flavors[t + 1];\n        double best_avg_future_score = -1;\n        char best_dir = 'F';\n\n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            int temp1[10][10];\n            memcpy(temp1, grid, sizeof(temp1));\n            tilt(dir, temp1);\n\n            vector<pair<int, int>> next_empties = get_empty_cells(temp1);\n            int num_empty = next_empties.size();\n            \n            // Use 5 samples with stratified sampling\n            int samples = min(5, num_empty);\n            vector<pair<int, int>> sampled_cells;\n            if (num_empty <= samples) {\n                sampled_cells = next_empties;\n            } else {\n                sampled_cells = stratified_sample(next_empties, samples);\n            }\n            \n            double total_future_score = 0;\n            \n            for (auto [nr, nc] : sampled_cells) {\n                int temp2[10][10];\n                memcpy(temp2, temp1, sizeof(temp2));\n                temp2[nr][nc] = next_flavor;\n                \n                int best_next_score = -1;\n                for (char next_dir : {'F', 'B', 'L', 'R'}) {\n                    int temp3[10][10];\n                    memcpy(temp3, temp2, sizeof(temp3));\n                    tilt(next_dir, temp3);\n                    int score = compute_score(temp3);\n                    if (score > best_next_score) {\n                        best_next_score = score;\n                    }\n                }\n                total_future_score += best_next_score;\n            }\n            \n            double avg_future_score = total_future_score / samples;\n            \n            if (avg_future_score > best_avg_future_score) {\n                best_avg_future_score = avg_future_score;\n                best_dir = dir;\n            }\n        }\n\n        cout << best_dir << endl;\n        tilt(best_dir, grid);\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\ndouble q_function(double x) {\n    return 0.5 * erfc(x / sqrt(2.0));\n}\n\nint main() {\n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Handle M=1 case\n    if (M == 1) {\n        cout << \"4\" << endl;\n        cout << \"000000\" << endl;\n        for (int q = 0; q < 100; ++q) {\n            string H;\n            cin >> H;\n            cout << \"0\" << endl;\n        }\n        return 0;\n    }\n    \n    // Find optimal N with adaptive continuity correction\n    double best_expected_score = -1.0;\n    int best_N = 4;\n    \n    for (int N = 4; N <= 100; ++N) {\n        int T = N * (N - 1) / 2;\n        if (T < M - 1) continue;\n        \n        double delta = (double)T / (M - 1);\n        double signal = delta * (1.0 - 2.0 * eps);\n        double noise = sqrt(T * eps * (1.0 - eps));\n        \n        double p_error;\n        if (noise < 1e-12) {\n            // No noise case\n            p_error = (signal > 0) ? 0.0 : 1.0;\n        } else {\n            // Adaptive continuity correction:\n            // Use 0.5 when signal is large, but smaller correction when signal is small\n            double correction;\n            if (signal > 2.0) {\n                correction = 0.5;  // Standard continuity correction\n            } else if (signal > 1.0) {\n                correction = 0.25; // Smaller correction for medium gaps\n            } else {\n                correction = 0.1;  // Very small correction for tiny gaps\n            }\n            \n            double corrected_signal = max(0.0, signal - correction);\n            double x = corrected_signal / (2.0 * noise);\n            double Q = q_function(x);\n            p_error = (2.0 - 2.0 / M) * Q;\n            if (p_error > 1.0) p_error = 1.0;\n        }\n        \n        double survival_prob = 1.0 - 0.1 * p_error;\n        if (survival_prob < 0.0) survival_prob = 0.0;\n        double expected_score = 1e9 * pow(survival_prob, 100) / N;\n        \n        if (expected_score > best_expected_score) {\n            best_expected_score = expected_score;\n            best_N = N;\n        }\n    }\n    \n    int N = best_N;\n    int T = N * (N - 1) / 2;\n    \n    // Generate graphs with equally spaced edge counts\n    vector<int> edge_counts(M);\n    for (int s = 0; s < M; ++s) {\n        edge_counts[s] = (s * T) / (M - 1);\n    }\n    \n    // Output\n    cout << N << endl;\n    for (int s = 0; s < M; ++s) {\n        string graph(T, '0');\n        for (int i = 0; i < edge_counts[s]; ++i) {\n            graph[i] = '1';\n        }\n        cout << graph << endl;\n    }\n    cout.flush();\n    \n    // Precompute expected observed edge counts\n    vector<double> expected_observed(M);\n    for (int s = 0; s < M; ++s) {\n        expected_observed[s] = edge_counts[s] * (1.0 - 2.0 * eps) + T * eps;\n    }\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n        \n        // Count edges\n        int observed_edges = 0;\n        for (char c : H) {\n            if (c == '1') observed_edges++;\n        }\n        \n        // Find closest expected value\n        int best_s = 0;\n        double min_diff = 1e100;\n        for (int s = 0; s < M; ++s) {\n            double diff = fabs(observed_edges - expected_observed[s]);\n            if (diff < min_diff) {\n                min_diff = diff;\n                best_s = s;\n            }\n        }\n        \n        cout << best_s << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <cassert>\n#include <tuple>\n#include <chrono>\n#include <functional>\n\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\n\nstruct Edge {\n    int u, v, w;\n    int idx;\n};\n\nstruct EdgeAdj {\n    int to, idx;\n    ll w;\n};\n\nvector<ll> dijkstra(int s, const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\nvector<ll> dijkstra_ignore_set(int s, const vector<bool>& ignore_edge, \n                               const vector<vector<EdgeAdj>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, INF);\n    dist[s] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<>> pq;\n    pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (const auto& e : adj[v]) {\n            if (ignore_edge[e.idx]) continue;\n            if (dist[e.to] > d + e.w) {\n                dist[e.to] = d + e.w;\n                pq.emplace(dist[e.to], e.to);\n            }\n        }\n    }\n    return dist;\n}\n\n// Compute betweenness centrality for edges\nvector<double> compute_edge_betweenness(int N, const vector<Edge>& edges, \n                                        const vector<vector<ll>>& dist) {\n    int M = edges.size();\n    vector<double> edge_betw(M, 0.0);\n    \n    for (int s = 0; s < N; ++s) {\n        const auto& d_s = dist[s];\n        vector<int> nodes(N);\n        iota(nodes.begin(), nodes.end(), 0);\n        sort(nodes.begin(), nodes.end(), [&](int a, int b) { \n            return d_s[a] < d_s[b]; \n        });\n        \n        vector<double> sigma(N, 0.0);\n        sigma[s] = 1.0;\n        vector<vector<int>> preds(N);\n        vector<vector<int>> pred_edges(N);\n        \n        for (int i = 0; i < M; ++i) {\n            int u = edges[i].u, v = edges[i].v;\n            ll w = edges[i].w;\n            if (d_s[u] + w == d_s[v]) {\n                preds[v].push_back(u);\n                pred_edges[v].push_back(i);\n            }\n            if (d_s[v] + w == d_s[u]) {\n                preds[u].push_back(v);\n                pred_edges[u].push_back(i);\n            }\n        }\n        \n        for (int v : nodes) {\n            if (v == s) continue;\n            for (int u : preds[v]) {\n                sigma[v] += sigma[u];\n            }\n        }\n        \n        vector<double> dep(N, 0.0);\n        for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {\n            int v = *it;\n            if (v == s) continue;\n            for (size_t i = 0; i < preds[v].size(); ++i) {\n                int u = preds[v][i];\n                int edge_idx = pred_edges[v][i];\n                double contrib = (sigma[u] / sigma[v]) * (1.0 + dep[v]);\n                dep[u] += contrib;\n                edge_betw[edge_idx] += contrib;\n            }\n        }\n    }\n    \n    return edge_betw;\n}\n\ndouble compute_day_frustration(int day, const vector<int>& day_assignment, \n                              const vector<Edge>& edges, const vector<vector<ll>>& orig_dist,\n                              const vector<vector<EdgeAdj>>& adj, int N, \n                              const vector<int>& sample_sources) {\n    vector<bool> ignore_edge(edges.size(), false);\n    int edge_count = 0;\n    for (int i = 0; i < edges.size(); ++i) {\n        if (day_assignment[i] == day) {\n            ignore_edge[i] = true;\n            edge_count++;\n        }\n    }\n    \n    if (edge_count == 0) return 0.0;\n    \n    double total_increase = 0.0;\n    int pair_count = 0;\n    \n    for (int s : sample_sources) {\n        vector<ll> new_dist = dijkstra_ignore_set(s, ignore_edge, adj);\n        for (int t = 0; t < N; ++t) {\n            if (s == t) continue;\n            ll orig_d = orig_dist[s][t];\n            ll new_d = new_dist[t];\n            if (new_d >= INF/2) new_d = 1000000000;\n            total_increase += (new_d - orig_d);\n            pair_count++;\n        }\n    }\n    \n    double avg_increase = total_increase / pair_count;\n    return avg_increase * (N * (N - 1)) / (sample_sources.size() * (N - 1));\n}\n\nvector<int> greedy_initial_assignment(const vector<Edge>& edges, const vector<double>& edge_importance,\n                                      int D, int K, int M) {\n    vector<int> assignment(M, 0);\n    vector<int> day_count(D, 0);\n    vector<double> day_importance(D, 0.0);\n    \n    // Sort edges by importance descending\n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int a, int b) {\n        return edge_importance[a] > edge_importance[b];\n    });\n    \n    for (int e_idx : edge_order) {\n        // Find day with minimum importance that has capacity\n        int best_day = -1;\n        double min_importance = 1e18;\n        for (int d = 0; d < D; ++d) {\n            if (day_count[d] < K && day_importance[d] < min_importance) {\n                min_importance = day_importance[d];\n                best_day = d;\n            }\n        }\n        assignment[e_idx] = best_day;\n        day_count[best_day]++;\n        day_importance[best_day] += edge_importance[e_idx];\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    \n    vector<Edge> edges(M);\n    vector<vector<EdgeAdj>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {u, v, w, i};\n        adj[u].push_back({v, i, w});\n        adj[v].push_back({u, i, w});\n    }\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Precompute original distances\n    vector<vector<ll>> orig_dist(N);\n    for (int s = 0; s < N; ++s) {\n        orig_dist[s] = dijkstra(s, adj);\n    }\n    \n    // Compute edge importance (betweenness * delta)\n    vector<double> edge_importance(M, 0.0);\n    vector<double> edge_betw = compute_edge_betweenness(N, edges, orig_dist);\n    \n    // Compute delta for each edge (alternative path length - original length)\n    vector<ll> edge_delta(M, 0);\n    for (int i = 0; i < M; ++i) {\n        int u = edges[i].u, v = edges[i].v;\n        ll w = edges[i].w;\n        vector<bool> ignore(M, false);\n        ignore[i] = true;\n        vector<ll> dist_u = dijkstra_ignore_set(u, ignore, adj);\n        edge_delta[i] = dist_u[v] - w;\n        if (edge_delta[i] < 0) edge_delta[i] = 0;\n    }\n    \n    for (int i = 0; i < M; ++i) {\n        edge_importance[i] = edge_betw[i] * edge_delta[i];\n    }\n    \n    // Sample vertices for frustration estimation\n    int sample_size = min(30, N);\n    vector<int> sample_sources(sample_size);\n    iota(sample_sources.begin(), sample_sources.end(), 0);\n    if (N > sample_size) {\n        random_device rd;\n        mt19937 gen(rd());\n        shuffle(sample_sources.begin(), sample_sources.end(), gen);\n        sample_sources.resize(sample_size);\n    }\n    \n    // Get initial assignment using greedy algorithm\n    vector<int> assignment = greedy_initial_assignment(edges, edge_importance, D, K, M);\n    \n    // Compute initial frustration\n    vector<double> day_frustration(D, 0.0);\n    double total_frustration = 0.0;\n    for (int day = 0; day < D; ++day) {\n        day_frustration[day] = compute_day_frustration(day, assignment, edges, orig_dist, \n                                                      adj, N, sample_sources);\n        total_frustration += day_frustration[day];\n    }\n    \n    // Simulated annealing with edge moves and swaps\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<double> dis(0.0, 1.0);\n    uniform_int_distribution<int> rand_edge(0, M - 1);\n    uniform_int_distribution<int> rand_day(0, D - 1);\n    uniform_int_distribution<int> rand_move_type(0, 1); // 0: move, 1: swap\n    \n    double temp = 1000.0;\n    double cooling = 0.9998;\n    const int ITER = 250000;\n    \n    for (int iter = 0; iter < ITER; ++iter) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 5.5) break;\n        \n        if (rand_move_type(gen) == 0) {\n            // Move single edge\n            int e = rand_edge(gen);\n            int old_day = assignment[e];\n            int new_day = rand_day(gen);\n            while (new_day == old_day) new_day = rand_day(gen);\n            \n            // Check capacity\n            int cnt_new = count(assignment.begin(), assignment.end(), new_day);\n            if (cnt_new >= K) continue;\n            \n            assignment[e] = new_day;\n            \n            double new_frustration_old = compute_day_frustration(old_day, assignment, edges, \n                                                                orig_dist, adj, N, sample_sources);\n            double new_frustration_new = compute_day_frustration(new_day, assignment, edges, \n                                                                orig_dist, adj, N, sample_sources);\n            \n            double new_total = total_frustration - day_frustration[old_day] - day_frustration[new_day] \n                              + new_frustration_old + new_frustration_new;\n            \n            double delta = new_total - total_frustration;\n            \n            if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n                total_frustration = new_total;\n                day_frustration[old_day] = new_frustration_old;\n                day_frustration[new_day] = new_frustration_new;\n            } else {\n                assignment[e] = old_day;\n            }\n        } else {\n            // Swap two edges between days\n            int e1 = rand_edge(gen);\n            int e2 = rand_edge(gen);\n            if (e1 == e2) continue;\n            \n            int day1 = assignment[e1];\n            int day2 = assignment[e2];\n            if (day1 == day2) continue;\n            \n            // Perform swap\n            assignment[e1] = day2;\n            assignment[e2] = day1;\n            \n            double new_frustration_day1 = compute_day_frustration(day1, assignment, edges, \n                                                                 orig_dist, adj, N, sample_sources);\n            double new_frustration_day2 = compute_day_frustration(day2, assignment, edges, \n                                                                 orig_dist, adj, N, sample_sources);\n            \n            double new_total = total_frustration - day_frustration[day1] - day_frustration[day2] \n                              + new_frustration_day1 + new_frustration_day2;\n            \n            double delta = new_total - total_frustration;\n            \n            if (delta < 0 || dis(gen) < exp(-delta / temp)) {\n                total_frustration = new_total;\n                day_frustration[day1] = new_frustration_day1;\n                day_frustration[day2] = new_frustration_day2;\n            } else {\n                // Revert swap\n                assignment[e1] = day1;\n                assignment[e2] = day2;\n            }\n        }\n        \n        temp *= cooling;\n    }\n    \n    // Output (convert to 1-indexed days)\n    for (int i = 0; i < M; ++i) {\n        if (i > 0) cout << ' ';\n        cout << (assignment[i] + 1);\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    // Read silhouettes, remove spaces\n    vector<string> f[2], r[2];\n    for (int i = 0; i < 2; ++i) {\n        f[i].resize(D);\n        for (int j = 0; j < D; ++j) {\n            cin >> f[i][j];\n            string clean;\n            for (char c : f[i][j]) if (c != ' ') clean.push_back(c);\n            f[i][j] = clean;\n        }\n        r[i].resize(D);\n        for (int j = 0; j < D; ++j) {\n            cin >> r[i][j];\n            string clean;\n            for (char c : r[i][j]) if (c != ' ') clean.push_back(c);\n            r[i][j] = clean;\n        }\n    }\n\n    // Allowed cells for each object\n    bool allowed[2][14][14][14] = {false};\n    for (int i = 0; i < 2; ++i) {\n        for (int x = 0; x < D; ++x) {\n            for (int y = 0; y < D; ++y) {\n                for (int z = 0; z < D; ++z) {\n                    if (f[i][z][x] == '1' && r[i][z][y] == '1') {\n                        allowed[i][x][y][z] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Common cells (intersection)\n    bool common[14][14][14] = {false};\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 (allowed[0][x][y][z] && allowed[1][x][y][z]) {\n                    common[x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // Occupation arrays for each object\n    bool occupied[2][14][14][14] = {false};\n    // Mark common cells as occupied in both objects\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 (common[x][y][z]) {\n                    occupied[0][x][y][z] = true;\n                    occupied[1][x][y][z] = true;\n                }\n            }\n        }\n    }\n\n    // Coverage arrays\n    bool covered_f[2][14][14] = {false};\n    bool covered_r[2][14][14] = {false};\n    // Initialize coverage from common cells\n    for (int i = 0; i < 2; ++i) {\n        for (int x = 0; x < D; ++x) {\n            for (int y = 0; y < D; ++y) {\n                for (int z = 0; z < D; ++z) {\n                    if (common[x][y][z]) {\n                        covered_f[i][z][x] = true;\n                        covered_r[i][z][y] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // Exclusive cells for each object\n    vector<array<int, 3>> excl[2];\n\n    // Cover remaining columns with exclusive blocks\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) {\n            // First cover uncovered front columns\n            for (int x = 0; x < D; ++x) {\n                if (f[i][z][x] == '1' && !covered_f[i][z][x]) {\n                    // Find a free allowed cell\n                    int chosen_y = -1;\n                    for (int y = 0; y < D; ++y) {\n                        if (allowed[i][x][y][z] && !occupied[i][x][y][z]) {\n                            chosen_y = y;\n                            break;\n                        }\n                    }\n                    if (chosen_y == -1) {\n                        // Should not happen, but fallback: choose any allowed y (might be occupied by common)\n                        for (int y = 0; y < D; ++y) {\n                            if (allowed[i][x][y][z]) {\n                                chosen_y = y;\n                                break;\n                            }\n                        }\n                    }\n                    if (chosen_y != -1) {\n                        occupied[i][x][chosen_y][z] = true;\n                        covered_f[i][z][x] = true;\n                        covered_r[i][z][chosen_y] = true;\n                        excl[i].push_back({x, chosen_y, z});\n                    }\n                }\n            }\n            // Then cover any still uncovered right columns\n            for (int y = 0; y < D; ++y) {\n                if (r[i][z][y] == '1' && !covered_r[i][z][y]) {\n                    int chosen_x = -1;\n                    for (int x = 0; x < D; ++x) {\n                        if (allowed[i][x][y][z] && !occupied[i][x][y][z]) {\n                            chosen_x = x;\n                            break;\n                        }\n                    }\n                    if (chosen_x == -1) {\n                        for (int x = 0; x < D; ++x) {\n                            if (allowed[i][x][y][z]) {\n                                chosen_x = x;\n                                break;\n                            }\n                        }\n                    }\n                    if (chosen_x != -1) {\n                        occupied[i][chosen_x][y][z] = true;\n                        covered_r[i][z][y] = true;\n                        excl[i].push_back({chosen_x, y, z});\n                    }\n                }\n            }\n        }\n    }\n\n    // Connected components of common cells (shared blocks)\n    const int dx[6] = {1, -1, 0, 0, 0, 0};\n    const int dy[6] = {0, 0, 1, -1, 0, 0};\n    const int dz[6] = {0, 0, 0, 0, 1, -1};\n    int compId[14][14][14];\n    memset(compId, -1, sizeof(compId));\n    vector<vector<array<int, 3>>> components;\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 (common[x][y][z] && compId[x][y][z] == -1) {\n                    queue<array<int, 3>> q;\n                    q.push({x, y, z});\n                    compId[x][y][z] = components.size();\n                    vector<array<int, 3>> comp;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.push_back({cx, cy, cz});\n                        for (int d = 0; d < 6; ++d) {\n                            int nx = cx + dx[d], ny = cy + dy[d], nz = cz + dz[d];\n                            if (nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                                common[nx][ny][nz] && compId[nx][ny][nz] == -1) {\n                                compId[nx][ny][nz] = components.size();\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n\n    // Assign block IDs\n    int n = components.size() + excl[0].size() + excl[1].size();\n    vector<int> compIds(components.size());\n    int curId = 1;\n    for (size_t i = 0; i < components.size(); ++i) compIds[i] = curId++;\n    vector<int> exclIds[2];\n    for (int i = 0; i < 2; ++i) {\n        exclIds[i].resize(excl[i].size());\n        for (size_t j = 0; j < excl[i].size(); ++j) exclIds[i][j] = curId++;\n    }\n\n    // Build output arrays\n    vector<vector<vector<int>>> b[2];\n    for (int i = 0; i < 2; ++i)\n        b[i].assign(D, vector<vector<int>>(D, vector<int>(D, 0)));\n\n    // Place shared blocks\n    for (size_t ci = 0; ci < components.size(); ++ci) {\n        int bid = compIds[ci];\n        for (auto [x, y, z] : components[ci]) {\n            b[0][x][y][z] = bid;\n            b[1][x][y][z] = bid;\n        }\n    }\n\n    // Place exclusive blocks\n    for (int i = 0; i < 2; ++i) {\n        for (size_t j = 0; j < excl[i].size(); ++j) {\n            auto [x, y, z] = excl[i][j];\n            b[i][x][y][z] = exclIds[i][j];\n        }\n    }\n\n    // Output\n    cout << n << '\\n';\n    for (int obj = 0; obj < 2; ++obj) {\n        bool first = true;\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 (first) first = false;\n                    else cout << ' ';\n                    cout << b[obj][x][y][z];\n                }\n            }\n        }\n        cout << '\\n';\n    }\n\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll INF = 1e18;\nconst ll RADIUS_SQ = 25000000LL; // 5000^2\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> x[i] >> y[i];\n    }\n    \n    // Graph and edge index mapping\n    vector<vector<ll>> distV(N, vector<ll>(N, INF));\n    vector<vector<int>> nextV(N, vector<int>(N, -1));\n    for (int i = 0; i < N; ++i) {\n        distV[i][i] = 0;\n        nextV[i][i] = i;\n    }\n    \n    vector<tuple<int, int, int>> edges(M);\n    vector<vector<int>> edgeIdx(N, vector<int>(N, -1));\n    for (int j = 0; j < M; ++j) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u, --v;\n        edges[j] = {u, v, w};\n        distV[u][v] = distV[v][u] = w;\n        nextV[u][v] = v;\n        nextV[v][u] = u;\n        edgeIdx[u][v] = edgeIdx[v][u] = j;\n    }\n    \n    // Residents\n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; ++k) {\n        cin >> a[k] >> b[k];\n    }\n    \n    // Precompute squared distances (integers)\n    vector<vector<ll>> sqDist(N, vector<ll>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            ll dx = x[i] - a[k];\n            ll dy = y[i] - b[k];\n            sqDist[i][k] = dx * dx + dy * dy;\n        }\n    }\n    \n    // Floyd-Warshall for shortest paths\n    for (int kk = 0; kk < N; ++kk) {\n        for (int i = 0; i < N; ++i) {\n            if (distV[i][kk] == INF) continue;\n            for (int j = 0; j < N; ++j) {\n                if (distV[kk][j] == INF) continue;\n                if (distV[i][j] > distV[i][kk] + distV[kk][j]) {\n                    distV[i][j] = distV[i][kk] + distV[kk][j];\n                    nextV[i][j] = nextV[i][kk];\n                }\n            }\n        }\n    }\n    \n    // Helper function to compute radius from maxSq\n    auto computeRadius = [](ll sq) -> int {\n        if (sq == 0) return 0;\n        // Compute integer ceiling of sqrt(sq)\n        int r = (int)sqrt((double)sq);\n        while ((ll)r * r < sq) ++r;\n        // Ensure radius <= 5000\n        return min(r, 5000);\n    };\n    \n    // Helper function to compute MST cost for a set of vertices\n    auto computeMSTCost = [&](const vector<int>& vertices) -> ll {\n        if (vertices.size() <= 1) return 0;\n        vector<tuple<ll, int, int>> mstEdges;\n        for (size_t i = 0; i < vertices.size(); ++i) {\n            for (size_t j = i + 1; j < vertices.size(); ++j) {\n                int u = vertices[i], v = vertices[j];\n                mstEdges.emplace_back(distV[u][v], u, v);\n            }\n        }\n        sort(mstEdges.begin(), mstEdges.end());\n        vector<int> parent(N);\n        iota(parent.begin(), parent.end(), 0);\n        function<int(int)> find = [&](int x) {\n            return parent[x] == x ? x : parent[x] = find(parent[x]);\n        };\n        ll cost = 0;\n        for (auto [w, u, v] : mstEdges) {\n            if (find(u) != find(v)) {\n                parent[find(u)] = find(v);\n                cost += w;\n            }\n        }\n        return cost;\n    };\n    \n    // Simple but effective initial vertex selection\n    vector<int> S;\n    vector<bool> covered(K, false);\n    \n    // Use set cover with variable radius (simpler approach that worked well)\n    for (int radius = 1000; radius <= 5000; radius += 1000) {\n        ll radius_sq = (ll)radius * radius;\n        fill(covered.begin(), covered.end(), false);\n        S.clear();\n        \n        // Set cover with current radius\n        while (true) {\n            int best = -1, bestCnt = 0;\n            for (int i = 0; i < N; ++i) {\n                int cnt = 0;\n                for (int k = 0; k < K; ++k) {\n                    if (!covered[k] && sqDist[i][k] <= radius_sq) {\n                        ++cnt;\n                    }\n                }\n                if (cnt > bestCnt) {\n                    bestCnt = cnt;\n                    best = i;\n                }\n            }\n            if (bestCnt == 0) break;\n            S.push_back(best);\n            for (int k = 0; k < K; ++k) {\n                if (sqDist[best][k] <= radius_sq) {\n                    covered[k] = true;\n                }\n            }\n        }\n        \n        // Check if all covered\n        bool all_covered = true;\n        for (int k = 0; k < K; ++k) {\n            if (!covered[k]) {\n                all_covered = false;\n                break;\n            }\n        }\n        if (all_covered) break;\n    }\n    \n    // Ensure vertex 0 is included\n    if (find(S.begin(), S.end(), 0) == S.end()) {\n        S.push_back(0);\n    }\n    \n    // Initial assignment: assign to vertex with smallest increase in radius\n    vector<int> assign(K);\n    vector<ll> maxSq(N, 0); // Maximum squared distance for each vertex\n    vector<vector<int>> residentsAt(N); // Which residents are assigned to each vertex\n    \n    for (int k = 0; k < K; ++k) {\n        ll bestScore = INF;\n        int bestV = -1;\n        for (int v : S) {\n            if (sqDist[v][k] > RADIUS_SQ) continue; // Must be within 5000\n            \n            ll currentMaxSq = maxSq[v];\n            ll newMaxSq = max(currentMaxSq, sqDist[v][k]);\n            ll score = newMaxSq - currentMaxSq; // Increase in squared distance\n            \n            if (score < bestScore) {\n                bestScore = score;\n                bestV = v;\n            }\n        }\n        \n        if (bestV == -1) {\n            // Fallback: assign to vertex with smallest distance\n            ll minDist = INF;\n            for (int v : S) {\n                if (sqDist[v][k] < minDist) {\n                    minDist = sqDist[v][k];\n                    bestV = v;\n                }\n            }\n        }\n        \n        assign[k] = bestV;\n        residentsAt[bestV].push_back(k);\n        if (sqDist[bestV][k] > maxSq[bestV]) {\n            maxSq[bestV] = sqDist[bestV][k];\n        }\n    }\n    \n    // Multi-pass optimization (the approach that worked well)\n    for (int pass = 0; pass < 3; ++pass) {\n        // Pass 0: Optimize high-radius vertices\n        // Pass 1: Optimize vertices with many residents\n        // Pass 2: Final cleanup\n        \n        bool improved = true;\n        int iterations = 0;\n        const int MAX_ITER = (pass == 2) ? 2 : 5; // Fewer iterations for final pass\n        \n        while (improved && iterations < MAX_ITER) {\n            improved = false;\n            ++iterations;\n            \n            vector<int> targetVertices;\n            if (pass == 0) {\n                // Target high-radius vertices\n                for (int v : S) {\n                    int radius = computeRadius(maxSq[v]);\n                    if (radius > 4000) {\n                        targetVertices.push_back(v);\n                    }\n                }\n            } else if (pass == 1) {\n                // Target vertices with many residents\n                for (int v : S) {\n                    if (residentsAt[v].size() > K / (int)S.size()) {\n                        targetVertices.push_back(v);\n                    }\n                }\n            } else {\n                // Final pass: target any vertex that can be improved\n                targetVertices = S;\n            }\n            \n            for (int v : targetVertices) {\n                int radiusV = computeRadius(maxSq[v]);\n                \n                // For residents assigned to v, try to reassign them to other vertices\n                for (int k : residentsAt[v]) {\n                    // In pass 0, only consider residents that contribute to max radius\n                    if (pass == 0 && sqDist[v][k] < maxSq[v]) continue;\n                    \n                    int bestU = -1;\n                    ll bestImprovement = 0;\n                    \n                    for (int u : S) {\n                        if (u == v) continue;\n                        if (sqDist[u][k] > RADIUS_SQ) continue;\n                        \n                        // Calculate potential improvement\n                        // New max for v without k\n                        ll newMaxSqV = 0;\n                        for (int k2 : residentsAt[v]) {\n                            if (k2 != k) {\n                                newMaxSqV = max(newMaxSqV, sqDist[v][k2]);\n                            }\n                        }\n                        \n                        ll newMaxSqU = max(maxSq[u], sqDist[u][k]);\n                        \n                        int oldRadiusV = radiusV;\n                        int oldRadiusU = computeRadius(maxSq[u]);\n                        int newRadiusV = computeRadius(newMaxSqV);\n                        int newRadiusU = computeRadius(newMaxSqU);\n                        \n                        ll oldCost = (ll)oldRadiusV * oldRadiusV + (ll)oldRadiusU * oldRadiusU;\n                        ll newCost = (ll)newRadiusV * newRadiusV + (ll)newRadiusU * newRadiusU;\n                        ll improvement = oldCost - newCost;\n                        \n                        if (improvement > bestImprovement) {\n                            bestImprovement = improvement;\n                            bestU = u;\n                        }\n                    }\n                    \n                    if (bestU != -1 && bestImprovement > 0) {\n                        // Reassign k from v to bestU\n                        residentsAt[v].erase(remove(residentsAt[v].begin(), residentsAt[v].end(), k), residentsAt[v].end());\n                        residentsAt[bestU].push_back(k);\n                        assign[k] = bestU;\n                        \n                        // Update maxSq for both vertices\n                        maxSq[v] = 0;\n                        for (int k2 : residentsAt[v]) {\n                            maxSq[v] = max(maxSq[v], sqDist[v][k2]);\n                        }\n                        maxSq[bestU] = max(maxSq[bestU], sqDist[bestU][k]);\n                        \n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        // Try to remove vertices (more aggressive in passes 0 and 1)\n        if (pass < 2) {\n            improved = true;\n            iterations = 0;\n            while (improved && iterations < 5) { // More iterations\n                improved = false;\n                ++iterations;\n                \n                for (size_t i = 0; i < S.size(); ++i) {\n                    int v = S[i];\n                    if (v == 0) continue;\n                    \n                    // Try to remove v (no restrictions on residents or radius)\n                    // Check if we can remove v\n                    bool canRemove = true;\n                    for (int k : residentsAt[v]) {\n                        bool found = false;\n                        for (int u : S) {\n                            if (u != v && sqDist[u][k] <= RADIUS_SQ) {\n                                found = true;\n                                break;\n                            }\n                        }\n                        if (!found) {\n                            canRemove = false;\n                            break;\n                        }\n                    }\n                    \n                    if (!canRemove) continue;\n                    \n                    // Reassign residents from v\n                    vector<int> newAssign = assign;\n                    vector<vector<int>> newResidentsAt = residentsAt;\n                    vector<ll> newMaxSq = maxSq;\n                    newResidentsAt[v].clear();\n                    newMaxSq[v] = 0;\n                    \n                    for (int k : residentsAt[v]) {\n                        ll bestDist = INF;\n                        int bestU = -1;\n                        for (int u : S) {\n                            if (u != v && sqDist[u][k] <= RADIUS_SQ) {\n                                if (sqDist[u][k] < bestDist) {\n                                    bestDist = sqDist[u][k];\n                                    bestU = u;\n                                }\n                            }\n                        }\n                        if (bestU != -1) {\n                            newAssign[k] = bestU;\n                            newResidentsAt[bestU].push_back(k);\n                            if (sqDist[bestU][k] > newMaxSq[bestU]) {\n                                newMaxSq[bestU] = sqDist[bestU][k];\n                            }\n                        }\n                    }\n                    \n                    // Compute new total cost\n                    ll newSumSq = 0;\n                    for (int u : S) {\n                        if (u == v) continue;\n                        int radius = computeRadius(newMaxSq[u]);\n                        newSumSq += (ll)radius * radius;\n                    }\n                    \n                    // Compute MST cost for new set (without v)\n                    vector<int> newS;\n                    for (int u : S) {\n                        if (u != v) newS.push_back(u);\n                    }\n                    \n                    if (newS.empty()) continue;\n                    \n                    ll newMSTCost = computeMSTCost(newS);\n                    ll newTotalCost = newSumSq + newMSTCost;\n                    \n                    // Compute current total cost\n                    ll currentSumSq = 0;\n                    for (int u : S) {\n                        int radius = computeRadius(maxSq[u]);\n                        currentSumSq += (ll)radius * radius;\n                    }\n                    ll currentMSTCost = computeMSTCost(S);\n                    ll currentTotalCost = currentSumSq + currentMSTCost;\n                    \n                    if (newTotalCost < currentTotalCost) {\n                        // Remove vertex v\n                        S = newS;\n                        assign = newAssign;\n                        residentsAt = newResidentsAt;\n                        maxSq = newMaxSq;\n                        improved = true;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Final assignment optimization\n    bool improved = true;\n    int iterations = 0;\n    while (improved && iterations < 3) {\n        improved = false;\n        ++iterations;\n        \n        for (int v : S) {\n            int radiusV = computeRadius(maxSq[v]);\n            \n            // For residents assigned to v, try to reassign them to other vertices\n            for (int k : residentsAt[v]) {\n                // Only consider residents that contribute to max radius\n                if (sqDist[v][k] < maxSq[v]) continue;\n                \n                int bestU = -1;\n                ll bestImprovement = 0;\n                \n                for (int u : S) {\n                    if (u == v) continue;\n                    if (sqDist[u][k] > RADIUS_SQ) continue;\n                    \n                    // Calculate potential improvement\n                    // New max for v without k\n                    ll newMaxSqV = 0;\n                    for (int k2 : residentsAt[v]) {\n                        if (k2 != k) {\n                            newMaxSqV = max(newMaxSqV, sqDist[v][k2]);\n                        }\n                    }\n                    \n                    ll newMaxSqU = max(maxSq[u], sqDist[u][k]);\n                    \n                    int oldRadiusV = radiusV;\n                    int oldRadiusU = computeRadius(maxSq[u]);\n                    int newRadiusV = computeRadius(newMaxSqV);\n                    int newRadiusU = computeRadius(newMaxSqU);\n                    \n                    ll oldCost = (ll)oldRadiusV * oldRadiusV + (ll)oldRadiusU * oldRadiusU;\n                    ll newCost = (ll)newRadiusV * newRadiusV + (ll)newRadiusU * newRadiusU;\n                    ll improvement = oldCost - newCost;\n                    \n                    if (improvement > bestImprovement) {\n                        bestImprovement = improvement;\n                        bestU = u;\n                    }\n                }\n                \n                if (bestU != -1 && bestImprovement > 0) {\n                    // Reassign k from v to bestU\n                    residentsAt[v].erase(remove(residentsAt[v].begin(), residentsAt[v].end(), k), residentsAt[v].end());\n                    residentsAt[bestU].push_back(k);\n                    assign[k] = bestU;\n                    \n                    // Update maxSq for both vertices\n                    maxSq[v] = 0;\n                    for (int k2 : residentsAt[v]) {\n                        maxSq[v] = max(maxSq[v], sqDist[v][k2]);\n                    }\n                    maxSq[bestU] = max(maxSq[bestU], sqDist[bestU][k]);\n                    \n                    improved = true;\n                }\n            }\n        }\n    }\n    \n    // Compute final P values (ensure they are \u2264 5000)\n    vector<int> P(N, 0);\n    for (int u : S) {\n        int radius = computeRadius(maxSq[u]);\n        P[u] = min(radius, 5000);\n    }\n    \n    // Build final MST\n    vector<tuple<ll, int, int>> finalMSTEdges;\n    for (size_t i = 0; i < S.size(); ++i) {\n        for (size_t j = i + 1; j < S.size(); ++j) {\n            int u = S[i], v = S[j];\n            finalMSTEdges.emplace_back(distV[u][v], u, v);\n        }\n    }\n    \n    sort(finalMSTEdges.begin(), finalMSTEdges.end());\n    vector<int> parent(N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find_func = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find_func(parent[x]);\n    };\n    \n    vector<pair<int, int>> mstPairs;\n    for (auto [w, u, v] : finalMSTEdges) {\n        if (find_func(u) != find_func(v)) {\n            parent[find_func(u)] = find_func(v);\n            mstPairs.emplace_back(u, v);\n        }\n    }\n    \n    // Turn on edges along shortest paths\n    vector<bool> edgeOn(M, false);\n    for (auto [u, v] : mstPairs) {\n        int cur = u;\n        while (cur != v) {\n            int nxt = nextV[cur][v];\n            int idx = edgeIdx[cur][nxt];\n            if (idx != -1) {\n                edgeOn[idx] = true;\n            }\n            cur = nxt;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; ++i) {\n        cout << P[i] << (i == N - 1 ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; ++j) {\n        cout << edgeOn[j] << (j == M - 1 ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 30, M = N*(N+1)/2;\n    int orig[N][N];\n    for(int i=0;i<N;i++) for(int j=0;j<=i;j++) cin>>orig[i][j];\n    \n    vector<pair<int,int>> parents;\n    for(int x=N-2;x>=0;x--) for(int y=x;y>=0;y--) parents.push_back({x,y});\n    int P = parents.size();\n    \n    auto solve = [&](const vector<pair<int,int>>& order)->int{\n        int g[N][N], px[M], py[M];\n        for(int i=0;i<N;i++) for(int j=0;j<=i;j++){\n            g[i][j]=orig[i][j]; px[g[i][j]]=i; py[g[i][j]]=j;\n        }\n        int cnt=0;\n        bool ch=true;\n        while(ch){ch=false;\n            for(auto&[x,y]:order){\n                int cx=x,cy=y;\n                while(cx<N-1){\n                    int v=g[cx][cy],lx=cx+1,ly=cy,rx=cx+1,ry=cy+1;\n                    int mx=cx,my=cy,mv=v;\n                    if(lx<N&&g[lx][ly]<mv){mx=lx;my=ly;mv=g[lx][ly];}\n                    if(rx<N&&g[rx][ry]<mv){mx=rx;my=ry;mv=g[rx][ry];}\n                    if(mx==cx&&my==cy)break;\n                    int a=g[cx][cy],b=g[mx][my];\n                    g[cx][cy]=b;g[mx][my]=a;\n                    px[a]=mx;py[a]=my;px[b]=cx;py[b]=cy;\n                    cnt++;ch=true;cx=mx;cy=my;\n                }\n            }\n        }\n        return cnt;\n    };\n    \n    int best_cnt = INT_MAX;\n    vector<pair<int,int>> best_order;\n    vector<pair<vector<pair<int,int>>,int>> top;\n    \n    auto try_ord=[&](vector<pair<int,int>> o){\n        int c=solve(o);\n        if(c<best_cnt){best_cnt=c;best_order=o;}\n        top.push_back({o,c});\n    };\n    \n    // Heuristic orderings\n    try_ord(parents);\n    {auto o=parents;reverse(o.begin(),o.end());try_ord(o);}\n    \n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){if(a.first!=b.first)return a.first>b.first;return a.second<b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){if(a.first!=b.first)return a.first>b.first;return a.second>b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){if(a.first!=b.first)return a.first<b.first;return a.second<b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){if(a.first!=b.first)return a.first<b.first;return a.second>b.second;});try_ord(o);}\n    \n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first+a.second<b.first+b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first+a.second>b.first+b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first-a.second<b.first-b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first-a.second>b.first-b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return abs(a.first-a.second)<abs(b.first-b.second);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return abs(a.first-a.second)>abs(b.first-b.second);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){int da=min(a.second,a.first-a.second),db=min(b.second,b.first-b.second);return da<db;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){int da=min(a.second,a.first-a.second),db=min(b.second,b.first-b.second);return da>db;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first*a.second<b.first*b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first*a.second>b.first*b.second;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){int da=abs(2*a.second-a.first),db=abs(2*b.second-b.first);return da<db;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){int da=abs(2*a.second-a.first),db=abs(2*b.second-b.first);return da>db;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){int da=a.first*a.first+a.second*a.second,db=b.first*b.first+b.second*b.second;return da<db;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){int da=a.first*a.first+a.second*a.second,db=b.first*b.first+b.second*b.second;return da>db;});try_ord(o);}\n    \n    for(int p=0;p<2;p++){\n        {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){\n            if(a.first!=b.first)return a.first>b.first;return(p==0)?a.second<b.second:a.second>b.second;});try_ord(o);}\n        {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){\n            if(a.first!=b.first)return a.first>b.first;return(p==0)?a.second>b.second:a.second<b.second;});try_ord(o);}\n        {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){\n            if(a.first!=b.first)return a.first<b.first;\n            int ay=(p==0)?a.second:a.first-a.second,by=(p==0)?b.second:b.first-b.second;return ay<by;});try_ord(o);}\n    }\n    \n    {auto o=parents;stable_sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.second<b.second;});try_ord(o);}\n    {auto o=parents;stable_sort(o.begin(),o.end(),[&](auto&a,auto&b){return a.first<b.first;});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return max(a.first,a.second)<max(b.first,b.second);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return max(a.first,a.second)>max(b.first,b.second);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){\n        if(a.first!=b.first)return a.first>b.first;return abs(2*a.second-a.first)<abs(2*b.second-b.first);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){\n        if(a.first!=b.first)return a.first<b.first;return abs(2*a.second-a.first)<abs(2*b.second-b.first);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){return(a.first^a.second)>(b.first^b.second);});try_ord(o);}\n    {auto o=parents;sort(o.begin(),o.end(),[&](auto&a,auto&b){\n        int da=a.first*a.first-a.second*a.second,db=b.first*b.first-b.second*b.second;return da<db;});try_ord(o);}\n    \n    // Random trials\n    for(int s=1;s<=600;s++){\n        auto o=parents; mt19937 rng(s); shuffle(o.begin(),o.end(),rng); try_ord(o);\n    }\n    \n    // Local search on top 80\n    sort(top.begin(),top.end(),[&](auto&a,auto&b){return a.second<b.second;});\n    int rc=min(80,(int)top.size());\n    for(int r=0;r<rc;r++){\n        for(int t=0;t<150;t++){\n            mt19937 rng(50000+r*300+t);\n            auto o=top[r].first;\n            int k=rng()%5+1;\n            for(int j=0;j<k;j++) swap(o[rng()%P],o[rng()%P]);\n            try_ord(o);\n        }\n    }\n    \n    // Second phase: deeper local search on very best\n    sort(top.begin(),top.end(),[&](auto&a,auto&b){return a.second<b.second;});\n    for(int r=0;r<min(10,(int)top.size());r++){\n        for(int t=0;t<300;t++){\n            mt19937 rng(200000+r*500+t);\n            auto o=top[r].first;\n            int k=rng()%4+1;\n            for(int j=0;j<k;j++) swap(o[rng()%P],o[rng()%P]);\n            try_ord(o);\n        }\n    }\n    \n    // Final random burst\n    for(int s=50000;s<=50300;s++){\n        auto o=parents; mt19937 rng(s); shuffle(o.begin(),o.end(),rng); try_ord(o);\n    }\n    \n    // Output using best order\n    int g[N][N], px[M], py[M];\n    for(int i=0;i<N;i++) for(int j=0;j<=i;j++){\n        g[i][j]=orig[i][j]; px[g[i][j]]=i; py[g[i][j]]=j;\n    }\n    vector<array<int,4>> ops;\n    bool ch=true;\n    while(ch){ch=false;\n        for(auto&[x,y]:best_order){\n            int cx=x,cy=y;\n            while(cx<N-1){\n                int v=g[cx][cy],lx=cx+1,ly=cy,rx=cx+1,ry=cy+1;\n                int mx=cx,my=cy,mv=v;\n                if(lx<N&&g[lx][ly]<mv){mx=lx;my=ly;mv=g[lx][ly];}\n                if(rx<N&&g[rx][ry]<mv){mx=rx;my=ry;mv=g[rx][ry];}\n                if(mx==cx&&my==cy)break;\n                ops.push_back({cx,cy,mx,my});\n                int a=g[cx][cy],b=g[mx][my];\n                g[cx][cy]=b;g[mx][my]=a;\n                px[a]=mx;py[a]=my;px[b]=cx;py[b]=cy;\n                ch=true;cx=mx;cy=my;\n            }\n        }\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto&o:ops)cout<<o[0]<<\" \"<<o[1]<<\" \"<<o[2]<<\" \"<<o[3]<<\"\\n\";\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n#include <cmath>\n#include <set>\n#include <climits>\n#include <functional>\nusing namespace std;\n\nconst int entrance_i = 0, entrance_j = 4;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nbool obstacle[9][9] = {false};\nbool occupied[9][9] = {false};\nint placed_number[9][9];\nvector<pair<int, int>> container_squares;\nint M;\nint dist[9][9];\nint min_d = INT_MAX, max_d = 0;\n\ninline bool in_bounds(int i, int j) {\n    return i >= 0 && i < 9 && j >= 0 && j < 9;\n}\n\nvoid compute_distances() {\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    dist[entrance_i][entrance_j] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || dist[nx][ny] != -1) continue;\n            dist[nx][ny] = dist[x][y] + 1;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    for (auto [i, j] : container_squares) {\n        if (dist[i][j] != -1) {\n            min_d = min(min_d, dist[i][j]);\n            max_d = max(max_d, dist[i][j]);\n        }\n    }\n}\n\nvector<pair<int, int>> get_reachable() {\n    bool vis[9][9] = {false};\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    vis[entrance_i][entrance_j] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n            if (nx == entrance_i && ny == entrance_j) continue;\n            if (occupied[nx][ny]) continue;\n            vis[nx][ny] = true;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    vector<pair<int, int>> reachable;\n    for (auto [i, j] : container_squares) {\n        if (vis[i][j] && !occupied[i][j]) {\n            reachable.emplace_back(i, j);\n        }\n    }\n    return reachable;\n}\n\nbool would_disconnect(int i, int j, int remaining) {\n    occupied[i][j] = true;\n    \n    bool vis[9][9] = {false};\n    queue<pair<int, int>> q;\n    q.emplace(entrance_i, entrance_j);\n    vis[entrance_i][entrance_j] = true;\n    int count = 1;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n            if (occupied[nx][ny]) continue;\n            vis[nx][ny] = true;\n            count++;\n            q.emplace(nx, ny);\n        }\n    }\n    \n    occupied[i][j] = false;\n    return count != remaining;\n}\n\n// Trap detection: check if placing here would trap any small numbers\ndouble trap_avoidance_score(int i, int j, int remaining, int current_t) {\n    // Temporarily occupy (i,j)\n    occupied[i][j] = true;\n    \n    double penalty = 0;\n    \n    // Check if any small numbers (t < M/3) become unreachable\n    for (auto [x, y] : container_squares) {\n        if (occupied[x][y]) continue;\n        if (placed_number[x][y] == -1 || placed_number[x][y] >= M/3) continue;\n        \n        // This is a small number - check if it's still reachable\n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        bool reachable = false;\n        \n        while (!q.empty() && !reachable) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny] || occupied[nx][ny]) continue;\n                if (nx == x && ny == y) {\n                    reachable = true;\n                    break;\n                }\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n        \n        if (!reachable) {\n            // Heavy penalty for trapping a small number\n            penalty += 50.0 * (1.0 - (double)placed_number[x][y] / (M - 1));\n        }\n    }\n    \n    occupied[i][j] = false;\n    return penalty;\n}\n\n// Strategic value with number-awareness\ndouble number_aware_strategic_value(int i, int j, int remaining) {\n    occupied[i][j] = true;\n    \n    double penalty = 0;\n    for (auto [x, y] : container_squares) {\n        if (occupied[x][y]) continue;\n        \n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        bool reachable = false;\n        \n        while (!q.empty() && !reachable) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny] || occupied[nx][ny]) continue;\n                if (nx == x && ny == y) {\n                    reachable = true;\n                    break;\n                }\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n        \n        if (!reachable) {\n            if (placed_number[x][y] != -1) {\n                // Quadratic weight for small numbers\n                double t_norm = (double)placed_number[x][y] / (M - 1);\n                double weight = (1.0 - t_norm) * (1.0 - t_norm); // Quadratic\n                penalty += 12.0 * weight;\n            } else {\n                penalty += 6.0;\n            }\n        }\n    }\n    \n    occupied[i][j] = false;\n    return penalty / (remaining + 1e-9);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    memset(placed_number, -1, sizeof(placed_number));\n    \n    for (int k = 0; k < N; ++k) {\n        int ri, rj;\n        cin >> ri >> rj;\n        obstacle[ri][rj] = true;\n    }\n    \n    for (int i = 0; i < 9; ++i) {\n        for (int j = 0; j < 9; ++j) {\n            if (i == entrance_i && j == entrance_j) continue;\n            if (obstacle[i][j]) continue;\n            container_squares.emplace_back(i, j);\n        }\n    }\n    M = container_squares.size();\n    \n    compute_distances();\n    \n    int placed = 0;\n    \n    for (int step = 0; step < M; ++step) {\n        int t;\n        cin >> t;\n        \n        auto reachable = get_reachable();\n        int remaining = M - placed;\n        \n        vector<pair<int, int>> safe_squares;\n        for (auto [i, j] : reachable) {\n            if (!would_disconnect(i, j, remaining)) {\n                safe_squares.emplace_back(i, j);\n            }\n        }\n        \n        if (safe_squares.empty()) {\n            safe_squares = reachable;\n        }\n        \n        pair<int, int> best_pos = safe_squares[0];\n        double best_score = -1e18;\n        \n        double fill_ratio = (double)placed / M;\n        double t_percentile = (double)t / (M - 1);\n        \n        for (auto [i, j] : safe_squares) {\n            int d = dist[i][j];\n            double normalized_d = (max_d == min_d) ? 0.5 : (double)(d - min_d) / (max_d - min_d);\n            \n            // Distance score with adaptive exponent\n            double distance_error = abs(normalized_d - t_percentile);\n            double distance_exponent = 2.5 + 1.5 * fill_ratio;\n            double distance_score = 110.0 * exp(-distance_exponent * distance_error);\n            \n            // Trap avoidance (critical for worst cases)\n            double trap_penalty = trap_avoidance_score(i, j, remaining, t);\n            double trap_score = 100.0 * exp(-0.5 * trap_penalty);\n            \n            // Number-aware strategic value\n            double strategic_penalty = number_aware_strategic_value(i, j, remaining);\n            double strategic_score = 90.0 * exp(-1.8 * strategic_penalty);\n            \n            // Neighbor connectivity\n            int neighbor_count = 0;\n            int empty_neighbors = 0;\n            int small_neighbors = 0;\n            for (int dd = 0; dd < 4; ++dd) {\n                int ni = i + dx[dd], nj = j + dy[dd];\n                if (in_bounds(ni, nj) && !obstacle[ni][nj]) {\n                    neighbor_count++;\n                    if (!occupied[ni][nj]) {\n                        empty_neighbors++;\n                        if (placed_number[ni][nj] != -1 && placed_number[ni][nj] < M/4) {\n                            small_neighbors++;\n                        }\n                    }\n                }\n            }\n            double neighbor_score = (8.0 * empty_neighbors + 15.0 * small_neighbors + 2.0 * neighbor_count);\n            neighbor_score *= exp(-1.2 * fill_ratio);\n            \n            // Path diversity\n            int path_count = 0;\n            for (int dd = 0; dd < 4; ++dd) {\n                int ni = i + dx[dd], nj = j + dy[dd];\n                if (in_bounds(ni, nj) && !obstacle[ni][nj] && dist[ni][nj] != -1 && dist[ni][nj] < dist[i][j]) {\n                    path_count++;\n                }\n            }\n            double diversity_score = 12.0 * min(path_count, 2) / 2.0;\n            \n            // Special handling for extreme numbers\n            double special_bonus = 0;\n            if (t_percentile < 0.12) {\n                special_bonus = 70.0 * (1.0 - normalized_d);\n            } else if (t_percentile > 0.88) {\n                special_bonus = 70.0 * normalized_d;\n            }\n            \n            // Critical path penalty\n            int critical_paths = 0;\n            for (int dd = 0; dd < 4; ++dd) {\n                int ni = i + dx[dd], nj = j + dy[dd];\n                if (in_bounds(ni, nj) && !obstacle[ni][nj] && dist[ni][nj] == dist[i][j] - 1) {\n                    critical_paths++;\n                }\n            }\n            double critical_penalty = (critical_paths == 1 && t_percentile < 0.3) ? 40.0 : 0.0;\n            \n            // Combined score\n            double score = distance_score + trap_score + strategic_score + \n                          neighbor_score + diversity_score + special_bonus - critical_penalty;\n            \n            // Deterministic tie-breaker\n            score += (i * 9 + j) * 1e-6;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_pos = {i, j};\n            }\n        }\n        \n        auto [pi, pj] = best_pos;\n        cout << pi << \" \" << pj << endl;\n        occupied[pi][pj] = true;\n        placed_number[pi][pj] = t;\n        placed++;\n    }\n    \n    // Optimal retrieval: always take smallest reachable number\n    vector<pair<int, int>> retrieval_order;\n    \n    bool sim_occupied[9][9];\n    int sim_numbers[9][9];\n    memcpy(sim_occupied, occupied, sizeof(sim_occupied));\n    memcpy(sim_numbers, placed_number, sizeof(sim_numbers));\n    \n    while (retrieval_order.size() < M) {\n        bool vis[9][9] = {false};\n        queue<pair<int, int>> q;\n        q.emplace(entrance_i, entrance_j);\n        vis[entrance_i][entrance_j] = true;\n        \n        vector<pair<int, int>> reachable;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (!in_bounds(nx, ny) || obstacle[nx][ny] || vis[nx][ny]) continue;\n                if (sim_occupied[nx][ny]) {\n                    reachable.emplace_back(nx, ny);\n                    vis[nx][ny] = true;\n                } else {\n                    vis[nx][ny] = true;\n                    q.emplace(nx, ny);\n                }\n            }\n        }\n        \n        if (reachable.empty()) break;\n        \n        auto best_square = reachable[0];\n        for (auto [i, j] : reachable) {\n            if (sim_numbers[i][j] < sim_numbers[best_square.first][best_square.second]) {\n                best_square = {i, j};\n            }\n        }\n        \n        retrieval_order.push_back(best_square);\n        sim_occupied[best_square.first][best_square.second] = false;\n    }\n    \n    for (auto [i, j] : retrieval_order) {\n        cout << i << \" \" << j << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n#include <functional>\n#include <set>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\n\nvector<vector<int>> grid;\nvector<int> color_size;\nvector<bool> adj0_orig;\nvector<int> boundary_count;\nvector<vector<bool>> adj_orig;\nvector<vector<int>> edge;\n\n// Check if removing cell (i,j) would disconnect its color component\nbool is_articulation(int i, int j, int c) {\n    if (color_size[c] <= 1) return true;\n    \n    // Quick check: if the cell has only one neighbor of same color, it's not articulation\n    int same_neighbors = 0;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == c) {\n            same_neighbors++;\n        }\n    }\n    if (same_neighbors <= 1) return false;\n    \n    // BFS to check connectivity without this cell\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    queue<pair<int, int>> q;\n    \n    // Start from a neighbor of the same color\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == c) {\n            visited[ni][nj] = true;\n            q.push({ni, nj});\n            break;\n        }\n    }\n    \n    if (q.empty()) return true; // No neighbor, would disconnect\n    \n    int count = 0;\n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        count++;\n        \n        for (int d = 0; d < 4; ++d) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N && \n                grid[nx][ny] == c && !visited[nx][ny] &&\n                !(nx == i && ny == j)) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return count != color_size[c] - 1;\n}\n\n// Check if a cell can be removed\nbool can_remove(int i, int j) {\n    int c = grid[i][j];\n    bool on_boundary = (i == 0 || i == N-1 || j == 0 || j == N-1);\n    \n    // Basic checks\n    if (color_size[c] <= 1) return false;\n    \n    // For interior cells, must be adjacent to an existing 0 cell\n    if (!on_boundary) {\n        bool adjacent_to_zero = false;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] == 0) {\n                adjacent_to_zero = true;\n                break;\n            }\n        }\n        if (!adjacent_to_zero) return false;\n    }\n    \n    // Count neighbors by color\n    int nc = 0; // same color neighbors\n    int n0 = 0; // zero neighbors\n    vector<int> cnt(M + 1, 0);\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            int dcol = grid[ni][nj];\n            if (dcol == c) nc++;\n            else if (dcol == 0) n0++;\n            else cnt[dcol]++;\n        }\n    }\n    \n    // Check if we can remove a cell of a color not adjacent to 0\n    if (!adj0_orig[c]) {\n        // Must have no same-color neighbors (to avoid creating new c-0 adjacency)\n        if (nc > 0) return false;\n        // All neighbor colors must be originally adjacent to 0\n        for (int d = 1; d <= M; ++d) {\n            if (cnt[d] > 0 && !adj0_orig[d]) return false;\n        }\n        // Must not break adjacencies with other colors\n        for (int d = 1; d <= M; ++d) {\n            if (d == c) continue;\n            if (adj_orig[c][d] && cnt[d] > 0 && edge[c][d] - cnt[d] < 1) {\n                return false;\n            }\n        }\n        // Must not disconnect\n        if (is_articulation(i, j, c)) return false;\n        return true;\n    }\n    \n    // For colors adjacent to 0\n    // Check that all neighbor colors are originally adjacent to 0\n    for (int d = 1; d <= M; ++d) {\n        if (cnt[d] > 0 && !adj0_orig[d]) {\n            return false;\n        }\n    }\n    \n    // Check adjacency preservation for inter-color edges\n    for (int d = 1; d <= M; ++d) {\n        if (d == c) continue;\n        if (adj_orig[c][d]) {\n            if (cnt[d] > 0 && edge[c][d] - cnt[d] < 1) {\n                return false;\n            }\n        }\n    }\n    \n    // Check adjacency with 0\n    int contributions = (on_boundary ? 1 : 0) + n0;\n    int new_edge_c0 = edge[c][0] - contributions + nc;\n    if (new_edge_c0 < 1) {\n        return false;\n    }\n    \n    // Must not disconnect\n    if (is_articulation(i, j, c)) return false;\n    \n    return true;\n}\n\n// Remove a cell and update data structures\nvoid remove_cell(int i, int j) {\n    int c = grid[i][j];\n    bool on_boundary = (i == 0 || i == N-1 || j == 0 || j == N-1);\n    \n    // Update edge counts for neighbors\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            int dcol = grid[ni][nj];\n            if (dcol != c) {\n                edge[c][dcol]--;\n                edge[dcol][c]--;\n            }\n        }\n    }\n    if (on_boundary) {\n        edge[c][0]--;\n        edge[0][c]--;\n    }\n    \n    // Set cell to 0\n    grid[i][j] = 0;\n    \n    // Add new edges from this cell as 0 to neighbors\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n            int dcol = grid[ni][nj];\n            if (dcol != 0) {\n                edge[0][dcol]++;\n                edge[dcol][0]++;\n            }\n        }\n    }\n    \n    // Update color size and boundary count\n    color_size[c]--;\n    if (on_boundary) {\n        boundary_count[c]--;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n_input, m_input;\n    cin >> n_input >> m_input;\n    \n    grid.resize(N, vector<int>(N));\n    color_size.resize(M + 1, 0);\n    adj0_orig.resize(M + 1, false);\n    boundary_count.resize(M + 1, 0);\n    adj_orig.resize(M + 1, vector<bool>(M + 1, false));\n    edge.resize(M + 1, vector<int>(M + 1, 0));\n    \n    // Read input\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n            int c = grid[i][j];\n            color_size[c]++;\n            if (i == 0 || i == N-1 || j == 0 || j == N-1) {\n                adj0_orig[c] = true;\n                boundary_count[c]++;\n            }\n        }\n    }\n    \n    // Compute original adjacencies and initial edge counts\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int c = grid[i][j];\n            // Right neighbor\n            if (j + 1 < N) {\n                int d = grid[i][j + 1];\n                if (c != d) {\n                    adj_orig[c][d] = adj_orig[d][c] = true;\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // Down neighbor\n            if (i + 1 < N) {\n                int d = grid[i + 1][j];\n                if (c != d) {\n                    adj_orig[c][d] = adj_orig[d][c] = true;\n                    edge[c][d]++;\n                    edge[d][c]++;\n                }\n            }\n            // Boundary adjacency with 0\n            if (i == 0 || i == N-1 || j == 0 || j == N-1) {\n                edge[c][0]++;\n                edge[0][c]++;\n            }\n        }\n    }\n    \n    // Priority queue for candidates\n    // We'll use a set to avoid duplicates and allow updates\n    set<tuple<int, int, int>> candidate_set;\n    auto add_candidate = [&](int i, int j) {\n        int c = grid[i][j];\n        if (c == 0) return;\n        \n        // Count neighbors\n        int same_neighbors = 0;\n        int diff_neighbors = 0;\n        int n0 = 0;\n        for (int d = 0; d < 4; ++d) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                if (grid[ni][nj] == c) same_neighbors++;\n                else if (grid[ni][nj] == 0) n0++;\n                else diff_neighbors++;\n            }\n        }\n        \n        // Calculate priority - we want to remove leaves first\n        // For colors adjacent to 0:\n        //   - Highest priority: cells with 1 same-color neighbor (leaves)\n        //   - Next: cells with 2 same-color neighbors\n        //   - Then: cells with more same-color neighbors\n        //   - Also prioritize cells with more 0 neighbors\n        // For colors not adjacent to 0:\n        //   - Only cells with 0 same-color neighbors are removable\n        int priority;\n        if (adj0_orig[c]) {\n            if (same_neighbors == 1) priority = 10000;  // Leaf - highest priority\n            else if (same_neighbors == 2) priority = 5000;  // Next best\n            else if (same_neighbors == 0) priority = 2000;  // Isolated (rare)\n            else priority = 1000;  // Interior cells\n            priority += n0 * 100 - diff_neighbors * 10;\n        } else {\n            priority = (same_neighbors == 0 ? 10000 : 0) + n0 * 100 - diff_neighbors * 10;\n        }\n        \n        candidate_set.insert({-priority, i, j});\n    };\n    \n    // Initialize with all cells that could potentially be removed\n    // We start with all cells that are either on boundary or adjacent to 0\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] > 0) {\n                bool candidate = false;\n                if (i == 0 || i == N-1 || j == 0 || j == N-1) {\n                    candidate = true;\n                } else {\n                    for (int d = 0; d < 4; ++d) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (grid[ni][nj] == 0) {\n                            candidate = true;\n                            break;\n                        }\n                    }\n                }\n                if (candidate) {\n                    add_candidate(i, j);\n                }\n            }\n        }\n    }\n    \n    // Process candidates\n    while (!candidate_set.empty()) {\n        auto [p, i, j] = *candidate_set.begin();\n        candidate_set.erase(candidate_set.begin());\n        \n        if (grid[i][j] == 0) continue;\n        \n        if (can_remove(i, j)) {\n            remove_cell(i, j);\n            \n            // Add neighbors to candidates\n            for (int d = 0; d < 4; ++d) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] > 0) {\n                    add_candidate(ni, nj);\n                }\n            }\n        }\n    }\n    \n    // Output final 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 << '\\n';\n    }\n    \n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <string>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint used = 0;\nint N, D, Q;\n\nstring do_query(int l, int r) {\n    cout << \"1 1 \" << l << \" \" << r << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nstring compare_groups(const vector<int>& a, const vector<int>& b) {\n    cout << a.size() << \" \" << b.size();\n    for (int x : a) cout << \" \" << x;\n    for (int x : b) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    string res;\n    cin >> res;\n    used++;\n    return res;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    // Initialize random generator for shuffling\n    unsigned seed = chrono::system_clock::now().time_since_epoch().count();\n    mt19937 rng(seed);\n    \n    // Create initial order and shuffle\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    \n    // Estimate required comparisons for full sorting (information-theoretic bound)\n    double log3_fact = 0.0;\n    for (int i = 2; i <= N; i++) {\n        log3_fact += log(i) / log(3.0);\n    }\n    int full_sort_comparisons = static_cast<int>(ceil(log3_fact));\n    \n    // Estimate comparisons for heap-based greedy: O(N log D)\n    int greedy_comparisons = static_cast<int>(N * ceil(log2(D)));\n    \n    // Adaptive strategy selection\n    bool use_greedy = false;\n    int sort_limit = Q;\n    \n    // More aggressive threshold: use greedy if we have at least 100 comparisons for sorting\n    // and enough for greedy\n    if (Q >= greedy_comparisons + 100) {\n        use_greedy = true;\n        sort_limit = min(full_sort_comparisons, Q - greedy_comparisons);\n    } else if (Q >= 2 * N && Q >= greedy_comparisons * 0.8) {\n        // For moderate Q, use greedy with partial sorting\n        use_greedy = true;\n        sort_limit = Q - greedy_comparisons;\n    } else {\n        // Not enough for greedy, use snake order\n        use_greedy = false;\n        sort_limit = Q;\n    }\n    \n    // Ensure we have at least some sorting\n    sort_limit = max(sort_limit, min(50, Q));\n    \n    vector<int> sorted;\n    sorted.reserve(N);\n    \n    // Binary insertion sort with limited comparisons\n    for (int x : order) {\n        if (used >= sort_limit) {\n            sorted.push_back(x);\n            continue;\n        }\n        \n        int low = 0, high = sorted.size();\n        while (low < high && used < sort_limit) {\n            int mid = (low + high) / 2;\n            string res = do_query(x, sorted[mid]);\n            \n            bool mid_is_heavier;\n            if (res == \">\") {\n                mid_is_heavier = true;\n            } else if (res == \"<\") {\n                mid_is_heavier = false;\n            } else {\n                // Tie-break by index\n                mid_is_heavier = (sorted[mid] < x);\n            }\n            \n            if (mid_is_heavier) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        sorted.insert(sorted.begin() + low, x);\n    }\n    \n    vector<int> group(N, -1);  // Initialize with -1 to detect unassigned items\n    \n    if (use_greedy) {\n        // Heap-based greedy assignment\n        vector<vector<int>> groups(D);\n        \n        // Assign first D items to different groups (heaviest items)\n        for (int i = 0; i < D && i < (int)sorted.size(); i++) {\n            groups[i].push_back(sorted[i]);\n            group[sorted[i]] = i;\n        }\n        \n        // Create a list of group indices sorted by current sum\n        vector<int> sorted_groups;\n        \n        // Insert non-empty groups into sorted list using binary search with comparisons\n        for (int g = 0; g < D; g++) {\n            if (groups[g].empty()) continue;\n            \n            int low = 0, high = sorted_groups.size();\n            while (low < high && used < Q) {\n                int mid = (low + high) / 2;\n                string res = compare_groups(groups[g], groups[sorted_groups[mid]]);\n                \n                bool g_is_lighter;\n                if (res == \"<\") {\n                    g_is_lighter = true;\n                } else if (res == \">\") {\n                    g_is_lighter = false;\n                } else {\n                    // Tie-break by group index\n                    g_is_lighter = (g < sorted_groups[mid]);\n                }\n                \n                if (g_is_lighter) {\n                    high = mid;\n                } else {\n                    low = mid + 1;\n                }\n            }\n            sorted_groups.insert(sorted_groups.begin() + low, g);\n        }\n        \n        // Assign remaining items to smallest group\n        for (int i = D; i < (int)sorted.size(); i++) {\n            int item = sorted[i];\n            \n            // If we've run out of queries, assign to first group\n            if (used >= Q || sorted_groups.empty()) {\n                // Find any non-empty group or use group 0\n                int target_group = 0;\n                for (int g = 0; g < D; g++) {\n                    if (!groups[g].empty()) {\n                        target_group = g;\n                        break;\n                    }\n                }\n                groups[target_group].push_back(item);\n                group[item] = target_group;\n                continue;\n            }\n            \n            // Get the smallest group (first in sorted_groups)\n            int smallest_group = sorted_groups[0];\n            groups[smallest_group].push_back(item);\n            group[item] = smallest_group;\n            \n            // Remove the smallest group from sorted list\n            sorted_groups.erase(sorted_groups.begin());\n            \n            // If we have queries left, re-insert the updated group\n            if (used < Q) {\n                int low = 0, high = sorted_groups.size();\n                while (low < high && used < Q) {\n                    int mid = (low + high) / 2;\n                    string res = compare_groups(groups[smallest_group], groups[sorted_groups[mid]]);\n                    \n                    bool is_lighter;\n                    if (res == \"<\") {\n                        is_lighter = true;\n                    } else if (res == \">\") {\n                        is_lighter = false;\n                    } else {\n                        is_lighter = (smallest_group < sorted_groups[mid]);\n                    }\n                    \n                    if (is_lighter) {\n                        high = mid;\n                    } else {\n                        low = mid + 1;\n                    }\n                }\n                sorted_groups.insert(sorted_groups.begin() + low, smallest_group);\n            } else {\n                // No queries left, just append to end (will be chosen last)\n                sorted_groups.push_back(smallest_group);\n            }\n        }\n        \n        // Ensure all items are assigned (should be already assigned above)\n        for (int i = 0; i < N; i++) {\n            if (group[i] == -1) {\n                // Assign unassigned items to group 0\n                group[i] = 0;\n            }\n        }\n    } else {\n        // Snake order assignment (fallback)\n        int cur_group = 0;\n        int step = 1;\n        for (int idx : sorted) {\n            group[idx] = cur_group;\n            cur_group += step;\n            if (cur_group == D) {\n                cur_group = D - 1;\n                step = -1;\n            } else if (cur_group == -1) {\n                cur_group = 0;\n                step = 1;\n            }\n        }\n        \n        // Ensure all items are assigned\n        for (int i = 0; i < N; i++) {\n            if (group[i] == -1) {\n                // This shouldn't happen, but assign to group 0 if it does\n                group[i] = 0;\n            }\n        }\n    }\n    \n    // Use any remaining queries as dummy queries\n    while (used < Q) {\n        do_query(0, 1);\n    }\n    \n    // Output the division\n    for (int i = 0; i < N; i++) {\n        if (i) cout << \" \";\n        cout << group[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; ++i) {\n        int cnt = n / m;\n        stacks[i].resize(cnt);\n        for (int j = 0; j < cnt; ++j) {\n            cin >> stacks[i][j];\n        }\n    }\n\n    vector<pair<int, int>> ops;\n    int next_box = 1;\n\n    // Helper to find the position of a box\n    auto find_box = [&](int val) -> pair<int, int> {\n        for (int i = 0; i < m; ++i) {\n            for (int j = 0; j < (int)stacks[i].size(); ++j) {\n                if (stacks[i][j] == val) {\n                    return {i, j};\n                }\n            }\n        }\n        return {-1, -1};\n    };\n\n    // Helper to get the top value of a stack (or INT_MAX if empty)\n    auto get_top = [&](int stack_idx) -> int {\n        if (stacks[stack_idx].empty()) return INT_MAX;\n        return stacks[stack_idx].back();\n    };\n\n    // Helper to check if a stack is decreasing (largest at bottom, smallest at top)\n    auto is_decreasing = [](const vector<int>& stack) -> bool {\n        for (size_t i = 1; i < stack.size(); ++i) {\n            if (stack[i] >= stack[i-1]) return false;\n        }\n        return true;\n    };\n\n    // Helper to count empty stacks\n    auto count_empty = [&]() -> int {\n        int count = 0;\n        for (int i = 0; i < m; ++i) {\n            if (stacks[i].empty()) count++;\n        }\n        return count;\n    };\n\n    while (next_box <= n) {\n        auto [s, idx] = find_box(next_box);\n        \n        if (idx == (int)stacks[s].size() - 1) {\n            // Already on top - carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        } else {\n            // Need to move boxes above it\n            int w = stacks[s][idx + 1];\n            \n            // Extract the segment above next_box\n            vector<int> segment(stacks[s].begin() + idx + 1, stacks[s].end());\n            \n            // Find best destination with refined adaptive strategy\n            int d = -1;\n            int best_score = INT_MIN;\n            int empty_stacks = count_empty();\n            \n            // Refined aggressive mode: only when we have many empty stacks AND the segment is decreasing\n            bool aggressive_mode = (empty_stacks >= 4) && (ops.size() < 1500) && is_decreasing(segment);\n            \n            for (int i = 0; i < m; ++i) {\n                if (i == s) continue;\n                \n                int score = 0;\n                \n                // Empty stack is excellent\n                if (stacks[i].empty()) {\n                    score += 1000;\n                    if (empty_stacks <= 2) score += 300;\n                } else {\n                    int dest_top = get_top(i);\n                    int block_bottom = segment[0];\n                    int block_top = segment.back();\n                    \n                    // If destination top > block bottom, order is maintained\n                    if (dest_top > block_bottom) {\n                        score += 500;\n                    }\n                    \n                    // Check if the block itself is decreasing\n                    bool block_decreasing = is_decreasing(segment);\n                    if (block_decreasing) {\n                        score += 300;\n                    }\n                    \n                    // Prefer stacks with larger tops (to avoid burying small boxes)\n                    score += dest_top / 10;\n                    \n                    // Penalize if we're creating a very tall stack\n                    if (stacks[i].size() > 15) {\n                        score -= 200;\n                    }\n                    \n                    // In aggressive mode, be extra smart about placement\n                    if (aggressive_mode) {\n                        // If moving this block here would put the next box we need on top\n                        if (block_top == next_box + 1) {\n                            score += 350;  // Slightly reduced bonus\n                        }\n                        // Also consider if this would help the next few boxes\n                        if (block_top <= next_box + 3 && block_top >= next_box + 1) {\n                            score += 100;\n                        }\n                    }\n                }\n                \n                // Smart penalty for block top being close to current smallest\n                int block_top = segment.back();\n                if (block_top == next_box + 1) {\n                    score += 200;  // The next box we need is on top of the block\n                } else if (block_top <= next_box + 10) {\n                    // Adaptive penalty: stronger when we have fewer empty stacks\n                    int penalty = 300;\n                    if (empty_stacks <= 1) penalty = 400;  // Stronger penalty when we're tight on space\n                    score -= penalty;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    d = i;\n                }\n            }\n            \n            // Fallback if no good destination found\n            if (d == -1) {\n                // Prefer stacks with largest tops\n                int max_top = -1;\n                for (int i = 0; i < m; ++i) {\n                    if (i != s && !stacks[i].empty()) {\n                        int top_val = get_top(i);\n                        if (top_val > max_top) {\n                            max_top = top_val;\n                            d = i;\n                        }\n                    }\n                }\n                // If all other stacks are empty, pick the first one\n                if (d == -1) {\n                    for (int i = 0; i < m; ++i) {\n                        if (i != s) {\n                            d = i;\n                            break;\n                        }\n                    }\n                }\n            }\n\n            // Move the entire segment\n            ops.emplace_back(w, d + 1);\n            stacks[d].insert(stacks[d].end(), segment.begin(), segment.end());\n            \n            // Remove the moved boxes from source stack\n            stacks[s].resize(idx + 1);\n            \n            // Now next_box is on top - carry out\n            ops.emplace_back(next_box, 0);\n            stacks[s].pop_back();\n            ++next_box;\n        }\n        \n        // Refined maintenance: more intelligent and adaptive\n        if (ops.size() < 3500) {  // Slightly more conservative threshold\n            int empty_stacks = count_empty();\n            // Only perform maintenance if we have at least one empty stack or are early in the process\n            if (empty_stacks > 0 || ops.size() < 2000) {\n                for (int i = 0; i < m; ++i) {\n                    if (stacks[i].size() > 1) {\n                        // Check if the top two boxes are out of order\n                        if (stacks[i].size() >= 2) {\n                            int top = stacks[i].back();\n                            int below = stacks[i][stacks[i].size() - 2];\n                            if (top > below) { // Should be decreasing, so top should be smaller\n                                // Find a place to move the top box\n                                // Prefer empty stacks if available\n                                bool moved = false;\n                                if (empty_stacks > 0) {\n                                    for (int j = 0; j < m; ++j) {\n                                        if (stacks[j].empty()) {\n                                            ops.emplace_back(top, j + 1);\n                                            stacks[j].push_back(top);\n                                            stacks[i].pop_back();\n                                            moved = true;\n                                            break;\n                                        }\n                                    }\n                                }\n                                // If no empty stack used, find a stack with larger top\n                                if (!moved) {\n                                    for (int j = 0; j < m; ++j) {\n                                        if (j != i && !stacks[j].empty() && \n                                            stacks[j].back() > top) {\n                                            ops.emplace_back(top, j + 1);\n                                            stacks[j].push_back(top);\n                                            stacks[i].pop_back();\n                                            break;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output operations\n    for (auto [v, i] : ops) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <array>\n#include <functional>\n\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_NODES = MAX_N * MAX_N;\nconst int DIRS = 4;\nconst int di[DIRS] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dj[DIRS] = {0, 0, -1, 1};\nconst char dir_char[DIRS] = {'U', 'D', 'L', 'R'};\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nvector<vector<double>> sqrt_d;\nvector<array<int, 4>> neighbors;\nvector<vector<int>> dist;\nvector<vector<int>> next_move;\n\nvoid build_graph() {\n    int total = N * N;\n    neighbors.assign(total, {-1, -1, -1, -1});\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            int node = i * N + j;\n            if (i < N-1 && h[i][j] == '0') {\n                int ni = i+1, nj = j;\n                int nnode = ni * N + nj;\n                neighbors[node][1] = nnode;\n                neighbors[nnode][0] = node;\n            }\n            if (j < N-1 && v[i][j] == '0') {\n                int ni = i, nj = j+1;\n                int nnode = ni * N + nj;\n                neighbors[node][3] = nnode;\n                neighbors[nnode][2] = node;\n            }\n        }\n    }\n}\n\nvoid precompute_paths() {\n    int total = N * N;\n    dist.assign(total, vector<int>(total, -1));\n    next_move.assign(total, vector<int>(total, -1));\n    for (int s = 0; s < total; ++s) {\n        queue<int> q;\n        q.push(s);\n        dist[s][s] = 0;\n        next_move[s][s] = -1;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int v = neighbors[u][dir];\n                if (v == -1) continue;\n                if (dist[s][v] == -1) {\n                    dist[s][v] = dist[s][u] + 1;\n                    if (u == s) {\n                        next_move[s][v] = dir;\n                    } else {\n                        next_move[s][v] = next_move[s][u];\n                    }\n                    q.push(v);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    for (int i = 0; i < N-1; ++i) cin >> h[i];\n    v.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    sqrt_d.assign(N, vector<double>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n            sqrt_d[i][j] = sqrt(d[i][j]);\n        }\n    }\n\n    build_graph();\n    precompute_paths();\n\n    int total_nodes = N * N;\n    int home = 0;\n    const int L_max = 100000;\n\n    string moves;\n    vector<int> m(total_nodes, 0);\n    vector<bool> visited(total_nodes, false);\n    int current = home;\n\n    // Proper DFS that generates a minimal traversal\n    // We'll use recursion with backtracking\n    function<void(int)> dfs = [&](int node) {\n        visited[node] = true;\n        \n        // Sort neighbors by \u221ad descending\n        vector<pair<double, int>> sorted_neighbors;\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[node][dir];\n            if (nb == -1) continue;\n            int i = nb / N, j = nb % N;\n            sorted_neighbors.emplace_back(sqrt_d[i][j], dir);\n        }\n        sort(sorted_neighbors.rbegin(), sorted_neighbors.rend());\n        \n        for (auto [_, dir] : sorted_neighbors) {\n            int nb = neighbors[node][dir];\n            if (nb == -1 || visited[nb]) continue;\n            \n            // Move to neighbor\n            moves += dir_char[dir];\n            current = nb;\n            m[current]++;\n            \n            // Recursively visit\n            dfs(nb);\n            \n            // Backtrack\n            int opposite_dir = dir ^ 1;\n            moves += dir_char[opposite_dir];\n            current = node;\n            m[current]++;\n        }\n    };\n    \n    // Start DFS from home\n    dfs(home);\n\n    // Now we have a DFS traversal that returns to home\n    // The length should be 2*(N^2-1) which is at most 2*1599 = 3198\n    \n    // Phase 2: Extend the walk to approach L_max moves\n    int current_length = moves.size();\n    \n    // If we already have more than L_max moves, truncate\n    if (current_length > L_max) {\n        moves.resize(L_max);\n        cout << moves << endl;\n        return 0;\n    }\n    \n    // Otherwise, extend with simple, safe moves\n    while (current_length < L_max) {\n        int remaining = L_max - current_length;\n        int dist_home = dist[current][home];\n        \n        // If we can't make any more moves and return home, break\n        if (remaining <= dist_home) {\n            break;\n        }\n        \n        // Find the neighbor with highest \u221ad that still allows returning home\n        double best_score = -1.0;\n        int best_dir = -1;\n        \n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb == -1) continue;\n            \n            int new_dist_home = dist[nb][home];\n            if (remaining - 1 < new_dist_home) {\n                continue; // Can't return home if we make this move\n            }\n            \n            int i = nb / N, j = nb % N;\n            double score = sqrt_d[i][j] / (m[nb] + 1.0);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        if (best_dir == -1) {\n            // No safe move to a better square, try any safe move\n            for (int dir = 0; dir < DIRS; ++dir) {\n                int nb = neighbors[current][dir];\n                if (nb == -1) continue;\n                \n                int new_dist_home = dist[nb][home];\n                if (remaining - 1 >= new_dist_home) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir == -1) {\n            // No safe move at all, break\n            break;\n        }\n        \n        // Make the move\n        moves += dir_char[best_dir];\n        current = neighbors[current][best_dir];\n        m[current]++;\n        current_length++;\n    }\n    \n    // Return home\n    while (current != home && current_length < L_max) {\n        int dir = next_move[current][home];\n        if (dir == -1) break;\n        moves += dir_char[dir];\n        current = neighbors[current][dir];\n        m[current]++;\n        current_length++;\n    }\n    \n    // If we still have moves left, add simple loops at home\n    while (current_length < L_max) {\n        // Find any valid move from home\n        for (int dir = 0; dir < DIRS; ++dir) {\n            int nb = neighbors[current][dir];\n            if (nb != -1) {\n                // Go to neighbor and back\n                moves += dir_char[dir];\n                current = neighbors[current][dir];\n                m[current]++;\n                current_length++;\n                if (current_length >= L_max) break;\n                \n                moves += dir_char[dir ^ 1]; // opposite direction\n                current = neighbors[current][dir ^ 1];\n                m[current]++;\n                current_length++;\n                break;\n            }\n        }\n    }\n\n    // Ensure we end at home\n    if (current != home) {\n        // This shouldn't happen, but if it does, try to go home\n        while (current != home && moves.size() < L_max) {\n            int dir = next_move[current][home];\n            if (dir == -1) break;\n            moves += dir_char[dir];\n            current = neighbors[current][dir];\n        }\n    }\n\n    // Final check: ensure we don't exceed L_max\n    if (moves.size() > L_max) {\n        moves.resize(L_max);\n    }\n\n    cout << moves << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int M_MAX = 200;\nusing Bits = bitset<M_MAX>;\n\n// Global variables\nunordered_map<string, int> pat_to_idx_global;\nconst int INF = 1e9;\n\n// Helper: compute which patterns appear in a string\nBits compute_cov(const string& s) {\n    Bits bs;\n    int L = s.size();\n    for (int i = 0; i <= L - 5; ++i) {\n        string sub = s.substr(i, 5);\n        auto it = pat_to_idx_global.find(sub);\n        if (it != pat_to_idx_global.end()) {\n            bs.set(it->second);\n        }\n    }\n    return bs;\n}\n\n// Compute maximum overlap for appending (suffix of a matches prefix of b)\nint compute_append_overlap(const string& a, const string& b) {\n    int max_o = 0;\n    for (int o = 5; o >= 1; --o) {\n        if (a.size() >= o && b.size() >= o) {\n            if (a.substr(a.size() - o) == b.substr(0, o)) {\n                max_o = o;\n                break;\n            }\n        }\n    }\n    return max_o;\n}\n\n// Compute DP for a string from start, returns minimal cost and DP for last character\npair<int, vector<int>> compute_dp_full(const string& s, int start_id,\n                                      const vector<vector<int>>& pos_for_char,\n                                      const vector<vector<int>>& dist) {\n    if (s.empty()) return {0, vector<int>(225, INF)};\n    int L = s.size();\n    vector<vector<int>> dp(L, vector<int>(225, INF));\n    \n    // First character\n    for (int id : pos_for_char[s[0] - 'A']) {\n        dp[0][id] = dist[start_id][id] + 1;\n    }\n    \n    // Rest of characters\n    for (int i = 1; i < L; ++i) {\n        char c = s[i];\n        for (int id : pos_for_char[c - 'A']) {\n            int best = INF;\n            char prev_c = s[i-1];\n            for (int prev_id : pos_for_char[prev_c - 'A']) {\n                if (dp[i-1][prev_id] < INF) {\n                    int cost = dp[i-1][prev_id] + dist[prev_id][id] + 1;\n                    if (cost < best) best = cost;\n                }\n            }\n            dp[i][id] = best;\n        }\n    }\n    \n    // Find minimum cost at last character\n    int min_cost = INF;\n    for (int id : pos_for_char[s.back() - 'A']) {\n        if (dp[L-1][id] < min_cost) min_cost = dp[L-1][id];\n    }\n    \n    return {min_cost, dp[L-1]};\n}\n\n// Compute additional cost for typing new_part starting from current_dp and last_char\npair<int, vector<int>> compute_additional_cost(const vector<int>& current_dp, \n                                              char last_char,\n                                              const string& new_part,\n                                              const vector<vector<int>>& pos_for_char,\n                                              const vector<vector<int>>& dist) {\n    if (new_part.empty()) return {0, current_dp};\n    \n    int L = new_part.size();\n    vector<vector<int>> dp(L, vector<int>(225, INF));\n    \n    // First character of new_part\n    for (int id : pos_for_char[new_part[0] - 'A']) {\n        int best = INF;\n        for (int prev_id : pos_for_char[last_char - 'A']) {\n            if (current_dp[prev_id] < INF) {\n                int cost = current_dp[prev_id] + dist[prev_id][id] + 1;\n                if (cost < best) best = cost;\n            }\n        }\n        dp[0][id] = best;\n    }\n    \n    // Rest of characters\n    for (int i = 1; i < L; ++i) {\n        char c = new_part[i];\n        for (int id : pos_for_char[c - 'A']) {\n            int best = INF;\n            char prev_c = new_part[i-1];\n            for (int prev_id : pos_for_char[prev_c - 'A']) {\n                if (dp[i-1][prev_id] < INF) {\n                    int cost = dp[i-1][prev_id] + dist[prev_id][id] + 1;\n                    if (cost < best) best = cost;\n                }\n            }\n            dp[i][id] = best;\n        }\n    }\n    \n    // Find minimum cost at last character\n    int min_additional = INF;\n    for (int id : pos_for_char[new_part.back() - 'A']) {\n        if (dp[L-1][id] < min_additional) min_additional = dp[L-1][id];\n    }\n    \n    return {min_additional, dp[L-1]};\n}\n\n// DP-guided greedy superstring construction with incremental DP\nstring dp_guided_greedy(const vector<string>& patterns, \n                        const vector<int>& pattern_costs,\n                        int start_id,\n                        const vector<vector<int>>& pos_for_char,\n                        const vector<vector<int>>& dist,\n                        mt19937& rng) {\n    int M = patterns.size();\n    vector<bool> used(M, false);\n    \n    // Sort patterns by cost to get the best starting candidates\n    vector<int> sorted_indices(M);\n    iota(sorted_indices.begin(), sorted_indices.end(), 0);\n    sort(sorted_indices.begin(), sorted_indices.end(), \n         [&](int a, int b) { return pattern_costs[a] < pattern_costs[b]; });\n    \n    // Choose initial pattern from top 5\n    int num_top = min(5, M);\n    uniform_int_distribution<int> dist_top(0, num_top - 1);\n    int init_idx = sorted_indices[dist_top(rng)];\n    \n    string current = patterns[init_idx];\n    used[init_idx] = true;\n    \n    auto [current_total_cost, current_dp] = compute_dp_full(current, start_id, pos_for_char, dist);\n    char current_last_char = current.back();\n    \n    // Create shuffled order for remaining patterns\n    vector<int> remaining;\n    for (int i = 0; i < M; ++i) {\n        if (!used[i]) remaining.push_back(i);\n    }\n    shuffle(remaining.begin(), remaining.end(), rng);\n    \n    // Keep adding patterns\n    for (int step = 1; step < M; ++step) {\n        // Find the next pattern among unused ones that minimizes total cost\n        int best_total_cost = INF;\n        int best_idx = -1;\n        string best_new_part;\n        vector<int> best_new_dp;\n        \n        for (int idx : remaining) {\n            if (used[idx]) continue;\n            \n            const string& pat = patterns[idx];\n            // Check if already contained\n            if (current.find(pat) != string::npos) {\n                used[idx] = true;\n                continue;\n            }\n            \n            int overlap = compute_append_overlap(current, pat);\n            string new_part = pat.substr(overlap);\n            \n            auto [additional_cost, new_dp] = compute_additional_cost(\n                current_dp, current_last_char, new_part, pos_for_char, dist);\n            \n            int total_cost = current_total_cost + additional_cost;\n            \n            // Tie-breaking: prefer shorter new_part, then lower additional cost\n            if (total_cost < best_total_cost || \n                (total_cost == best_total_cost && \n                 (best_new_part.empty() || new_part.size() < best_new_part.size()))) {\n                best_total_cost = total_cost;\n                best_idx = idx;\n                best_new_part = new_part;\n                best_new_dp = new_dp;\n            }\n        }\n        \n        if (best_idx == -1) break; // No more patterns\n        \n        // Update current string and DP\n        current += best_new_part;\n        current_total_cost = best_total_cost;\n        current_dp = best_new_dp;\n        current_last_char = current.back();\n        used[best_idx] = true;\n        \n        // Remove used pattern from remaining list\n        auto it = find(remaining.begin(), remaining.end(), best_idx);\n        if (it != remaining.end()) remaining.erase(it);\n    }\n    \n    return current;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    random_device rd;\n    mt19937 rng(rd());\n\n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<string> patterns(M);\n    for (int k = 0; k < M; ++k) {\n        cin >> patterns[k];\n        pat_to_idx_global[patterns[k]] = k;\n    }\n\n    // Build position data and distance matrix\n    vector<vector<int>> pos_for_char(26);\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            char c = grid[i][j];\n            pos_for_char[c - 'A'].push_back(i * N + j);\n        }\n    }\n\n    const int CELLS = N * N;\n    vector<vector<int>> dist(CELLS, vector<int>(CELLS));\n    for (int id1 = 0; id1 < CELLS; ++id1) {\n        int x1 = id1 / N, y1 = id1 % N;\n        for (int id2 = 0; id2 < CELLS; ++id2) {\n            int x2 = id2 / N, y2 = id2 % N;\n            dist[id1][id2] = abs(x1 - x2) + abs(y1 - y2);\n        }\n    }\n\n    int start_id = si * N + sj;\n    \n    // Precompute pattern costs\n    vector<int> pattern_costs(M);\n    for (int i = 0; i < M; ++i) {\n        pattern_costs[i] = compute_dp_full(patterns[i], start_id, pos_for_char, dist).first;\n    }\n    \n    // Run multiple trials with different random orders\n    const int NUM_TRIALS = 5;\n    string best_superstring;\n    int best_cost = INF;\n    \n    for (int trial = 0; trial < NUM_TRIALS; ++trial) {\n        string superstring = dp_guided_greedy(patterns, pattern_costs, start_id, pos_for_char, dist, rng);\n        int cost = compute_dp_full(superstring, start_id, pos_for_char, dist).first;\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_superstring = superstring;\n        }\n    }\n    \n    // Final DP for optimal key sequence (with backtracking)\n    int L = best_superstring.size();\n    vector<vector<int>> dp(L, vector<int>(225, INF));\n    vector<vector<int>> parent(L, vector<int>(225, -1));\n    \n    // First character\n    for (int id : pos_for_char[best_superstring[0] - 'A']) {\n        dp[0][id] = dist[start_id][id] + 1;\n        parent[0][id] = -1;\n    }\n    \n    // Rest of characters\n    for (int i = 1; i < L; ++i) {\n        char c = best_superstring[i];\n        for (int id : pos_for_char[c - 'A']) {\n            int best = INF;\n            int best_prev = -1;\n            char prev_c = best_superstring[i-1];\n            for (int prev_id : pos_for_char[prev_c - 'A']) {\n                if (dp[i-1][prev_id] < INF) {\n                    int cost = dp[i-1][prev_id] + dist[prev_id][id] + 1;\n                    if (cost < best) {\n                        best = cost;\n                        best_prev = prev_id;\n                    }\n                }\n            }\n            dp[i][id] = best;\n            parent[i][id] = best_prev;\n        }\n    }\n    \n    // Find best final state\n    int best_id = -1;\n    int best_final_cost = INF;\n    for (int id : pos_for_char[best_superstring.back() - 'A']) {\n        if (dp[L-1][id] < best_final_cost) {\n            best_final_cost = dp[L-1][id];\n            best_id = id;\n        }\n    }\n    \n    // Backtrack to get path\n    vector<int> path_ids(L);\n    int cur_id = best_id;\n    for (int i = L-1; i >= 0; --i) {\n        path_ids[i] = cur_id;\n        cur_id = parent[i][cur_id];\n    }\n    \n    // Output\n    for (int id : path_ids) {\n        int x = id / N, y = id % N;\n        cout << x << \" \" << y << \"\\n\";\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cstring>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n\n    // Read shapes (not used in this approach)\n    for (int k = 0; k < M; ++k) {\n        int d;\n        cin >> d;\n        for (int s = 0; s < d; ++s) {\n            int i, j;\n            cin >> i >> j;\n        }\n    }\n\n    vector<pair<int, int>> positives;\n    vector<vector<bool>> drilled(N, vector<bool>(N, false));\n    queue<pair<int, int>> q;\n\n    // Helper function to drill a square\n    auto drill = [&](int i, int j) {\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        int val;\n        cin >> val;\n        return val;\n    };\n\n    // Initial sparse drilling: checkerboard pattern\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if ((i + j) % 2 == 0) {\n                int val = drill(i, j);\n                drilled[i][j] = true;\n                if (val > 0) {\n                    positives.emplace_back(i, j);\n                    // Add neighbors to queue\n                    if (i + 1 < N) q.emplace(i + 1, j);\n                    if (i - 1 >= 0) q.emplace(i - 1, j);\n                    if (j + 1 < N) q.emplace(i, j + 1);\n                    if (j - 1 >= 0) q.emplace(i, j - 1);\n                }\n            }\n        }\n    }\n\n    // BFS from queued squares\n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        if (drilled[i][j]) continue;\n        \n        int val = drill(i, j);\n        drilled[i][j] = true;\n        if (val > 0) {\n            positives.emplace_back(i, j);\n            // Add neighbors\n            if (i + 1 < N && !drilled[i + 1][j]) q.emplace(i + 1, j);\n            if (i - 1 >= 0 && !drilled[i - 1][j]) q.emplace(i - 1, j);\n            if (j + 1 < N && !drilled[i][j + 1]) q.emplace(i, j + 1);\n            if (j - 1 >= 0 && !drilled[i][j - 1]) q.emplace(i, j - 1);\n        }\n    }\n\n    // Output final guess\n    cout << \"a \" << positives.size();\n    for (auto [i, j] : positives) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    cout.flush();\n    \n    int resp;\n    cin >> resp;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    int area;\n};\n\n// tries to pack rectangles with desired areas B (sorted descending) using common row height H\n// returns true and fills rects if successful\nbool pack(int W, int H, const vector<int>& B, vector<Rect>& rects) {\n    int N = B.size();\n    vector<int> w(N);\n    for (int i = 0; i < N; ++i) {\n        w[i] = (B[i] + H - 1) / H;          // width needed for area at least B[i]\n        if (w[i] > W) return false;         // too wide to fit\n    }\n    // indices sorted by width descending (first-fit decreasing)\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) { return w[i] > w[j]; });\n\n    vector<int> row_used;                     // used width in each row\n    vector<vector<pair<int, int>>> row_items; // each row: (rectangle index, start_x)\n\n    for (int i : idx) {\n        int placed = -1;\n        for (int r = 0; r < (int)row_used.size(); ++r) {\n            if (row_used[r] + w[i] <= W) {\n                placed = r;\n                break;\n            }\n        }\n        if (placed == -1) {                   // start new row\n            row_used.push_back(w[i]);\n            row_items.push_back({{i, 0}});\n        } else {\n            int start_x = row_used[placed];\n            row_used[placed] += w[i];\n            row_items[placed].emplace_back(i, start_x);\n        }\n    }\n\n    int rows = row_used.size();\n    if (rows * H > W) return false;           // total height exceeds W\n\n    rects.assign(N, Rect());\n    for (int r = 0; r < rows; ++r) {\n        int y0 = r * H;\n        int y1 = y0 + H;\n        for (auto& p : row_items[r]) {\n            int id = p.first;\n            int x0 = p.second;\n            rects[id].x0 = x0;\n            rects[id].x1 = x0 + w[id];\n            rects[id].y0 = y0;\n            rects[id].y1 = y1;\n            rects[id].area = w[id] * H;\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W, D, N;\n    cin >> W >> D >> N;\n\n    vector<vector<int>> a_original(D, vector<int>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> a_original[d][k];\n\n    // ----- build descending demands per day -----\n    vector<vector<int>> a_desc(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        a_desc[d] = a_original[d];\n        sort(a_desc[d].begin(), a_desc[d].end(), greater<int>());\n    }\n\n    // ----- for each position i (i-th largest) collect values over days -----\n    vector<vector<int>> slot_vals(N, vector<int>(D));\n    for (int i = 0; i < N; ++i) {\n        for (int d = 0; d < D; ++d)\n            slot_vals[i][d] = a_desc[d][i];\n        sort(slot_vals[i].begin(), slot_vals[i].end(), greater<int>());\n    }\n\n    // ----- water filling to obtain optimal target areas b[i] -----\n    vector<int> b(N, 0);\n    vector<int> ptr(N, D);                // number of values > current b[i]\n    using P = pair<int, int>;\n    priority_queue<P> pq;                 // max-heap by f = ptr\n    for (int i = 0; i < N; ++i)\n        pq.emplace(ptr[i], i);\n\n    const int S = W * W;\n    int total_used = 0;\n    while (total_used < S && !pq.empty()) {\n        auto [f, i] = pq.top();\n        pq.pop();\n        if (f != ptr[i]) continue;        // outdated entry\n        if (f == 0) break;                // no further improvement possible\n        // add one unit to rectangle i\n        b[i]++;\n        total_used++;\n        // update ptr[i]\n        while (ptr[i] > 0 && slot_vals[i][ptr[i] - 1] <= b[i])\n            ptr[i]--;\n        pq.emplace(ptr[i], i);\n    }\n\n    // b now contains the desired areas; sort them descending\n    vector<int> B = b;\n    sort(B.begin(), B.end(), greater<int>());\n\n    // ----- pack rectangles into the W x W square -----\n    vector<Rect> rects;\n    int H_min = 0;\n    for (int bi : B)\n        H_min = max(H_min, (bi + W - 1) / W);   // smallest H such that width <= W\n\n    bool packed = false;\n    auto pack_lambda = [&](int H, const vector<int>& B, vector<Rect>& rects) -> bool {\n        return pack(W, H, B, rects);\n    };\n    for (int H = H_min; H <= W; ++H) {\n        if (pack_lambda(H, B, rects)) {\n            packed = true;\n            break;\n        }\n    }\n    if (!packed) {   // fallback: vertical strips of almost equal width\n        int Nrect = B.size();\n        vector<int> widths(Nrect, W / Nrect);\n        int rem = W % Nrect;\n        for (int i = 0; i < rem; ++i) widths[i]++;\n        rects.resize(Nrect);\n        int x = 0;\n        for (int i = 0; i < Nrect; ++i) {\n            rects[i].x0 = x;\n            rects[i].x1 = x + widths[i];\n            rects[i].y0 = 0;\n            rects[i].y1 = W;\n            rects[i].area = widths[i] * W;\n            x += widths[i];\n        }\n    }\n\n    // ----- order rectangles by area (largest first) -----\n    vector<int> rect_order(N);\n    iota(rect_order.begin(), rect_order.end(), 0);\n    sort(rect_order.begin(), rect_order.end(),\n         [&](int i, int j) { return rects[i].area > rects[j].area; });\n\n    // ----- assign rectangles to reservations each day -----\n    vector<vector<int>> assign(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        vector<pair<int, int>> dem;   // (demand, original index)\n        for (int k = 0; k < N; ++k)\n            dem.emplace_back(a_original[d][k], k);\n        sort(dem.begin(), dem.end(), greater<pair<int, int>>());\n        for (int t = 0; t < N; ++t) {\n            int orig_k = dem[t].second;\n            int ridx = rect_order[t];\n            assign[d][orig_k] = ridx;\n        }\n    }\n\n    // ----- output -----\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            int r = assign[d][k];\n            cout << rects[r].x0 << \" \" << rects[r].y0 << \" \"\n                 << rects[r].x1 << \" \" << rects[r].y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst ll MOD = 998244353;\n\nll mod(ll x) {\n    return ((x % MOD) + MOD) % MOD;\n}\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    vector<vector<ll>> a(N, vector<ll>(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    vector<vector<vector<ll>>> s(M, vector<vector<ll>>(3, vector<ll>(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    // Randomized greedy initial solution\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    vector<vector<ll>> board = a;\n    vector<tuple<int, int, int>> ops;\n    for (int step = 0; step < K; ++step) {\n        vector<tuple<ll, int, int, int>> candidates; // gain, m, p, q\n        for (int m = 0; m < M; ++m) {\n            for (int p = 0; p <= N - 3; ++p) {\n                for (int q = 0; q <= N - 3; ++q) {\n                    ll gain = 0;\n                    for (int di = 0; di < 3; ++di) {\n                        for (int dj = 0; dj < 3; ++dj) {\n                            int i = p + di, j = q + dj;\n                            ll old_val = board[i][j];\n                            ll add = s[m][di][dj];\n                            ll new_val = old_val + add;\n                            gain += mod(new_val) - mod(old_val);\n                        }\n                    }\n                    candidates.emplace_back(gain, m, p, q);\n                }\n            }\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        // Pick one of the top 5 randomly, if available\n        int num_candidates = min(5, (int)candidates.size());\n        uniform_int_distribution<int> rand_cand(0, num_candidates - 1);\n        int idx = rand_cand(rng);\n        auto [best_gain, best_m, best_p, best_q] = candidates[idx];\n        if (best_gain <= 0) break;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj) {\n                int i = best_p + di, j = best_q + dj;\n                board[i][j] += s[best_m][di][dj];\n            }\n        }\n        ops.emplace_back(best_m, best_p, best_q);\n    }\n\n    // Compute current score\n    ll current_score = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_score += mod(board[i][j]);\n        }\n    }\n    ll best_score = current_score;\n    auto best_board = board;\n    auto best_ops = ops;\n\n    // Simulated Annealing\n    uniform_real_distribution<double> uniform(0.0, 1.0);\n    uniform_int_distribution<int> rand_op(0, M - 1);\n    uniform_int_distribution<int> rand_pos(0, N - 3);\n\n    const int SA_ITER = 800000;\n    double T = 1e10;\n    const double cooling = 0.9999945;\n\n    int L = ops.size();\n    for (int iter = 0; iter < SA_ITER; ++iter) {\n        if (L == 0 && K == 0) break;\n        double move_choice = uniform(rng);\n        int move_type;\n        if (L == 0) move_type = 0; // add\n        else if (L == K) {\n            if (move_choice < 0.15) move_type = 1; // remove\n            else if (move_choice < 0.35) move_type = 2; // replace\n            else if (move_choice < 0.65) move_type = 3; // double replace\n            else move_type = 4; // swap (only if L>=2)\n            if (move_type == 3 && L < 2) move_type = (move_choice < 0.5) ? 1 : 2;\n            if (move_type == 4 && L < 2) move_type = (move_choice < 0.5) ? 1 : 2;\n        } else {\n            if (move_choice < 0.1) move_type = 0; // add\n            else if (move_choice < 0.2) move_type = 1; // remove\n            else if (move_choice < 0.4) move_type = 2; // replace\n            else if (move_choice < 0.7) move_type = 3; // double replace\n            else move_type = 4; // swap\n            if (move_type == 3 && L < 2) move_type = (move_choice < 0.55) ? 0 : 2;\n            if (move_type == 4 && L < 2) move_type = (move_choice < 0.55) ? 0 : 2;\n        }\n\n        ll delta = 0;\n        if (move_type == 0) { // add\n            if (L >= K) continue;\n            int m = rand_op(rng);\n            int p = rand_pos(rng);\n            int q = rand_pos(rng);\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val + s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] += s[m][di][dj];\n                    }\n                }\n                ops.emplace_back(m, p, q);\n                L++;\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else if (move_type == 1) { // remove\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m, p, q] = ops[idx];\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    int i = p + di, j = q + dj;\n                    ll old_val = board[i][j];\n                    ll new_val = old_val - s[m][di][dj];\n                    delta += mod(new_val) - mod(old_val);\n                }\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p + di, j = q + dj;\n                        board[i][j] -= s[m][di][dj];\n                    }\n                }\n                ops.erase(ops.begin() + idx);\n                L--;\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else if (move_type == 2) { // replace\n            if (L <= 0) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx = rand_idx(rng);\n            auto [m_old, p_old, q_old] = ops[idx];\n            int m_new = rand_op(rng);\n            int p_new = rand_pos(rng);\n            int q_new = rand_pos(rng);\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p_old + di, q_old + dj});\n                    cells.insert({p_new + di, q_new + dj});\n                }\n            }\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                if (i >= p_old && i < p_old + 3 && j >= q_old && j < q_old + 3) {\n                    int di = i - p_old, dj = j - q_old;\n                    new_val -= s[m_old][di][dj];\n                }\n                if (i >= p_new && i < p_new + 3 && j >= q_new && j < q_new + 3) {\n                    int di = i - p_new, dj = j - q_new;\n                    new_val += s[m_new][di][dj];\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_old + di, j = q_old + dj;\n                        board[i][j] -= s[m_old][di][dj];\n                    }\n                }\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        int i = p_new + di, j = q_new + dj;\n                        board[i][j] += s[m_new][di][dj];\n                    }\n                }\n                ops[idx] = {m_new, p_new, q_new};\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else if (move_type == 3) { // double replace\n            if (L < 2) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx1 = rand_idx(rng);\n            int idx2 = rand_idx(rng);\n            while (idx2 == idx1) idx2 = rand_idx(rng);\n            auto [m_old1, p_old1, q_old1] = ops[idx1];\n            auto [m_old2, p_old2, q_old2] = ops[idx2];\n            int m_new1 = rand_op(rng), p_new1 = rand_pos(rng), q_new1 = rand_pos(rng);\n            int m_new2 = rand_op(rng), p_new2 = rand_pos(rng), q_new2 = rand_pos(rng);\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p_old1 + di, q_old1 + dj});\n                    cells.insert({p_old2 + di, q_old2 + dj});\n                    cells.insert({p_new1 + di, q_new1 + dj});\n                    cells.insert({p_new2 + di, q_new2 + dj});\n                }\n            }\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                if (i >= p_old1 && i < p_old1 + 3 && j >= q_old1 && j < q_old1 + 3) {\n                    int di = i - p_old1, dj = j - q_old1;\n                    new_val -= s[m_old1][di][dj];\n                }\n                if (i >= p_old2 && i < p_old2 + 3 && j >= q_old2 && j < q_old2 + 3) {\n                    int di = i - p_old2, dj = j - q_old2;\n                    new_val -= s[m_old2][di][dj];\n                }\n                if (i >= p_new1 && i < p_new1 + 3 && j >= q_new1 && j < q_new1 + 3) {\n                    int di = i - p_new1, dj = j - q_new1;\n                    new_val += s[m_new1][di][dj];\n                }\n                if (i >= p_new2 && i < p_new2 + 3 && j >= q_new2 && j < q_new2 + 3) {\n                    int di = i - p_new2, dj = j - q_new2;\n                    new_val += s[m_new2][di][dj];\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                // Remove old operations (larger index first to avoid shifting issues)\n                int first = idx1, second = idx2;\n                if (first < second) swap(first, second);\n                ops.erase(ops.begin() + first);\n                ops.erase(ops.begin() + second);\n                // Add new operations\n                ops.emplace_back(m_new1, p_new1, q_new1);\n                ops.emplace_back(m_new2, p_new2, q_new2);\n                // Update board\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        board[p_old1 + di][q_old1 + dj] -= s[m_old1][di][dj];\n                        board[p_old2 + di][q_old2 + dj] -= s[m_old2][di][dj];\n                        board[p_new1 + di][q_new1 + dj] += s[m_new1][di][dj];\n                        board[p_new2 + di][q_new2 + dj] += s[m_new2][di][dj];\n                    }\n                }\n                L = ops.size();\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        } else { // swap (move_type == 4)\n            if (L < 2) continue;\n            uniform_int_distribution<int> rand_idx(0, L - 1);\n            int idx1 = rand_idx(rng);\n            int idx2 = rand_idx(rng);\n            while (idx2 == idx1) idx2 = rand_idx(rng);\n            auto [m1, p1, q1] = ops[idx1];\n            auto [m2, p2, q2] = ops[idx2];\n            // Compute delta for swapping stamps and positions\n            set<pair<int, int>> cells;\n            for (int di = 0; di < 3; ++di) {\n                for (int dj = 0; dj < 3; ++dj) {\n                    cells.insert({p1 + di, q1 + dj});\n                    cells.insert({p2 + di, q2 + dj});\n                }\n            }\n            for (auto [i, j] : cells) {\n                ll old_val = board[i][j];\n                ll new_val = old_val;\n                // Remove contributions from old operations\n                if (i >= p1 && i < p1 + 3 && j >= q1 && j < q1 + 3) {\n                    int di = i - p1, dj = j - q1;\n                    new_val -= s[m1][di][dj];\n                }\n                if (i >= p2 && i < p2 + 3 && j >= q2 && j < q2 + 3) {\n                    int di = i - p2, dj = j - q2;\n                    new_val -= s[m2][di][dj];\n                }\n                // Add contributions from swapped operations\n                if (i >= p1 && i < p1 + 3 && j >= q1 && j < q1 + 3) {\n                    int di = i - p1, dj = j - q1;\n                    new_val += s[m2][di][dj]; // stamp m2 at position (p1,q1)\n                }\n                if (i >= p2 && i < p2 + 3 && j >= q2 && j < q2 + 3) {\n                    int di = i - p2, dj = j - q2;\n                    new_val += s[m1][di][dj]; // stamp m1 at position (p2,q2)\n                }\n                delta += mod(new_val) - mod(old_val);\n            }\n            if (delta > 0 || uniform(rng) < exp(delta / T)) {\n                // Update board: subtract old contributions and add new\n                for (int di = 0; di < 3; ++di) {\n                    for (int dj = 0; dj < 3; ++dj) {\n                        board[p1 + di][q1 + dj] -= s[m1][di][dj];\n                        board[p2 + di][q2 + dj] -= s[m2][di][dj];\n                        board[p1 + di][q1 + dj] += s[m2][di][dj];\n                        board[p2 + di][q2 + dj] += s[m1][di][dj];\n                    }\n                }\n                // Update ops\n                ops[idx1] = {m2, p1, q1};\n                ops[idx2] = {m1, p2, q2};\n                current_score += delta;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    best_board = board;\n                    best_ops = ops;\n                }\n            }\n        }\n        T *= cooling;\n    }\n\n    // Output the best found solution\n    cout << best_ops.size() << \"\\n\";\n    for (auto [m, p, q] : best_ops) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    const int N = 5;\n    int A[N][N];\n    int grid[N][N];\n    pair<int, int> pos_of[25];          // position of each container on the grid, (-1,-1) if not present\n    int next_idx[N] = {0};              // how many containers have been placed from each gate\n    bool dispatched[25] = {false};\n    int next_dispatch = 0;              // not used in decisions but kept for completeness\n\n    // crane state\n    int crane_r = 0, crane_c = 0;\n    int crane_hold = -1;                // -1 means not holding\n\n    // read input\n    int dummy; cin >> dummy;            // N is always 5, but we read it\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> A[i][j];\n\n    // initialise grid and pos_of\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            grid[i][j] = -1;\n    for (int b = 0; b < 25; ++b)\n        pos_of[b] = {-1, -1};\n\n    vector<char> actions;               // actions of the large crane\n\n    // helper lambdas\n    auto move_towards = [&](int tr, int tc) -> char {\n        if (crane_r != tr)\n            return (tr < crane_r) ? 'U' : 'D';\n        else\n            return (tc < crane_c) ? 'L' : 'R';\n    };\n\n    auto decide = [&]() -> char {\n        if (crane_hold != -1) {\n            // holding a container -> go to its dispatch gate and release\n            int tr = crane_hold / N;\n            int tc = N - 1;\n            if (crane_r == tr && crane_c == tc)\n                return 'Q';\n            return move_towards(tr, tc);\n        } else {\n            // find the best container to pick up (greedy: minimize travel to pick up + travel to dispatch)\n            int best_b = -1;\n            int best_cost = 1e9;\n            int best_r = -1, best_c = -1;\n            for (int b = 0; b < N*N; ++b) {\n                if (pos_of[b].first != -1) { // container is on the grid\n                    int r = pos_of[b].first, c = pos_of[b].second;\n                    int dist_to_container = abs(crane_r - r) + abs(crane_c - c);\n                    int dist_to_dispatch = abs(r - b/N) + abs(c - (N-1));\n                    int total = dist_to_container + dist_to_dispatch;\n                    if (total < best_cost) {\n                        best_cost = total;\n                        best_b = b;\n                        best_r = r;\n                        best_c = c;\n                    }\n                }\n            }\n            if (best_b != -1) {\n                if (crane_r == best_r && crane_c == best_c)\n                    return 'P';\n                return move_towards(best_r, best_c);\n            } else {\n                // no container on grid, wait\n                return '.';\n            }\n        }\n    };\n\n    auto apply = [&](char act) {\n        if (act == 'P') {\n            // pick up\n            crane_hold = grid[crane_r][crane_c];\n            grid[crane_r][crane_c] = -1;\n            pos_of[crane_hold] = {-1, -1};\n        } else if (act == 'Q') {\n            // release\n            int cont = crane_hold;\n            grid[crane_r][crane_c] = cont;\n            pos_of[cont] = {crane_r, crane_c};\n            crane_hold = -1;\n        } else if (act == 'U') {\n            --crane_r;\n        } else if (act == 'D') {\n            ++crane_r;\n        } else if (act == 'L') {\n            --crane_c;\n        } else if (act == 'R') {\n            ++crane_c;\n        } // '.' does nothing\n    };\n\n    // simulation loop\n    const int MAX_TURN = 10000;\n    for (int turn = 1; turn <= MAX_TURN; ++turn) {\n        // ----- step 1 : receiving -----\n        for (int i = 0; i < N; ++i) {\n            if (next_idx[i] < N && grid[i][0] == -1) {\n                // condition: no crane holding a container at this square\n                if (crane_r == i && crane_c == 0 && crane_hold != -1)\n                    continue;   // blocked\n                int cont = A[i][next_idx[i]];\n                grid[i][0] = cont;\n                pos_of[cont] = {i, 0};\n                ++next_idx[i];\n            }\n        }\n\n        // ----- step 2 : actions -----\n        char act = decide();\n        actions.push_back(act);\n        apply(act);\n\n        // ----- step 3 : dispatch -----\n        for (int i = 0; i < N; ++i) {\n            int cont = grid[i][N-1];\n            if (cont != -1) {\n                dispatched[cont] = true;\n                grid[i][N-1] = -1;\n                pos_of[cont] = {-1, -1};\n            }\n        }\n\n        // update next_dispatch (not used in decisions but kept for completeness)\n        while (next_dispatch < N*N && dispatched[next_dispatch])\n            ++next_dispatch;\n\n        // check completion\n        bool all_done = true;\n        for (int b = 0; b < N*N; ++b)\n            if (!dispatched[b]) { all_done = false; break; }\n        if (all_done)\n            break;\n    }\n\n    int T = actions.size();\n    // output for large crane (initially at (0,0))\n    string S0(actions.begin(), actions.end());\n    cout << S0 << endl;\n    // output for the four small cranes: bomb at first turn, then idle\n    for (int i = 1; i < N; ++i) {\n        string Si = 'B' + string(T-1, '.');\n        cout << Si << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<array<int, 3>> supplies, demands;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (h[i][j] > 0)\n                supplies.push_back({i, j, h[i][j]});\n            else if (h[i][j] < 0)\n                demands.push_back({i, j, -h[i][j]});\n        }\n    }\n\n    vector<string> ops;\n    int cur_r = 0, cur_c = 0, load = 0;\n\n    auto move_to = [&](int tr, int tc) {\n        while (cur_r > tr) {\n            ops.push_back(\"U\");\n            --cur_r;\n        }\n        while (cur_r < tr) {\n            ops.push_back(\"D\");\n            ++cur_r;\n        }\n        while (cur_c > tc) {\n            ops.push_back(\"L\");\n            --cur_c;\n        }\n        while (cur_c < tc) {\n            ops.push_back(\"R\");\n            ++cur_c;\n        }\n    };\n\n    auto dist = [](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n\n    while (!supplies.empty() || !demands.empty()) {\n        int total_cells = supplies.size() + demands.size();\n        if (total_cells <= 11) {\n            // Brute-force optimization for remaining cells\n            struct Cell {\n                int r, c, amount, type; // type: 0 for supply, 1 for demand\n            };\n            vector<Cell> cells;\n            for (auto& s : supplies) cells.push_back({s[0], s[1], s[2], 0});\n            for (auto& d : demands) cells.push_back({d[0], d[1], d[2], 1});\n            \n            vector<int> perm(cells.size());\n            iota(perm.begin(), perm.end(), 0);\n            double best_cost = 1e18;\n            vector<int> best_perm;\n            \n            do {\n                int temp_r = cur_r, temp_c = cur_c, temp_load = load;\n                double cost = 0;\n                bool feasible = true;\n                for (int idx : perm) {\n                    auto& cell = cells[idx];\n                    int d = dist(temp_r, temp_c, cell.r, cell.c);\n                    cost += d * (100.0 + temp_load);\n                    if (cell.type == 0) { // supply\n                        cost += cell.amount;\n                        temp_load += cell.amount;\n                    } else { // demand\n                        if (temp_load < cell.amount) {\n                            feasible = false;\n                            break;\n                        }\n                        cost += cell.amount;\n                        temp_load -= cell.amount;\n                    }\n                    temp_r = cell.r;\n                    temp_c = cell.c;\n                }\n                if (feasible && cost < best_cost) {\n                    best_cost = cost;\n                    best_perm = perm;\n                }\n            } while (next_permutation(perm.begin(), perm.end()));\n            \n            // Execute the best permutation\n            for (int idx : best_perm) {\n                auto& cell = cells[idx];\n                move_to(cell.r, cell.c);\n                if (cell.type == 0) {\n                    ops.push_back(\"+\" + to_string(cell.amount));\n                    load += cell.amount;\n                } else {\n                    ops.push_back(\"-\" + to_string(cell.amount));\n                    load -= cell.amount;\n                }\n            }\n            supplies.clear();\n            demands.clear();\n            break;\n        }\n        \n        // Greedy logic with optimized constants (12,56,22)\n        if (load == 0) {\n            int best_idx = -1;\n            double best_cost = 1e18;\n            for (int i = 0; i < (int)supplies.size(); ++i) {\n                auto& s = supplies[i];\n                int d = dist(cur_r, cur_c, s[0], s[1]);\n                int amt = s[2];\n                double cost = d * 100.0 - amt * 12.0;\n                if (best_idx == -1 || cost < best_cost) {\n                    best_idx = i;\n                    best_cost = cost;\n                }\n            }\n            auto& s = supplies[best_idx];\n            move_to(s[0], s[1]);\n            ops.push_back(\"+\" + to_string(s[2]));\n            load += s[2];\n            supplies.erase(supplies.begin() + best_idx);\n        } else {\n            vector<int> feasible;\n            for (int i = 0; i < (int)demands.size(); ++i) {\n                if (demands[i][2] <= load)\n                    feasible.push_back(i);\n            }\n            \n            if (!feasible.empty()) {\n                int best_idx = -1;\n                double best_cost = 1e18;\n                for (int idx : feasible) {\n                    auto& d = demands[idx];\n                    int distance = dist(cur_r, cur_c, d[0], d[1]);\n                    int amount = d[2];\n                    double cost = distance * (100.0 + load) - amount * 56.0;\n                    if (best_idx == -1 || cost < best_cost) {\n                        best_idx = idx;\n                        best_cost = cost;\n                    }\n                }\n                auto& d = demands[best_idx];\n                move_to(d[0], d[1]);\n                ops.push_back(\"-\" + to_string(d[2]));\n                load -= d[2];\n                demands.erase(demands.begin() + best_idx);\n            } else {\n                int best_idx = -1;\n                double best_cost = 1e18;\n                for (int i = 0; i < (int)supplies.size(); ++i) {\n                    auto& s = supplies[i];\n                    int d = dist(cur_r, cur_c, s[0], s[1]);\n                    int amt = s[2];\n                    double cost = d * (100.0 + load) - amt * 22.0;\n                    if (best_idx == -1 || cost < best_cost) {\n                        best_idx = i;\n                        best_cost = cost;\n                    }\n                }\n                auto& s = supplies[best_idx];\n                move_to(s[0], s[1]);\n                ops.push_back(\"+\" + to_string(s[2]));\n                load += s[2];\n                supplies.erase(supplies.begin() + best_idx);\n            }\n        }\n    }\n\n    for (string& op : ops)\n        cout << op << endl;\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <numeric>\n#include <cmath>\n#include <random>\n#include <chrono>\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);  // 60\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    // Random generator for simulated annealing\n    auto now = chrono::high_resolution_clock::now();\n    auto seed = chrono::duration_cast<chrono::microseconds>(now.time_since_epoch()).count();\n    mt19937 rng(seed);\n\n    // Track the best seed value seen so far\n    int best_seed_value_seen = 0;\n\n    for (int t = 0; t < T; t++) {\n        // Compute sum for each seed\n        vector<int> sum(seed_count, 0);\n        for (int i = 0; i < seed_count; i++) {\n            int s = 0;\n            for (int j = 0; j < M; j++) {\n                s += seeds[i][j];\n            }\n            sum[i] = s;\n            best_seed_value_seen = max(best_seed_value_seen, s);\n        }\n\n        // Compute potential matrix for all seeds (sum of max)\n        vector<vector<int>> pot_all(seed_count, vector<int>(seed_count, 0));\n        // Also compute sum of squared differences for variance\n        vector<vector<int>> diff_sq_all(seed_count, vector<int>(seed_count, 0));\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < seed_count; j++) {\n                if (i == j) continue;\n                int total_max = 0;\n                int total_diff_sq = 0;\n                for (int l = 0; l < M; l++) {\n                    total_max += max(seeds[i][l], seeds[j][l]);\n                    int diff = seeds[i][l] - seeds[j][l];\n                    total_diff_sq += diff * diff;\n                }\n                pot_all[i][j] = total_max;\n                diff_sq_all[i][j] = total_diff_sq;\n            }\n        }\n\n        // Find seeds with top 2 values for each criterion\n        vector<set<int>> top_per_criterion(M);\n        for (int l = 0; l < M; l++) {\n            vector<pair<int, int>> values;\n            for (int i = 0; i < seed_count; i++) {\n                values.emplace_back(seeds[i][l], i);\n            }\n            sort(values.begin(), values.end(), greater<pair<int, int>>());\n            for (int i = 0; i < 2 && i < (int)values.size(); i++) {\n                top_per_criterion[l].insert(values[i].second);\n            }\n        }\n\n        // Set of important seeds (top 2 per criterion)\n        set<int> important;\n        for (int l = 0; l < M; l++) {\n            for (int idx : top_per_criterion[l]) {\n                important.insert(idx);\n            }\n        }\n\n        // Enhanced selection: first important seeds, then by diversity score\n        vector<bool> selected(seed_count, false);\n        vector<int> selected_orig;\n        for (int idx : important) {\n            if (selected_orig.size() < 36) {\n                selected[idx] = true;\n                selected_orig.push_back(idx);\n            }\n        }\n\n        // Compute diversity score for remaining seeds\n        vector<double> diversity_score(seed_count, 0.0);\n        for (int i = 0; i < seed_count; i++) {\n            if (selected[i]) continue;\n            // Calculate minimum Euclidean distance to already selected seeds\n            double min_dist = 1e9;\n            for (int j : selected_orig) {\n                double dist = 0.0;\n                for (int l = 0; l < M; l++) {\n                    double diff = seeds[i][l] - seeds[j][l];\n                    dist += diff * diff;\n                }\n                min_dist = min(min_dist, sqrt(dist));\n            }\n            // Combine sum and diversity (give more weight to sum)\n            diversity_score[i] = sum[i] * 0.8 + min_dist * 0.2;\n        }\n\n        // Greedy addition of remaining seeds\n        while (selected_orig.size() < 36) {\n            int best_idx = -1;\n            double best_score = -1.0;\n            for (int i = 0; i < seed_count; i++) {\n                if (selected[i]) continue;\n                if (diversity_score[i] > best_score) {\n                    best_score = diversity_score[i];\n                    best_idx = i;\n                }\n            }\n            if (best_idx == -1) break;\n            selected[best_idx] = true;\n            selected_orig.push_back(best_idx);\n            \n            // Update diversity scores for remaining seeds\n            for (int i = 0; i < seed_count; i++) {\n                if (selected[i]) continue;\n                double min_dist = 1e9;\n                for (int j : selected_orig) {\n                    double dist = 0.0;\n                    for (int l = 0; l < M; l++) {\n                        double diff = seeds[i][l] - seeds[j][l];\n                        dist += diff * diff;\n                    }\n                    min_dist = min(min_dist, sqrt(dist));\n                }\n                diversity_score[i] = sum[i] * 0.8 + min_dist * 0.2;\n            }\n        }\n\n        int K = selected_orig.size();  // should be 36\n        // Compute potential and diff_sq matrices for selected seeds\n        vector<vector<int>> pot(K, vector<int>(K, 0));\n        vector<vector<int>> diff_sq(K, vector<int>(K, 0));\n        for (int i = 0; i < K; i++) {\n            for (int j = 0; j < K; j++) {\n                if (i == j) continue;\n                pot[i][j] = pot_all[selected_orig[i]][selected_orig[j]];\n                diff_sq[i][j] = diff_sq_all[selected_orig[i]][selected_orig[j]];\n            }\n        }\n\n        // Compute sums for selected seeds\n        vector<int> selected_sum(K);\n        for (int i = 0; i < K; i++) {\n            selected_sum[i] = sum[selected_orig[i]];\n        }\n\n        // Compute composite score for each selected seed\n        vector<double> composite_score(K, 0.0);\n        for (int i = 0; i < K; i++) {\n            double avg_pot = 0.0;\n            for (int j = 0; j < K; j++) {\n                if (i == j) continue;\n                avg_pot += pot[i][j];\n            }\n            avg_pot /= (K - 1);\n            composite_score[i] = selected_sum[i] * 0.7 + avg_pot * 0.3;\n        }\n\n        // Order to place seeds: descending by composite score\n        vector<int> order(K);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int a, int b) { return composite_score[a] > composite_score[b]; });\n\n        // Grid assignment: grid[i][j] = index in selected_orig (0..K-1)\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n\n        // Greedy placement with position weighting\n        vector<vector<int>> position_weight(N, vector<int>(N, 0));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int weight = 4;  // center\n                if (i == 0 || i == N-1) weight--;\n                if (j == 0 || j == N-1) weight--;\n                position_weight[i][j] = weight;\n            }\n        }\n\n        // Place seeds\n        for (int idx : order) {\n            double best_score = -1.0;\n            int best_i = -1, best_j = -1;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) continue;\n                    double score = 0.0;\n                    // Check up, down, left, right\n                    if (i > 0 && grid[i-1][j] != -1) {\n                        score += pot[idx][grid[i-1][j]];\n                    }\n                    if (i < N-1 && grid[i+1][j] != -1) {\n                        score += pot[idx][grid[i+1][j]];\n                    }\n                    if (j > 0 && grid[i][j-1] != -1) {\n                        score += pot[idx][grid[i][j-1]];\n                    }\n                    if (j < N-1 && grid[i][j+1] != -1) {\n                        score += pot[idx][grid[i][j+1]];\n                    }\n                    // Weight by position importance\n                    score *= position_weight[i][j];\n                    if (score > best_score) {\n                        best_score = score;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n            if (best_i != -1 && best_j != -1) {\n                grid[best_i][best_j] = idx;\n            }\n        }\n\n        // Fill any remaining positions (shouldn't happen, but just in case)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == -1) {\n                    for (int idx = 0; idx < K; idx++) {\n                        bool used = false;\n                        for (int ii = 0; ii < N; ii++) {\n                            for (int jj = 0; jj < N; jj++) {\n                                if (grid[ii][jj] == idx) {\n                                    used = true;\n                                    break;\n                                }\n                            }\n                            if (used) break;\n                        }\n                        if (!used) {\n                            grid[i][j] = idx;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n\n        // Helper function to compute optimistic bound for an edge\n        auto compute_bound = [&](int i, int j) {\n            double mean = (selected_sum[i] + selected_sum[j]) / 2.0;\n            double variance = diff_sq[i][j] / 4.0;\n            double std = sqrt(variance);\n            \n            // Adaptive confidence: more aggressive if we haven't seen high values\n            double base_confidence = 2.5 - (t * 0.15);  // from 2.5 to 1.0 over 10 turns\n            // Adjust based on how close we are to theoretical maximum\n            double max_possible = 0;\n            for (int l = 0; l < M; l++) {\n                max_possible += max(seeds[selected_orig[i]][l], seeds[selected_orig[j]][l]);\n            }\n            double ratio = best_seed_value_seen / max_possible;\n            double confidence = base_confidence * (1.0 + (1.0 - ratio) * 0.5);\n            \n            return mean + confidence * std;\n        };\n\n        // Helper function to compute score based on bounds\n        auto compute_score = [&](const vector<vector<int>>& g) {\n            double max_bound = 0;\n            double sum_bounds = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    int s1 = g[i][j];\n                    if (i+1 < N) {\n                        int s2 = g[i+1][j];\n                        double bound = compute_bound(s1, s2);\n                        max_bound = max(max_bound, bound);\n                        sum_bounds += bound;\n                    }\n                    if (j+1 < N) {\n                        int s2 = g[i][j+1];\n                        double bound = compute_bound(s1, s2);\n                        max_bound = max(max_bound, bound);\n                        sum_bounds += bound;\n                    }\n                }\n            }\n            // Very high weight on max_bound to focus on creating at least one excellent edge\n            return max_bound * 5000 + sum_bounds;\n        };\n\n        // Simulated Annealing with adaptive parameters\n        double temperature = 1000.0;\n        double cooling_rate = 0.99975;\n        int iterations = 90000;\n        double current_score = compute_score(grid);\n\n        uniform_int_distribution<int> dist_pos(0, N-1);\n        uniform_real_distribution<double> dist_real(0.0, 1.0);\n\n        for (int iter = 0; iter < iterations; iter++) {\n            // Randomly select two distinct positions\n            int i1 = dist_pos(rng), j1 = dist_pos(rng);\n            int i2 = dist_pos(rng), j2 = dist_pos(rng);\n            while (i1 == i2 && j1 == j2) {\n                i2 = dist_pos(rng);\n                j2 = dist_pos(rng);\n            }\n\n            // Swap\n            swap(grid[i1][j1], grid[i2][j2]);\n            double new_score = compute_score(grid);\n            double delta = new_score - current_score;\n\n            if (delta > 0 || dist_real(rng) < exp(delta / temperature)) {\n                current_score = new_score;\n            } else {\n                // Swap back\n                swap(grid[i1][j1], grid[i2][j2]);\n            }\n\n            temperature *= cooling_rate;\n        }\n\n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << selected_orig[grid[i][j]];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << endl;\n        }\n        cout.flush();\n\n        // Read next generation if not last turn\n        if (t < T - 1) {\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\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n#include <cstdlib>\n#include <cassert>\n#include <climits>\n\nusing namespace std;\n\n// Directions: 0:right, 1:down, 2:left, 3:up\nconst int dr[4] = {0, 1, 0, -1};\nconst int dc[4] = {1, 0, -1, 0};\n\nint N, M, V;\nint V_prime;          // number of vertices used\nint K;                // number of leaves = V_prime-1\nvector<int> len;      // length of each leaf (1-indexed, len[i] for leaf i)\nint root_r, root_c;   // current root position\nvector<int> dir;      // direction of each leaf (1-indexed)\nvector<bool> holding; // whether leaf i holds a takoyaki\nbool src_rem[30][30]; // remaining source squares\nbool tgt_rem[30][30]; // remaining target squares\nint src_cnt, tgt_cnt; // counts\n\n// Helper functions\ninline bool in_grid(int r, int c) {\n    return 0 <= r && r < N && 0 <= c && c < N;\n}\n\n// Output one turn\nvoid output_turn(char move, const vector<char>& rot, const vector<char>& act) {\n    string S(2 * V_prime, '.');\n    S[0] = move;\n    for (int i = 1; i <= K; ++i) {\n        S[i] = rot[i];\n    }\n    for (int i = 0; i <= K; ++i) {\n        if (act[i] == 'P') {\n            S[V_prime + i] = 'P';\n        }\n    }\n    cout << S << '\\n';\n}\n\n// Move root to (tr,tc) while rotating leaf `leaf` to direction `des_dir`.\n// Performs one step per turn, rotating the leaf as much as possible.\nvoid move_root_to(int tr, int tc, int leaf, int des_dir) {\n    while (root_r != tr || root_c != tc) {\n        // Determine movement direction\n        char move_char;\n        if (tr > root_r) move_char = 'D';\n        else if (tr < root_r) move_char = 'U';\n        else if (tc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Rotation for the leaf we are controlling\n        char rot_leaf = '.';\n        if (leaf != -1 && dir[leaf] != des_dir) {\n            int diff = (des_dir - dir[leaf] + 4) % 4;\n            if (diff == 1) {\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            } else if (diff == 3) {\n                rot_leaf = 'L';\n                dir[leaf] = (dir[leaf] + 3) % 4;\n            } else { // diff == 2, rotate arbitrarily (choose R)\n                rot_leaf = 'R';\n                dir[leaf] = (dir[leaf] + 1) % 4;\n            }\n        }\n\n        vector<char> rot(K+1, '.');\n        if (leaf != -1) rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.'); // no pick/drop during movement\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        if (move_char == 'U') root_r--;\n        else if (move_char == 'D') root_r++;\n        else if (move_char == 'L') root_c--;\n        else if (move_char == 'R') root_c++;\n    }\n\n    // After reaching the target, finish rotation if needed\n    while (leaf != -1 && dir[leaf] != des_dir) {\n        char rot_leaf = '.';\n        int diff = (des_dir - dir[leaf] + 4) % 4;\n        if (diff == 1) {\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        } else if (diff == 3) {\n            rot_leaf = 'L';\n            dir[leaf] = (dir[leaf] + 3) % 4;\n        } else { // diff == 2\n            rot_leaf = 'R';\n            dir[leaf] = (dir[leaf] + 1) % 4;\n        }\n        vector<char> rot(K+1, '.');\n        rot[leaf] = rot_leaf;\n        vector<char> act(K+1, '.');\n        output_turn('.', rot, act);\n    }\n}\n\n// Output a turn with only a pick/drop for a given leaf (no movement, no other rotations)\nvoid output_action(int leaf, char action) {\n    vector<char> rot(K+1, '.');\n    vector<char> act(K+1, '.');\n    act[leaf] = action;\n    output_turn('.', rot, act);\n}\n\n// Find any remaining target square that leaf i can reach, together with a suitable direction.\ntuple<int,int,int> find_target_for_leaf(int i) {\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (tgt_rem[r][c]) {\n                for (int d = 0; d < 4; ++d) {\n                    int nr = r - dr[d] * len[i];\n                    int nc = c - dc[d] * len[i];\n                    if (in_grid(nr, nc)) {\n                        return make_tuple(r, c, d);\n                    }\n                }\n            }\n        }\n    }\n    // should never happen\n    return make_tuple(-1, -1, -1);\n}\n\n// Find any remaining source square\npair<int,int> find_source() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (src_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Find any remaining target square\npair<int,int> find_target() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            if (tgt_rem[r][c])\n                return {r, c};\n    return {-1, -1};\n}\n\n// Try to stay in place to rotate a leaf 180\u00b0 and pick/drop if possible.\n// Returns true if we performed stay turns.\nbool try_stay_for_rotation() {\n    // First try drops\n    for (int i = 1; i <= K; ++i) {\n        if (!holding[i]) continue;\n        for (int d = 0; d < 4; ++d) {\n            int pr = root_r + dr[d] * len[i];\n            int pc = root_c + dc[d] * len[i];\n            if (!in_grid(pr, pc) || !tgt_rem[pr][pc]) continue;\n            int delta = (d - dir[i] + 4) % 4;\n            if (delta == 2) { // 180\u00b0 rotation needed\n                // Rotate twice (choose R,R) and drop on the second turn.\n                // First turn: rotate 90\u00b0 (R)\n                vector<char> rot1(K+1, '.');\n                rot1[i] = 'R';\n                vector<char> act1(K+1, '.');\n                output_turn('.', rot1, act1);\n                dir[i] = (dir[i] + 1) % 4;\n                \n                // Second turn: rotate another 90\u00b0 (R) and drop\n                vector<char> rot2(K+1, '.');\n                rot2[i] = 'R';\n                vector<char> act2(K+1, '.');\n                act2[i] = 'P';\n                output_turn('.', rot2, act2);\n                dir[i] = (dir[i] + 1) % 4; // now equals d\n                holding[i] = false;\n                tgt_rem[pr][pc] = false;\n                --tgt_cnt;\n                return true;\n            }\n        }\n    }\n    \n    // Then try picks\n    for (int i = 1; i <= K; ++i) {\n        if (holding[i]) continue;\n        for (int d = 0; d < 4; ++d) {\n            int pr = root_r + dr[d] * len[i];\n            int pc = root_c + dc[d] * len[i];\n            if (!in_grid(pr, pc) || !src_rem[pr][pc]) continue;\n            int delta = (d - dir[i] + 4) % 4;\n            if (delta == 2) { // 180\u00b0 rotation needed\n                // Rotate twice and pick on the second turn.\n                // First turn: rotate 90\u00b0 (R)\n                vector<char> rot1(K+1, '.');\n                rot1[i] = 'R';\n                vector<char> act1(K+1, '.');\n                output_turn('.', rot1, act1);\n                dir[i] = (dir[i] + 1) % 4;\n                \n                // Second turn: rotate another 90\u00b0 (R) and pick\n                vector<char> rot2(K+1, '.');\n                rot2[i] = 'R';\n                vector<char> act2(K+1, '.');\n                act2[i] = 'P';\n                output_turn('.', rot2, act2);\n                dir[i] = (dir[i] + 1) % 4; // now equals d\n                holding[i] = true;\n                src_rem[pr][pc] = false;\n                --src_cnt;\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    // Input\n    cin >> N >> M >> V;\n    vector<string> s_grid(N), t_grid(N);\n    for (int i = 0; i < N; ++i) cin >> s_grid[i];\n    for (int i = 0; i < N; ++i) cin >> t_grid[i];\n\n    // Determine sources and targets (remove overlaps)\n    src_cnt = tgt_cnt = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            bool s = (s_grid[i][j] == '1');\n            bool t = (t_grid[i][j] == '1');\n            if (s && t) {\n                // already in place, ignore\n                src_rem[i][j] = false;\n                tgt_rem[i][j] = false;\n            } else if (s) {\n                src_rem[i][j] = true;\n                ++src_cnt;\n                tgt_rem[i][j] = false;\n            } else if (t) {\n                tgt_rem[i][j] = true;\n                ++tgt_cnt;\n                src_rem[i][j] = false;\n            } else {\n                src_rem[i][j] = tgt_rem[i][j] = false;\n            }\n        }\n    }\n\n    // Design the arm: star with root 0 and leaves 1..K, lengths = 1,2,...,K\n    V_prime = V;                // use all vertices\n    K = V_prime - 1;\n    len.resize(K+1);\n    for (int i = 1; i <= K; ++i) len[i] = i;   // guaranteed i <= N-1 because N>=15, K<=14\n\n    // Initial root position (choose (0,0))\n    root_r = 0; root_c = 0;\n\n    // Output arm design\n    cout << V_prime << '\\n';\n    for (int i = 1; i <= K; ++i) {\n        cout << \"0 \" << len[i] << '\\n';\n    }\n    cout << root_r << ' ' << root_c << '\\n';\n\n    // Initialize state\n    dir.assign(K+1, 0);          // all initially point right\n    holding.assign(K+1, false);\n\n    // Snake traversal: generate order of cells\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) cells.emplace_back(i, j);\n        } else {\n            for (int j = N-1; j >= 0; --j) cells.emplace_back(i, j);\n        }\n    }\n\n    // Perform moves along the snake\n    size_t idx = 0;\n    while (idx < cells.size() - 1) {\n        int nr = cells[idx+1].first;\n        int nc = cells[idx+1].second;\n\n        // Determine movement character\n        char move_char;\n        if (nr > root_r) move_char = 'D';\n        else if (nr < root_r) move_char = 'U';\n        else if (nc > root_c) move_char = 'R';\n        else move_char = 'L';\n\n        // Greedy assignment of picks/drops at the new position\n        vector<bool> used(K+1, false);\n        vector<int> desired_dir(K+1, -1);\n        vector<char> action(K+1, '.');\n\n        // Drops first\n        for (int i = 1; i <= K; ++i) {\n            if (holding[i] && !used[i]) {\n                // Try the three reachable directions (current, left, right)\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && tgt_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = false;\n                        tgt_rem[pr][pc] = false;\n                        --tgt_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Picks\n        for (int i = 1; i <= K; ++i) {\n            if (!holding[i] && !used[i]) {\n                for (int d : {dir[i], (dir[i]+3)%4, (dir[i]+1)%4}) {\n                    int pr = nr + dr[d] * len[i];\n                    int pc = nc + dc[d] * len[i];\n                    if (in_grid(pr, pc) && src_rem[pr][pc]) {\n                        used[i] = true;\n                        desired_dir[i] = d;\n                        action[i] = 'P';\n                        holding[i] = true;\n                        src_rem[pr][pc] = false;\n                        --src_cnt;\n                        break;\n                    }\n                }\n            }\n        }\n\n        // Build rotation commands\n        vector<char> rot(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (desired_dir[i] != -1) {\n                int delta = (desired_dir[i] - dir[i] + 4) % 4;\n                if (delta == 0) rot[i] = '.';\n                else if (delta == 1) rot[i] = 'R';\n                else if (delta == 3) rot[i] = 'L';\n                // delta == 2 cannot happen because we only used reachable directions\n                dir[i] = desired_dir[i];\n            }\n        }\n\n        // Build action vector (root action always '.')\n        vector<char> act(K+1, '.');\n        for (int i = 1; i <= K; ++i) {\n            if (action[i] == 'P') act[i] = 'P';\n        }\n\n        // Output the turn (move to next cell)\n        output_turn(move_char, rot, act);\n\n        // Update root position\n        root_r = nr;\n        root_c = nc;\n        ++idx;\n\n        // After moving, stay for rotations if beneficial (multiple stays allowed)\n        int stays = 0;\n        while (stays < K && try_stay_for_rotation()) {\n            stays++;\n        }\n    }\n\n    // If all takoyaki are already at targets, we are done\n    if (src_cnt == 0 && tgt_cnt == 0) {\n        return 0;\n    }\n\n    // ----- Cleanup phase -----\n    // Step 1: Drop any takoyaki still held by leaves\n    for (int i = 1; i <= K; ++i) {\n        while (holding[i]) {\n            auto [tr, tc, d] = find_target_for_leaf(i);\n            int nr = tr - dr[d] * len[i];\n            int nc = tc - dc[d] * len[i];\n            move_root_to(nr, nc, i, d);\n            output_action(i, 'P');\n            holding[i] = false;\n            tgt_rem[tr][tc] = false;\n            --tgt_cnt;\n        }\n    }\n\n    // Step 2: Move remaining sources to targets using optimal leaf selection\n    while (src_cnt > 0) {\n        // Find the source that can be picked with minimal travel distance\n        int best_dist = INT_MAX;\n        int best_sr = -1, best_sc = -1;\n        int best_leaf = -1, best_dir = -1;\n        int best_nr = -1, best_nc = -1;\n        \n        for (int sr = 0; sr < N; ++sr) {\n            for (int sc = 0; sc < N; ++sc) {\n                if (!src_rem[sr][sc]) continue;\n                for (int i = 1; i <= K; ++i) {\n                    if (holding[i]) continue; // leaf already holding\n                    for (int d = 0; d < 4; ++d) {\n                        int nr = sr - dr[d] * len[i];\n                        int nc = sc - dc[d] * len[i];\n                        if (!in_grid(nr, nc)) continue;\n                        int dist = abs(nr - root_r) + abs(nc - root_c);\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best_sr = sr; best_sc = sc;\n                            best_leaf = i; best_dir = d;\n                            best_nr = nr; best_nc = nc;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Should always find a pickable source\n        if (best_dist == INT_MAX) break;\n        \n        // Move to pick position and pick\n        move_root_to(best_nr, best_nc, best_leaf, best_dir);\n        output_action(best_leaf, 'P');\n        holding[best_leaf] = true;\n        src_rem[best_sr][best_sc] = false;\n        --src_cnt;\n        \n        // Now find the best target for this leaf\n        int best_drop_dist = INT_MAX;\n        int best_tr = -1, best_tc = -1;\n        int best_d2 = -1;\n        int best_nr2 = -1, best_nc2 = -1;\n        \n        for (int tr = 0; tr < N; ++tr) {\n            for (int tc = 0; tc < N; ++tc) {\n                if (!tgt_rem[tr][tc]) continue;\n                for (int d2 = 0; d2 < 4; ++d2) {\n                    int nr2 = tr - dr[d2] * len[best_leaf];\n                    int nc2 = tc - dc[d2] * len[best_leaf];\n                    if (!in_grid(nr2, nc2)) continue;\n                    int dist2 = abs(nr2 - root_r) + abs(nc2 - root_c);\n                    if (dist2 < best_drop_dist) {\n                        best_drop_dist = dist2;\n                        best_tr = tr; best_tc = tc;\n                        best_d2 = d2;\n                        best_nr2 = nr2; best_nc2 = nc2;\n                    }\n                }\n            }\n        }\n        \n        if (best_drop_dist == INT_MAX) {\n            // Should not happen, but just in case: find any target\n            auto [tr, tc, d2] = find_target_for_leaf(best_leaf);\n            best_tr = tr; best_tc = tc; best_d2 = d2;\n            best_nr2 = tr - dr[d2] * len[best_leaf];\n            best_nc2 = tc - dc[d2] * len[best_leaf];\n        }\n        \n        // Move to drop position and drop\n        move_root_to(best_nr2, best_nc2, best_leaf, best_d2);\n        output_action(best_leaf, 'P');\n        holding[best_leaf] = false;\n        tgt_rem[best_tr][best_tc] = false;\n        --tgt_cnt;\n    }\n\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n};\n\nint compute_score(int x1, int x2, int y1, int y2, \n                  const vector<Point>& mack, const vector<Point>& sard) {\n    int a = 0, b = 0;\n    for (const auto& p : mack) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) a++;\n    }\n    for (const auto& p : sard) {\n        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) b++;\n    }\n    return max(0, a - b + 1);\n}\n\n// Try to create an L-shaped polygon\ntuple<int, int, int, int, int, bool> try_l_shape(int x1, int x2, int y1, int y2,\n                                                 int score1,\n                                                 const vector<Point>& mack,\n                                                 const vector<Point>& sard,\n                                                 const vector<int>& xs,\n                                                 const vector<int>& ys) {\n    if (score1 <= 0) return {x1, x2, y1, y2, score1, false};\n    \n    // Adjust attempts based on current score\n    int attempts_limit = 30;\n    if (score1 < 500) attempts_limit = 80;\n    else if (score1 < 1000) attempts_limit = 50;\n    \n    // Try adding a vertical extension on the right side\n    int attempts = 0;\n    for (int ext_x : xs) {\n        if (ext_x > x2 && ext_x <= min(MAX_COORD, x2 + 10000)) {\n            int new_score = compute_score(x1, ext_x, y1, y2, mack, sard);\n            if (new_score > score1) {\n                return {x1, ext_x, y1, y2, new_score, true};\n            }\n            if (++attempts >= attempts_limit) break;\n        }\n    }\n    \n    // Try adding a horizontal extension on the top side\n    attempts = 0;\n    for (int ext_y : ys) {\n        if (ext_y > y2 && ext_y <= min(MAX_COORD, y2 + 10000)) {\n            int new_score = compute_score(x1, x2, y1, ext_y, mack, sard);\n            if (new_score > score1) {\n                return {x1, x2, y1, ext_y, new_score, true};\n            }\n            if (++attempts >= attempts_limit) break;\n        }\n    }\n    \n    // Try adding a vertical extension on the left side\n    attempts = 0;\n    for (int ext_x : xs) {\n        if (ext_x < x1 && ext_x >= max(0, x1 - 10000)) {\n            int new_score = compute_score(ext_x, x2, y1, y2, mack, sard);\n            if (new_score > score1) {\n                return {ext_x, x2, y1, y2, new_score, true};\n            }\n            if (++attempts >= attempts_limit) break;\n        }\n    }\n    \n    // Try adding a horizontal extension on the bottom side\n    attempts = 0;\n    for (int ext_y : ys) {\n        if (ext_y < y1 && ext_y >= max(0, y1 - 10000)) {\n            int new_score = compute_score(x1, x2, ext_y, y2, mack, sard);\n            if (new_score > score1) {\n                return {x1, x2, ext_y, y2, new_score, true};\n            }\n            if (++attempts >= attempts_limit) break;\n        }\n    }\n    \n    return {x1, x2, y1, y2, score1, false};\n}\n\n// Try to create an indented polygon to avoid sardines\ntuple<int, int, int, int, int, bool> try_indent_polygon(int x1, int x2, int y1, int y2,\n                                                        int score1,\n                                                        const vector<Point>& mack,\n                                                        const vector<Point>& sard,\n                                                        const vector<int>& xs,\n                                                        const vector<int>& ys) {\n    if (score1 <= 5) return {x1, x2, y1, y2, score1, false};\n    \n    // Adjust threshold and attempts based on score\n    double threshold = 1.15;\n    int attempts_limit = 25;\n    if (score1 < 500) {\n        threshold = 1.05;\n        attempts_limit = 60;\n    } else if (score1 < 1000) {\n        threshold = 1.1;\n        attempts_limit = 40;\n    }\n    \n    // Try vertical indentations\n    int attempts = 0;\n    for (int indent_x : xs) {\n        if (indent_x > x1 && indent_x < x2) {\n            // Try right side indentation\n            int new_score_right = compute_score(x1, indent_x, y1, y2, mack, sard);\n            if (new_score_right > score1 * threshold) {\n                return {x1, indent_x, y1, y2, new_score_right, true};\n            }\n            \n            // Try left side indentation\n            int new_score_left = compute_score(indent_x, x2, y1, y2, mack, sard);\n            if (new_score_left > score1 * threshold) {\n                return {indent_x, x2, y1, y2, new_score_left, true};\n            }\n            \n            if (++attempts >= attempts_limit) break;\n        }\n    }\n    \n    // Try horizontal indentations\n    attempts = 0;\n    for (int indent_y : ys) {\n        if (indent_y > y1 && indent_y < y2) {\n            // Try top side indentation\n            int new_score_top = compute_score(x1, x2, y1, indent_y, mack, sard);\n            if (new_score_top > score1 * threshold) {\n                return {x1, x2, y1, indent_y, new_score_top, true};\n            }\n            \n            // Try bottom side indentation\n            int new_score_bottom = compute_score(x1, x2, indent_y, y2, mack, sard);\n            if (new_score_bottom > score1 * threshold) {\n                return {x1, x2, indent_y, y2, new_score_bottom, true};\n            }\n            \n            if (++attempts >= attempts_limit) break;\n        }\n    }\n    \n    return {x1, x2, y1, y2, score1, false};\n}\n\n// Enhanced local optimization with more aggressive search for low scores\nvoid enhanced_local_optimize(int& x1, int& x2, int& y1, int& y2,\n                             const vector<Point>& mack, const vector<Point>& sard,\n                             const vector<int>& xs, const vector<int>& ys) {\n    int current_score = compute_score(x1, x2, y1, y2, mack, sard);\n    \n    // First, do expansion\n    bool improved = true;\n    int iterations = 0;\n    while (improved && iterations < 12) {\n        improved = false;\n        iterations++;\n        \n        // Try left expansion\n        auto it_left = lower_bound(xs.begin(), xs.end(), x1);\n        if (it_left != xs.begin()) {\n            int new_x1 = *(--it_left);\n            int new_score = compute_score(new_x1, x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = new_x1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try right expansion\n        auto it_right = upper_bound(xs.begin(), xs.end(), x2);\n        if (it_right != xs.end()) {\n            int new_x2 = *it_right;\n            int new_score = compute_score(x1, new_x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x2 = new_x2;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try bottom expansion\n        auto it_bottom = lower_bound(ys.begin(), ys.end(), y1);\n        if (it_bottom != ys.begin()) {\n            int new_y1 = *(--it_bottom);\n            int new_score = compute_score(x1, x2, new_y1, y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = new_y1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try top expansion\n        auto it_top = upper_bound(ys.begin(), ys.end(), y2);\n        if (it_top != ys.end()) {\n            int new_y2 = *it_top;\n            int new_score = compute_score(x1, x2, y1, new_y2, mack, sard);\n            if (new_score > current_score) {\n                y2 = new_y2;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n    }\n    \n    // Then try contraction to exclude sardines\n    improved = true;\n    iterations = 0;\n    while (improved && iterations < 6) {\n        improved = false;\n        iterations++;\n        \n        // Try left contraction\n        auto it_left = upper_bound(xs.begin(), xs.end(), x1);\n        if (it_left != xs.end() && *it_left < x2) {\n            int new_x1 = *it_left;\n            int new_score = compute_score(new_x1, x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = new_x1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try right contraction\n        auto it_right = lower_bound(xs.begin(), xs.end(), x2);\n        if (it_right != xs.begin()) {\n            int new_x2 = *(--it_right);\n            if (new_x2 > x1) {\n                int new_score = compute_score(x1, new_x2, y1, y2, mack, sard);\n                if (new_score > current_score) {\n                    x2 = new_x2;\n                    current_score = new_score;\n                    improved = true;\n                    continue;\n                }\n            }\n        }\n        \n        // Try bottom contraction\n        auto it_bottom = upper_bound(ys.begin(), ys.end(), y1);\n        if (it_bottom != ys.end() && *it_bottom < y2) {\n            int new_y1 = *it_bottom;\n            int new_score = compute_score(x1, x2, new_y1, y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = new_y1;\n                current_score = new_score;\n                improved = true;\n                continue;\n            }\n        }\n        \n        // Try top contraction\n        auto it_top = lower_bound(ys.begin(), ys.end(), y2);\n        if (it_top != ys.begin()) {\n            int new_y2 = *(--it_top);\n            if (new_y2 > y1) {\n                int new_score = compute_score(x1, x2, y1, new_y2, mack, sard);\n                if (new_score > current_score) {\n                    y2 = new_y2;\n                    current_score = new_score;\n                    improved = true;\n                    continue;\n                }\n            }\n        }\n    }\n    \n    // Final aggressive search based on score\n    int search_range = 10;\n    if (current_score < 500) search_range = 50;\n    else if (current_score < 1000) search_range = 30;\n    else if (current_score < 1200) search_range = 20;  // Extra for borderline cases\n    \n    // Try moving left boundary to nearby points\n    int left_idx = lower_bound(xs.begin(), xs.end(), x1) - xs.begin();\n    for (int i = max(0, left_idx - search_range); i <= min((int)xs.size() - 1, left_idx + search_range); i++) {\n        if (xs[i] < x2) {\n            int new_score = compute_score(xs[i], x2, y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x1 = xs[i];\n                current_score = new_score;\n            }\n        }\n    }\n    \n    // Try moving right boundary to nearby points\n    int right_idx = lower_bound(xs.begin(), xs.end(), x2) - xs.begin();\n    for (int i = max(0, right_idx - search_range); i <= min((int)xs.size() - 1, right_idx + search_range); i++) {\n        if (xs[i] > x1) {\n            int new_score = compute_score(x1, xs[i], y1, y2, mack, sard);\n            if (new_score > current_score) {\n                x2 = xs[i];\n                current_score = new_score;\n            }\n        }\n    }\n    \n    // Try moving bottom boundary to nearby points\n    int bottom_idx = lower_bound(ys.begin(), ys.end(), y1) - ys.begin();\n    for (int i = max(0, bottom_idx - search_range); i <= min((int)ys.size() - 1, bottom_idx + search_range); i++) {\n        if (ys[i] < y2) {\n            int new_score = compute_score(x1, x2, ys[i], y2, mack, sard);\n            if (new_score > current_score) {\n                y1 = ys[i];\n                current_score = new_score;\n            }\n        }\n    }\n    \n    // Try moving top boundary to nearby points\n    int top_idx = lower_bound(ys.begin(), ys.end(), y2) - ys.begin();\n    for (int i = max(0, top_idx - search_range); i <= min((int)ys.size() - 1, top_idx + search_range); i++) {\n        if (ys[i] > y1) {\n            int new_score = compute_score(x1, x2, y1, ys[i], mack, sard);\n            if (new_score > current_score) {\n                y2 = ys[i];\n                current_score = new_score;\n            }\n        }\n    }\n}\n\ntuple<int, int, int, int, int> process_cell_size(int cell_size,\n                                                 const vector<Point>& mack,\n                                                 const vector<Point>& sard,\n                                                 const vector<int>& xs,\n                                                 const vector<int>& ys,\n                                                 vector<tuple<int, int, int, int, int>>& all_candidates) {\n    int num_cells_x = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    int num_cells_y = (MAX_COORD + cell_size - 1) / cell_size + 1;\n    vector<vector<int>> mack_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<vector<int>> sard_count(num_cells_x, vector<int>(num_cells_y, 0));\n    vector<pair<int, int>> mack_cells(mack.size());\n\n    for (size_t i = 0; i < mack.size(); i++) {\n        int cx = mack[i].x / cell_size;\n        int cy = mack[i].y / cell_size;\n        mack_count[cx][cy]++;\n        mack_cells[i] = {cx, cy};\n    }\n    for (size_t i = 0; i < sard.size(); i++) {\n        int cx = sard[i].x / cell_size;\n        int cy = sard[i].y / cell_size;\n        sard_count[cx][cy]++;\n    }\n\n    vector<vector<int>> weight(num_cells_x, vector<int>(num_cells_y, 0));\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            weight[i][j] = mack_count[i][j] - sard_count[i][j];\n        }\n    }\n\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 0, best_y1 = 0, best_y2 = 0;\n\n    // Cell rectangles\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0) {\n                int x1 = i * cell_size;\n                int x2 = min(MAX_COORD, (i + 1) * cell_size);\n                int y1 = j * cell_size;\n                int y2 = min(MAX_COORD, (j + 1) * cell_size);\n                if (x1 < x2 && y1 < y2) {\n                    int a = 0, b = 0;\n                    for (const auto& p : mack) {\n                        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) a++;\n                    }\n                    for (const auto& p : sard) {\n                        if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) b++;\n                    }\n                    int score = max(0, a - b + 1);\n                    all_candidates.push_back({x1, x2, y1, y2, score});\n                    if (score > best_score) {\n                        best_score = score;\n                        best_x1 = x1;\n                        best_x2 = x2;\n                        best_y1 = y1;\n                        best_y2 = y2;\n                    }\n                }\n            }\n        }\n    }\n\n    // Connected components using BFS\n    vector<vector<bool>> visited(num_cells_x, vector<bool>(num_cells_y, false));\n    const int dx[4] = {1, -1, 0, 0};\n    const int dy[4] = {0, 0, 1, -1};\n\n    for (int i = 0; i < num_cells_x; i++) {\n        for (int j = 0; j < num_cells_y; j++) {\n            if (weight[i][j] > 0 && !visited[i][j]) {\n                vector<pair<int, int>> comp;\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();\n                    q.pop();\n                    comp.push_back({x, y});\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 < num_cells_x && ny >= 0 && ny < num_cells_y &&\n                            weight[nx][ny] > 0 && !visited[nx][ny]) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n\n                int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n                for (size_t k = 0; k < mack.size(); k++) {\n                    int cx = mack_cells[k].first, cy = mack_cells[k].second;\n                    for (const auto& cell : comp) {\n                        if (cell.first == cx && cell.second == cy) {\n                            min_x = min(min_x, mack[k].x);\n                            max_x = max(max_x, mack[k].x);\n                            min_y = min(min_y, mack[k].y);\n                            max_y = max(max_y, mack[k].y);\n                            break;\n                        }\n                    }\n                }\n\n                if (min_x == max_x) {\n                    min_x = max(0, min_x - 1);\n                    max_x = min(MAX_COORD, max_x + 1);\n                }\n                if (min_y == max_y) {\n                    min_y = max(0, min_y - 1);\n                    max_y = min(MAX_COORD, max_y + 1);\n                }\n\n                if (min_x < max_x && min_y < max_y) {\n                    int a = 0, b = 0;\n                    for (const auto& p : mack) {\n                        if (min_x <= p.x && p.x <= max_x && min_y <= p.y && p.y <= max_y) a++;\n                    }\n                    for (const auto& p : sard) {\n                        if (min_x <= p.x && p.x <= max_x && min_y <= p.y && p.y <= max_y) b++;\n                    }\n                    int score = max(0, a - b + 1);\n                    all_candidates.push_back({min_x, max_x, min_y, max_y, score});\n                    if (score > best_score) {\n                        best_score = score;\n                        best_x1 = min_x;\n                        best_x2 = max_x;\n                        best_y1 = min_y;\n                        best_y2 = max_y;\n                    }\n                }\n            }\n        }\n    }\n\n    return {best_x1, best_x2, best_y1, best_y2, best_score};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;\n    cin >> N;\n    vector<Point> mack(N), sard(N);\n    for (int i = 0; i < N; i++) {\n        cin >> mack[i].x >> mack[i].y;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sard[i].x >> sard[i].y;\n    }\n\n    // Precompute sorted unique coordinates\n    vector<int> xs, ys;\n    for (const auto& p : mack) {\n        xs.push_back(p.x);\n        ys.push_back(p.y);\n    }\n    for (const auto& p : sard) {\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    // Try multiple grid sizes (comprehensive coverage)\n    vector<int> cell_sizes = {600, 800, 1000, 1200, 1500, 1800, 2000, 2500, 3000, 3500, 4000, \n                              4500, 5000, 5500, 6000, 6500, 7500, 8000, 9000, 10000, 12000, 14000};\n    int best_score = 0;\n    int best_x1 = 0, best_x2 = 0, best_y1 = 0, best_y2 = 0;\n    vector<tuple<int, int, int, int, int>> all_candidates;\n\n    for (int cell_size : cell_sizes) {\n        auto [x1, x2, y1, y2, score] = process_cell_size(cell_size, mack, sard, xs, ys, all_candidates);\n        if (score > best_score) {\n            best_score = score;\n            best_x1 = x1;\n            best_x2 = x2;\n            best_y1 = y1;\n            best_y2 = y2;\n        }\n    }\n\n    // Sort all candidates by score and keep top 15\n    sort(all_candidates.begin(), all_candidates.end(), \n         [](const auto& a, const auto& b) { return get<4>(a) > get<4>(b); });\n    \n    // Try merging top candidates\n    if (all_candidates.size() >= 2) {\n        int top_k = min(15, (int)all_candidates.size());\n        for (int i = 0; i < top_k; i++) {\n            for (int j = i + 1; j < top_k; j++) {\n                auto [x1_i, x2_i, y1_i, y2_i, score_i] = all_candidates[i];\n                auto [x1_j, x2_j, y1_j, y2_j, score_j] = all_candidates[j];\n                \n                // Compute union rectangle\n                int x1 = min(x1_i, x1_j);\n                int x2 = max(x2_i, x2_j);\n                int y1 = min(y1_i, y1_j);\n                int y2 = max(y2_i, y2_j);\n                \n                // Skip if same rectangle\n                if ((x1 == x1_i && x2 == x2_i && y1 == y1_i && y2 == y2_i) ||\n                    (x1 == x1_j && x2 == x2_j && y1 == y1_j && y2 == y2_j)) {\n                    continue;\n                }\n                \n                // Ensure non-degenerate\n                if (x1 >= x2 || y1 >= y2) continue;\n                \n                int new_score = compute_score(x1, x2, y1, y2, mack, sard);\n                if (new_score > best_score) {\n                    best_score = new_score;\n                    best_x1 = x1;\n                    best_x2 = x2;\n                    best_y1 = y1;\n                    best_y2 = y2;\n                }\n            }\n        }\n    }\n\n    // Apply enhanced local optimization\n    if (best_score > 0) {\n        enhanced_local_optimize(best_x1, best_x2, best_y1, best_y2, mack, sard, xs, ys);\n        best_score = compute_score(best_x1, best_x2, best_y1, best_y2, mack, sard);\n    }\n\n    // Try L-shape with the best rectangle\n    if (best_score > 0) {\n        auto [new_x1, new_x2, new_y1, new_y2, new_score, improved] = \n            try_l_shape(best_x1, best_x2, best_y1, best_y2, best_score, mack, sard, xs, ys);\n        if (improved && new_score > best_score) {\n            best_score = new_score;\n            best_x1 = new_x1;\n            best_x2 = new_x2;\n            best_y1 = new_y1;\n            best_y2 = new_y2;\n        }\n    }\n\n    // Try indent polygon for low-scoring cases\n    if (best_score < 1000 && best_score > 0) {\n        auto [new_x1, new_x2, new_y1, new_y2, new_score, improved] = \n            try_indent_polygon(best_x1, best_x2, best_y1, best_y2, best_score, mack, sard, xs, ys);\n        if (improved && new_score > best_score) {\n            best_score = new_score;\n            best_x1 = new_x1;\n            best_x2 = new_x2;\n            best_y1 = new_y1;\n            best_y2 = new_y2;\n        }\n    }\n\n    // Apply one more round of local optimization after L-shape/indent\n    if (best_score > 0) {\n        enhanced_local_optimize(best_x1, best_x2, best_y1, best_y2, mack, sard, xs, ys);\n        best_score = compute_score(best_x1, best_x2, best_y1, best_y2, mack, sard);\n    }\n\n    // For very low scores or borderline cases, try one more aggressive round\n    if ((best_score < 500 || (best_score > 950 && best_score < 1050)) && best_score > 0) {\n        // Try even more aggressive indent polygon\n        auto [new_x1, new_x2, new_y1, new_y2, new_score, improved] = \n            try_indent_polygon(best_x1, best_x2, best_y1, best_y2, best_score, mack, sard, xs, ys);\n        if (improved && new_score > best_score) {\n            best_score = new_score;\n            best_x1 = new_x1;\n            best_x2 = new_x2;\n            best_y1 = new_y1;\n            best_y2 = new_y2;\n        }\n        \n        // And one more local optimization\n        enhanced_local_optimize(best_x1, best_x2, best_y1, best_y2, mack, sard, xs, ys);\n        best_score = compute_score(best_x1, best_x2, best_y1, best_y2, mack, sard);\n    }\n\n    // Fallback if no good rectangle found\n    if (best_score == 0) {\n        // Try to find a small rectangle around a mackerel\n        for (const auto& mp : mack) {\n            int x1 = max(0, mp.x - 1);\n            int x2 = min(MAX_COORD, mp.x + 1);\n            int y1 = max(0, mp.y - 1);\n            int y2 = min(MAX_COORD, mp.y + 1);\n            int score = compute_score(x1, x2, y1, y2, mack, sard);\n            if (score > best_score) {\n                best_score = score;\n                best_x1 = x1;\n                best_x2 = x2;\n                best_y1 = y1;\n                best_y2 = y2;\n            }\n        }\n    }\n\n    // Ultimate fallback\n    if (best_score == 0) {\n        best_x1 = 0;\n        best_x2 = 1;\n        best_y1 = 0;\n        best_y2 = 1;\n        best_score = 1;\n    }\n\n    // Output as rectangle (4 vertices)\n    cout << 4 << \"\\n\";\n    cout << best_x1 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y1 << \"\\n\";\n    cout << best_x2 << \" \" << best_y2 << \"\\n\";\n    cout << best_x1 << \" \" << best_y2 << \"\\n\";\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <numeric>\n#include <limits>\n\nusing namespace std;\n\nstruct Placement {\n    int p;      // rectangle index\n    int r;      // rotation: 0 or 1\n    char d;     // direction: 'U' or 'L'\n    int b;      // reference rectangle, -1 for boundary\n};\n\nstruct PlacedRect {\n    int idx; // original index\n    long long x, y, w, h;\n};\n\n// Hybrid packing: tries all possibilities for each rectangle\nvector<Placement> generate_hybrid_packing(const vector<int>& w, const vector<int>& h,\n                                          mt19937& rng, double noise, double skip_threshold) {\n    int n = w.size();\n    vector<Placement> res;\n    vector<PlacedRect> placed;\n    uniform_real_distribution<double> dist(0.0, noise);\n\n    for (int i = 0; i < n; ++i) {\n        double best_increase = numeric_limits<double>::max();\n        Placement best_placement;\n        PlacedRect best_rect;\n\n        int w0 = w[i], h0 = h[i];\n        int w1 = h[i], h1 = w[i];\n\n        for (int r = 0; r < 2; ++r) {\n            int wc = (r == 0 ? w0 : w1);\n            int hc = (r == 0 ? h0 : h1);\n\n            for (char d : {'L', 'U'}) {\n                // Try b = -1 and all placed rectangles\n                vector<int> b_candidates = {-1};\n                for (int j = 0; j < (int)placed.size(); ++j) {\n                    b_candidates.push_back(j); // index in placed vector\n                }\n\n                for (int b_idx : b_candidates) {\n                    long long left, top;\n\n                    if (d == 'L') {\n                        // Determine top from b\n                        if (b_idx == -1) {\n                            top = 0;\n                        } else {\n                            top = placed[b_idx].y + placed[b_idx].h;\n                        }\n                        // Compute left as the maximum right edge of rectangles that overlap vertically\n                        left = 0;\n                        for (const PlacedRect& rect : placed) {\n                            if (top < rect.y + rect.h && top + hc > rect.y) {\n                                left = max(left, rect.x + rect.w);\n                            }\n                        }\n                    } else { // d == 'U'\n                        // Determine left from b\n                        if (b_idx == -1) {\n                            left = 0;\n                        } else {\n                            left = placed[b_idx].x + placed[b_idx].w;\n                        }\n                        // Compute top as the maximum bottom edge of rectangles that overlap horizontally\n                        top = 0;\n                        for (const PlacedRect& rect : placed) {\n                            if (left < rect.x + rect.w && left + wc > rect.x) {\n                                top = max(top, rect.y + rect.h);\n                            }\n                        }\n                    }\n\n                    // Check for overlap (should not happen by construction, but double-check)\n                    bool overlap = false;\n                    for (const PlacedRect& rect : placed) {\n                        if (left < rect.x + rect.w && left + wc > rect.x &&\n                            top < rect.y + rect.h && top + hc > rect.y) {\n                            overlap = true;\n                            break;\n                        }\n                    }\n                    if (overlap) {\n                        continue;\n                    }\n\n                    // Compute new overall width and height\n                    long long new_width = 0, new_height = 0;\n                    for (const PlacedRect& rect : placed) {\n                        new_width = max(new_width, rect.x + rect.w);\n                        new_height = max(new_height, rect.y + rect.h);\n                    }\n                    new_width = max(new_width, left + wc);\n                    new_height = max(new_height, top + hc);\n\n                    // Current overall width and height\n                    long long cur_width = 0, cur_height = 0;\n                    if (!placed.empty()) {\n                        for (const PlacedRect& rect : placed) {\n                            cur_width = max(cur_width, rect.x + rect.w);\n                            cur_height = max(cur_height, rect.y + rect.h);\n                        }\n                    }\n\n                    double increase = (new_width - cur_width) + (new_height - cur_height) + dist(rng);\n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        int actual_b = (b_idx == -1) ? -1 : placed[b_idx].idx;\n                        best_placement = {i, r, d, actual_b};\n                        best_rect = {i, left, top, wc, hc};\n                    }\n                }\n            }\n        }\n\n        // If no valid placement found, skip the rectangle\n        if (best_increase == numeric_limits<double>::max()) {\n            continue;\n        }\n\n        // Check skipping condition\n        long long penalty = w[i] + h[i];\n        if (best_increase > skip_threshold * penalty) {\n            continue;\n        }\n\n        // Place the rectangle\n        res.push_back(best_placement);\n        placed.push_back(best_rect);\n    }\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<long long> sum_w(N), sum_h(N);\n    vector<int> cnt(N, 1); // start with the given noisy measurements\n    for (int i = 0; i < N; ++i) {\n        int wp, hp;\n        cin >> wp >> hp;\n        sum_w[i] = wp;\n        sum_h[i] = hp;\n    }\n\n    // Estimate true sizes from the given data (already one sample)\n    vector<int> est_w(N), est_h(N);\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n    }\n\n    // Order rectangles by estimated area to prioritize measurement\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return (long long)est_w[a] * est_h[a] > (long long)est_w[b] * est_h[b];\n    });\n\n    // Number of packing attempts: 30, but ensure at least 5 measurement turns if possible\n    const int PACK_TURNS = min(30, max(1, T - 5));\n    int M = T - PACK_TURNS; // number of measurement turns\n\n    // ---------- Measurement phase ----------\n    for (int t = 0; t < M; ++t) {\n        int idx = order[t % N]; // cycle through rectangles, most important first\n        cout << \"1\\n\";\n        cout << idx << \" 0 U -1\\n\";\n        cout << flush;\n\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n\n        // Update measurements\n        sum_w[idx] += Wp;\n        sum_h[idx] += Hp;\n        cnt[idx]++;\n        // Update estimates on the fly\n        est_w[idx] = (sum_w[idx] + cnt[idx]/2) / cnt[idx];\n        est_h[idx] = (sum_h[idx] + cnt[idx]/2) / cnt[idx];\n    }\n\n    // Recompute all estimates after measurement phase\n    for (int i = 0; i < N; ++i) {\n        est_w[i] = (sum_w[i] + cnt[i]/2) / cnt[i];\n        est_h[i] = (sum_h[i] + cnt[i]/2) / cnt[i];\n        if (est_w[i] < 1) est_w[i] = 1;\n        if (est_h[i] < 1) est_h[i] = 1;\n    }\n\n    // ---------- Packing phase ----------\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    const double noise = 0.1;\n    const double skip_threshold = 2.0; // fixed, less aggressive\n\n    for (int t = M; t < T; ++t) {\n        vector<Placement> placements = generate_hybrid_packing(est_w, est_h, rng, noise, skip_threshold);\n\n        // Output the placement\n        cout << placements.size() << \"\\n\";\n        for (const auto& pl : placements) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << \"\\n\";\n        }\n        cout << flush;\n\n        // Read the measurement (ignored for further decisions)\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <tuple>\n#include <numeric>\nusing namespace std;\n\n// Proven SA parameters from the 21.5M solution with minor optimizations\nconst int MAX_ITER = 1300000;  // Slightly increased from 1200000\nconst double START_TEMP = 80.0;\nconst double COOLING = 0.999965;  // Adjusted for more iterations\nconst double START_PENALTY = 1.0;\nconst double END_PENALTY = 30000.0;\nconst int RESTART_INTERVAL = 150000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    cin >> N >> M >> H;\n\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\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    // PROVEN WORKING INITIALIZATION: BFS from low-beauty roots\n    vector<int> depth(N, -1);\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });\n\n    for (int v : order) {\n        if (depth[v] != -1) continue;\n        depth[v] = 0;\n        queue<pair<int, int>> q;\n        q.emplace(v, 0);\n        while (!q.empty()) {\n            auto [u, d] = q.front(); q.pop();\n            if (d == H) continue;\n            for (int w : adj[u]) {\n                if (depth[w] == -1) {\n                    depth[w] = d + 1;\n                    q.emplace(w, d + 1);\n                }\n            }\n        }\n    }\n\n    // Compute initial support and score\n    vector<int> support(N, 0);\n    int unsatisfied_cnt = 0;\n    long long current_score = 0;\n    for (int v = 0; v < N; ++v) {\n        current_score += (long long)depth[v] * A[v];\n        if (depth[v] > 0) {\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v] - 1) {\n                    support[v]++;\n                }\n            }\n            if (support[v] == 0) unsatisfied_cnt++;\n        }\n    }\n\n    // Best feasible solution\n    long long best_score = current_score;\n    vector<int> best_depths = depth;\n    int best_unsatisfied = unsatisfied_cnt;\n\n    // Random number generators\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> rand_vertex(0, N - 1);\n    uniform_int_distribution<int> rand_depth(0, H);\n    uniform_real_distribution<double> rand_real(0.0, 1.0);\n\n    // SA variables\n    double temp = START_TEMP;\n    double penalty_weight = START_PENALTY;\n    const double penalty_inc = (END_PENALTY - START_PENALTY) / MAX_ITER;\n    int last_improvement = 0;\n\n    // Precompute vertices sorted by beauty for biased selection\n    vector<int> vertices_by_beauty(N);\n    iota(vertices_by_beauty.begin(), vertices_by_beauty.end(), 0);\n    sort(vertices_by_beauty.begin(), vertices_by_beauty.end(), \n         [&](int i, int j) { return A[i] > A[j]; });\n\n    for (int iter = 0; iter < MAX_ITER; ++iter) {\n        // Occasionally restart from best with perturbation\n        if (iter - last_improvement > RESTART_INTERVAL && iter > 0) {\n            depth = best_depths;\n            // Recompute support and score\n            fill(support.begin(), support.end(), 0);\n            current_score = 0;\n            unsatisfied_cnt = 0;\n            for (int v = 0; v < N; ++v) {\n                current_score += (long long)depth[v] * A[v];\n                if (depth[v] > 0) {\n                    for (int u : adj[v]) {\n                        if (depth[u] == depth[v] - 1) {\n                            support[v]++;\n                        }\n                    }\n                    if (support[v] == 0) unsatisfied_cnt++;\n                }\n            }\n            // Perturbation\n            for (int i = 0; i < 15; ++i) {\n                int idx = rand_vertex(rng) % (N / 4);  // Top 25%\n                int v = vertices_by_beauty[idx];\n                int old_d = depth[v];\n                int new_d = rand_depth(rng);\n                if (old_d != new_d) {\n                    depth[v] = new_d;\n                    // Update support for v and neighbors\n                    if (depth[v] > 0) {\n                        support[v] = 0;\n                        for (int x : adj[v]) {\n                            if (depth[x] == depth[v] - 1) support[v]++;\n                        }\n                    }\n                    for (int u : adj[v]) {\n                        if (depth[u] > 0) {\n                            support[u] = 0;\n                            for (int x : adj[u]) {\n                                if (depth[x] == depth[u] - 1) support[u]++;\n                            }\n                        }\n                    }\n                }\n            }\n            // Recompute score and unsatisfied\n            current_score = 0;\n            unsatisfied_cnt = 0;\n            for (int v = 0; v < N; ++v) {\n                current_score += (long long)depth[v] * A[v];\n                if (depth[v] > 0 && support[v] == 0) unsatisfied_cnt++;\n            }\n            last_improvement = iter;\n        }\n\n        // Choose move type with optimized probabilities\n        double move_type = rand_real(rng);\n        bool is_swap = false;\n        int v, u, old_d_v, old_d_u, new_d_v, new_d_u;\n        vector<int> affected;\n\n        if (move_type < 0.35) {  // Single vertex depth change (35%)\n            // Strong bias toward high-beauty vertices\n            if (rand_real(rng) < 0.85) {\n                int idx = rand_vertex(rng) % (N / 6);  // Top 16.7%\n                v = vertices_by_beauty[idx];\n            } else {\n                v = rand_vertex(rng);\n            }\n            \n            old_d_v = depth[v];\n            \n            // Optimized depth change probabilities\n            if (rand_real(rng) < 0.70) {  // 70% chance to try increment\n                if (old_d_v < H) new_d_v = old_d_v + 1;\n                else new_d_v = rand_depth(rng);\n            } else if (rand_real(rng) < 0.85) {  // 15% chance to try decrement\n                if (old_d_v > 0) new_d_v = old_d_v - 1;\n                else new_d_v = rand_depth(rng);\n            } else {  // 15% chance random\n                new_d_v = rand_depth(rng);\n            }\n            \n            if (old_d_v == new_d_v) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            affected = {v};\n            for (int w : adj[v]) affected.push_back(w);\n        } \n        else if (move_type < 0.65) {  // Swap moves (30%)\n            // Bias toward beneficial swaps\n            if (rand_real(rng) < 0.75) {  // 75% beneficial swap\n                // Pick high A vertex with relatively low depth\n                int idx1 = rand_vertex(rng) % (N / 4);\n                v = vertices_by_beauty[idx1];\n                // Pick low A vertex with relatively high depth\n                int idx2 = N - 1 - (rand_vertex(rng) % (N / 4));\n                u = vertices_by_beauty[idx2];\n                if (v == u) u = vertices_by_beauty[(idx2 + 1) % N];\n            } else {  // 25% random swap\n                v = rand_vertex(rng);\n                u = rand_vertex(rng);\n                while (u == v) u = rand_vertex(rng);\n            }\n            \n            old_d_v = depth[v];\n            old_d_u = depth[u];\n            if (old_d_v == old_d_u) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            new_d_v = old_d_u;\n            new_d_u = old_d_v;\n            is_swap = true;\n            \n            affected = {v, u};\n            for (int w : adj[v]) affected.push_back(w);\n            for (int w : adj[u]) {\n                if (find(affected.begin(), affected.end(), w) == affected.end()) {\n                    affected.push_back(w);\n                }\n            }\n        }\n        else {  // Chain extension move (35%)\n            // Try to extend a chain for a high-beauty vertex\n            int idx = rand_vertex(rng) % (N / 3);  // Top 33%\n            v = vertices_by_beauty[idx];\n            old_d_v = depth[v];\n            \n            if (old_d_v >= H) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            // Check if we can extend: need a neighbor with depth = old_d_v\n            bool can_extend = false;\n            for (int u : adj[v]) {\n                if (depth[u] == old_d_v) {\n                    can_extend = true;\n                    break;\n                }\n            }\n            \n            if (!can_extend) {\n                temp *= COOLING;\n                penalty_weight += penalty_inc;\n                continue;\n            }\n            \n            new_d_v = old_d_v + 1;\n            affected = {v};\n            for (int w : adj[v]) affected.push_back(w);\n        }\n\n        // Compute delta\n        long long delta_score = 0;\n        double delta_penalty = 0.0;\n        int delta_unsatisfied = 0;\n        vector<pair<int, int>> updates; // (vertex, new_support)\n\n        if (is_swap) {\n            delta_score = (long long)(new_d_v - old_d_v) * A[v] + \n                         (long long)(new_d_u - old_d_u) * A[u];\n        } else {\n            delta_score = (long long)(new_d_v - old_d_v) * A[v];\n        }\n\n        for (int w : affected) {\n            int depth_w_old = depth[w];\n            int depth_w_new = depth_w_old;\n            if (w == v) depth_w_new = new_d_v;\n            else if (is_swap && w == u) depth_w_new = new_d_u;\n            \n            bool old_sat = (depth_w_old == 0) || (support[w] > 0);\n\n            // Compute new support for w\n            int new_support_w = 0;\n            for (int x : adj[w]) {\n                int depth_x = depth[x];\n                if (x == v) depth_x = new_d_v;\n                else if (is_swap && x == u) depth_x = new_d_u;\n                \n                if (depth_x == depth_w_new - 1) {\n                    new_support_w++;\n                }\n            }\n            bool new_sat = (depth_w_new == 0) || (new_support_w > 0);\n\n            delta_penalty += penalty_weight * ((new_sat ? 0 : A[w]) - (old_sat ? 0 : A[w]));\n            delta_unsatisfied += (new_sat ? 0 : 1) - (old_sat ? 0 : 1);\n            updates.emplace_back(w, new_support_w);\n        }\n\n        double delta_total = delta_score - delta_penalty;\n\n        if (delta_total > 0.0 || rand_real(rng) < exp(delta_total / temp)) {\n            // Accept move\n            depth[v] = new_d_v;\n            if (is_swap) depth[u] = new_d_u;\n            \n            for (auto& [w, ns] : updates) {\n                support[w] = ns;\n            }\n            current_score += delta_score;\n            unsatisfied_cnt += delta_unsatisfied;\n\n            // Update best feasible solution\n            if (unsatisfied_cnt == 0 && current_score > best_score) {\n                best_score = current_score;\n                best_depths = depth;\n                last_improvement = iter;\n            }\n        }\n\n        temp *= COOLING;\n        penalty_weight += penalty_inc;\n    }\n\n    // Proven post-processing from the 21.5M solution\n    depth = best_depths;\n    \n    // Fix any infeasibility\n    bool feasible = false;\n    while (!feasible) {\n        feasible = true;\n        for (int v = 0; v < N; ++v) {\n            if (depth[v] > 0) {\n                int sup = 0;\n                for (int u : adj[v]) {\n                    if (depth[u] == depth[v] - 1) sup++;\n                }\n                if (sup == 0) {\n                    feasible = false;\n                    depth[v] = 0;\n                }\n            }\n        }\n    }\n    \n    // Update best score\n    long long score = 0;\n    for (int v = 0; v < N; ++v) score += (long long)depth[v] * A[v];\n    if (score > best_score) {\n        best_score = score;\n        best_depths = depth;\n    }\n    \n    // Multi-pass greedy optimization (7 passes as in 21.5M solution)\n    for (int pass = 0; pass < 7; ++pass) {\n        bool improved = false;\n        for (int v : vertices_by_beauty) {\n            if (depth[v] >= H) continue;\n            \n            // Check if we can increment\n            bool has_support = false;\n            for (int u : adj[v]) {\n                if (depth[u] == depth[v]) {\n                    has_support = true;\n                    break;\n                }\n            }\n            if (!has_support) continue;\n            \n            // Try increment\n            int old_d = depth[v];\n            depth[v]++;\n            \n            // Check feasibility\n            bool feasible = true;\n            vector<int> to_check = {v};\n            for (int u : adj[v]) to_check.push_back(u);\n            \n            for (int w : to_check) {\n                if (depth[w] > 0) {\n                    int sup = 0;\n                    for (int x : adj[w]) {\n                        if (depth[x] == depth[w] - 1) sup++;\n                    }\n                    if (sup == 0) {\n                        feasible = false;\n                        break;\n                    }\n                }\n            }\n            \n            if (feasible) {\n                improved = true;\n                long long new_score = 0;\n                for (int i = 0; i < N; ++i) new_score += (long long)depth[i] * A[i];\n                if (new_score > best_score) {\n                    best_score = new_score;\n                    best_depths = depth;\n                }\n            } else {\n                depth[v] = old_d;  // Revert\n            }\n        }\n        if (!improved) break;\n    }\n\n    depth = best_depths;\n\n    // Assign parents\n    vector<int> parent(N, -1);\n    for (int v = 0; v < N; ++v) {\n        if (depth[v] == 0) continue;\n        for (int u : adj[v]) {\n            if (depth[u] == depth[v] - 1) {\n                parent[v] = u;\n                break;\n            }\n        }\n    }\n\n    // Output\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nvector<string> simulate_columns_first(vector<string> board) {\n    int N = board.size();\n    vector<string> ops;\n    \n    // Process columns\n    for (int j = 0; j < N; ++j) {\n        int top_f = N, bottom_f = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                top_f = min(top_f, i);\n                bottom_f = max(bottom_f, i);\n            }\n        }\n        \n        // If no fuku in column, clear with single shifts\n        if (top_f == N) {\n            bool has_oni = false;\n            for (int i = 0; i < N; ++i) {\n                if (board[i][j] == 'x') {\n                    has_oni = true;\n                    break;\n                }\n            }\n            if (has_oni) {\n                // Use up shifts to clear\n                for (int k = 0; k < N; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int i = 0; i < N; ++i) board[i][j] = '.';\n            }\n            continue;\n        }\n        \n        // Check for oni in top and bottom zones\n        bool has_top_oni = false;\n        for (int i = 0; i < top_f; ++i) {\n            if (board[i][j] == 'x') {\n                has_top_oni = true;\n                break;\n            }\n        }\n        \n        bool has_bottom_oni = false;\n        for (int i = bottom_f + 1; i < N; ++i) {\n            if (board[i][j] == 'x') {\n                has_bottom_oni = true;\n                break;\n            }\n        }\n        \n        // Process zones\n        if (has_top_oni && has_bottom_oni) {\n            // Process smaller zone first\n            if (top_f <= N - 1 - bottom_f) {\n                // Top zone is smaller or equal\n                int t = top_f;\n                for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int i = 0; i < t; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n                \n                int b = N - 1 - bottom_f;\n                for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int i = bottom_f + 1; i < N; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n            } else {\n                // Bottom zone is smaller\n                int b = N - 1 - bottom_f;\n                for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int i = bottom_f + 1; i < N; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n                \n                int t = top_f;\n                for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n                for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n                for (int i = 0; i < t; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n            }\n        } else if (has_top_oni) {\n            int t = top_f;\n            for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int k = 0; k < t; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int i = 0; i < t; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n        } else if (has_bottom_oni) {\n            int b = N - 1 - bottom_f;\n            for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int k = 0; k < b; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int i = bottom_f + 1; i < N; ++i) if (board[i][j] == 'x') board[i][j] = '.';\n        }\n    }\n    \n    // Process rows with single shifts\n    for (int i = 0; i < N; ++i) {\n        int left_f = N, right_f = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                left_f = min(left_f, j);\n                right_f = max(right_f, j);\n            }\n        }\n        \n        // Process left zone\n        bool has_left_oni = false;\n        for (int j = 0; j < left_f; ++j) {\n            if (board[i][j] == 'x') {\n                has_left_oni = true;\n                break;\n            }\n        }\n        \n        if (has_left_oni) {\n            int l = left_f;\n            for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n            string new_row(N, '.');\n            for (int j = l; j < N; ++j) new_row[j - l] = board[i][j];\n            board[i] = new_row;\n        }\n        \n        // Recompute right_f after left shift\n        right_f = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                right_f = max(right_f, j);\n            }\n        }\n        \n        // Process right zone\n        bool has_right_oni = false;\n        for (int j = right_f + 1; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                has_right_oni = true;\n                break;\n            }\n        }\n        \n        if (has_right_oni) {\n            int r = N - 1 - right_f;\n            for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n            string new_row(N, '.');\n            for (int j = 0; j < N - r; ++j) new_row[j + r] = board[i][j];\n            board[i] = new_row;\n        }\n    }\n    \n    return ops;\n}\n\nvector<string> simulate_rows_first(vector<string> board) {\n    int N = board.size();\n    vector<string> ops;\n    \n    // Process rows\n    for (int i = 0; i < N; ++i) {\n        int left_f = N, right_f = -1;\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 'o') {\n                left_f = min(left_f, j);\n                right_f = max(right_f, j);\n            }\n        }\n        \n        // If no fuku in row, clear with single shifts\n        if (left_f == N) {\n            bool has_oni = false;\n            for (int j = 0; j < N; ++j) {\n                if (board[i][j] == 'x') {\n                    has_oni = true;\n                    break;\n                }\n            }\n            if (has_oni) {\n                for (int k = 0; k < N; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int j = 0; j < N; ++j) board[i][j] = '.';\n            }\n            continue;\n        }\n        \n        bool has_left_oni = false;\n        for (int j = 0; j < left_f; ++j) {\n            if (board[i][j] == 'x') {\n                has_left_oni = true;\n                break;\n            }\n        }\n        \n        bool has_right_oni = false;\n        for (int j = right_f + 1; j < N; ++j) {\n            if (board[i][j] == 'x') {\n                has_right_oni = true;\n                break;\n            }\n        }\n        \n        if (has_left_oni && has_right_oni) {\n            // Process smaller zone first\n            if (left_f <= N - 1 - right_f) {\n                int l = left_f;\n                for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int j = 0; j < l; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n                \n                int r = N - 1 - right_f;\n                for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int j = right_f + 1; j < N; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n            } else {\n                int r = N - 1 - right_f;\n                for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int j = right_f + 1; j < N; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n                \n                int l = left_f;\n                for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n                for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n                for (int j = 0; j < l; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n            }\n        } else if (has_left_oni) {\n            int l = left_f;\n            for (int k = 0; k < l; ++k) ops.push_back(\"L \" + to_string(i));\n            for (int k = 0; k < l; ++k) ops.push_back(\"R \" + to_string(i));\n            for (int j = 0; j < l; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n        } else if (has_right_oni) {\n            int r = N - 1 - right_f;\n            for (int k = 0; k < r; ++k) ops.push_back(\"R \" + to_string(i));\n            for (int k = 0; k < r; ++k) ops.push_back(\"L \" + to_string(i));\n            for (int j = right_f + 1; j < N; ++j) if (board[i][j] == 'x') board[i][j] = '.';\n        }\n    }\n    \n    // Process columns with single shifts\n    for (int j = 0; j < N; ++j) {\n        int top_f = N, bottom_f = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                top_f = min(top_f, i);\n                bottom_f = max(bottom_f, i);\n            }\n        }\n        \n        // Process top zone\n        bool has_top_oni = false;\n        for (int i = 0; i < top_f; ++i) {\n            if (board[i][j] == 'x') {\n                has_top_oni = true;\n                break;\n            }\n        }\n        \n        if (has_top_oni) {\n            int t = top_f;\n            for (int k = 0; k < t; ++k) ops.push_back(\"U \" + to_string(j));\n            for (int i = 0; i < N - t; ++i) board[i][j] = board[i + t][j];\n            for (int i = N - t; i < N; ++i) board[i][j] = '.';\n        }\n        \n        // Recompute bottom_f after up shift\n        bottom_f = -1;\n        for (int i = 0; i < N; ++i) {\n            if (board[i][j] == 'o') {\n                bottom_f = max(bottom_f, i);\n            }\n        }\n        \n        // Process bottom zone\n        bool has_bottom_oni = false;\n        for (int i = bottom_f + 1; i < N; ++i) {\n            if (board[i][j] == 'x') {\n                has_bottom_oni = true;\n                break;\n            }\n        }\n        \n        if (has_bottom_oni) {\n            int b = N - 1 - bottom_f;\n            for (int k = 0; k < b; ++k) ops.push_back(\"D \" + to_string(j));\n            for (int i = N - 1; i >= b; --i) board[i][j] = board[i - b][j];\n            for (int i = 0; i < b; ++i) board[i][j] = '.';\n        }\n    }\n    \n    return ops;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n    \n    auto ops1 = simulate_columns_first(board);\n    auto ops2 = simulate_rows_first(board);\n    \n    if (ops1.size() <= ops2.size()) {\n        for (const string& op : ops1) cout << op << '\\n';\n    } else {\n        for (const string& op : ops2) cout << op << '\\n';\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\nconst int L = 500000;\n\nint T[N];\nint a[N], b[N];\nint best_a[N], best_b[N];\nint best_error;\n\n// Fast simulation\nint simulate(const int a[], const int b[]) {\n    int count[N] = {0};\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int next;\n        if (count[current] & 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\n// Get error vector for analysis\nvector<int> get_errors(const int a[], const int b[]) {\n    vector<int> count(N, 0);\n    int current = 0;\n    for (int week = 1; week <= L; week++) {\n        count[current]++;\n        if (week == L) break;\n        int next;\n        if (count[current] & 1) {\n            next = a[current];\n        } else {\n            next = b[current];\n        }\n        current = next;\n    }\n    vector<int> errors(N);\n    for (int i = 0; i < N; i++) {\n        errors[i] = abs(count[i] - T[i]);\n    }\n    return errors;\n}\n\n// Improved flow-based initialization with multiple strategies\nvoid flow_based_init(int strategy) {\n    int out_a[N], out_b[N];\n    for (int i = 0; i < N; i++) {\n        out_a[i] = (T[i] + 1) / 2;\n        out_b[i] = T[i] / 2;\n    }\n    \n    int in_demand[N];\n    for (int i = 0; i < N; i++) {\n        in_demand[i] = T[i];\n    }\n    in_demand[0]--;\n    \n    vector<tuple<int, int, bool>> items;\n    for (int i = 0; i < N; i++) {\n        items.push_back({out_a[i], i, true});\n        items.push_back({out_b[i], i, false});\n    }\n    \n    // Different sorting strategies\n    if (strategy == 0) {\n        sort(items.rbegin(), items.rend()); // Descending by weight\n    } else if (strategy == 1) {\n        sort(items.begin(), items.end()); // Ascending by weight\n    } else {\n        shuffle(items.begin(), items.end(), mt19937(42)); // Random order\n    }\n    \n    fill(a, a + N, -1);\n    fill(b, b + N, -1);\n    \n    for (auto& [weight, i, is_a] : items) {\n        // Find best employee(s) with highest remaining demand\n        vector<int> candidates;\n        int max_demand = -1;\n        for (int j = 0; j < N; j++) {\n            if (in_demand[j] > max_demand) {\n                max_demand = in_demand[j];\n                candidates.clear();\n                candidates.push_back(j);\n            } else if (in_demand[j] == max_demand && max_demand > 0) {\n                candidates.push_back(j);\n            }\n        }\n        \n        if (candidates.empty()) {\n            candidates.push_back(0);\n        }\n        \n        int best_j = candidates[rand() % candidates.size()];\n        \n        if (is_a) {\n            a[i] = best_j;\n        } else {\n            b[i] = best_j;\n        }\n        \n        in_demand[best_j] -= weight;\n        if (in_demand[best_j] < 0) in_demand[best_j] = 0;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (a[i] == -1) a[i] = 0;\n        if (b[i] == -1) b[i] = 0;\n    }\n}\n\nvoid solve() {\n    // Try multiple initialization strategies and keep the best\n    int best_init_error = INT_MAX;\n    int temp_a[N], temp_b[N];\n    \n    for (int strategy = 0; strategy < 3; strategy++) {\n        flow_based_init(strategy);\n        int error = simulate(a, b);\n        if (error < best_init_error) {\n            best_init_error = error;\n            memcpy(temp_a, a, sizeof(a));\n            memcpy(temp_b, b, sizeof(b));\n        }\n    }\n    \n    memcpy(a, temp_a, sizeof(a));\n    memcpy(b, temp_b, sizeof(b));\n    int current_error = simulate(a, b);\n    best_error = current_error;\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis_emp(0, N - 1);\n    uniform_real_distribution<> dis_real(0, 1);\n    \n    double temperature = 55.0;\n    double cooling_rate = 0.9965;\n    int max_iter = 750;\n    auto start_time = chrono::steady_clock::now();\n    int no_improvement_count = 0;\n    int restart_count = 0;\n    \n    for (int iter = 0; iter < max_iter; iter++) {\n        auto current_time = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > 1.85) break;\n        \n        int new_a[N], new_b[N];\n        memcpy(new_a, a, sizeof(a));\n        memcpy(new_b, b, sizeof(b));\n        \n        // Adaptive move selection\n        double move_type = dis_real(gen);\n        \n        // More aggressive exploration early, more refinement later\n        if (iter < max_iter / 4) {\n            // Early: focus on exploration\n            if (move_type < 0.7) {\n                int i = dis_emp(gen);\n                if (dis_real(gen) < 0.5) {\n                    new_a[i] = dis_emp(gen);\n                } else {\n                    new_b[i] = dis_emp(gen);\n                }\n            } else if (move_type < 0.9) {\n                // Swap edges\n                int i = dis_emp(gen);\n                int j = dis_emp(gen);\n                while (i == j) j = dis_emp(gen);\n                int swap_type = dis_real(gen) * 4;\n                if (swap_type == 0) swap(new_a[i], new_a[j]);\n                else if (swap_type == 1) swap(new_b[i], new_b[j]);\n                else if (swap_type == 2) swap(new_a[i], new_b[j]);\n                else swap(new_b[i], new_a[j]);\n            } else {\n                // Change both edges\n                int i = dis_emp(gen);\n                new_a[i] = dis_emp(gen);\n                new_b[i] = dis_emp(gen);\n            }\n        } else if (iter < 3 * max_iter / 4) {\n            // Middle: balanced exploration and exploitation\n            if (move_type < 0.5) {\n                int i = dis_emp(gen);\n                if (dis_real(gen) < 0.5) {\n                    new_a[i] = dis_emp(gen);\n                } else {\n                    new_b[i] = dis_emp(gen);\n                }\n            } else if (move_type < 0.85) {\n                int i = dis_emp(gen);\n                int j = dis_emp(gen);\n                while (i == j) j = dis_emp(gen);\n                int swap_type = dis_real(gen) * 4;\n                if (swap_type == 0) swap(new_a[i], new_a[j]);\n                else if (swap_type == 1) swap(new_b[i], new_b[j]);\n                else if (swap_type == 2) swap(new_a[i], new_b[j]);\n                else swap(new_b[i], new_a[j]);\n            } else {\n                int i = dis_emp(gen);\n                new_a[i] = dis_emp(gen);\n                new_b[i] = dis_emp(gen);\n            }\n        } else {\n            // Late: focus on refinement\n            if (move_type < 0.15) {\n                int i = dis_emp(gen);\n                if (dis_real(gen) < 0.5) {\n                    new_a[i] = dis_emp(gen);\n                } else {\n                    new_b[i] = dis_emp(gen);\n                }\n            } else if (move_type < 0.95) {\n                int i = dis_emp(gen);\n                int j = dis_emp(gen);\n                while (i == j) j = dis_emp(gen);\n                int swap_type = dis_real(gen) * 4;\n                if (swap_type == 0) swap(new_a[i], new_a[j]);\n                else if (swap_type == 1) swap(new_b[i], new_b[j]);\n                else if (swap_type == 2) swap(new_a[i], new_b[j]);\n                else swap(new_b[i], new_a[j]);\n            } else {\n                int i = dis_emp(gen);\n                new_a[i] = dis_emp(gen);\n                new_b[i] = dis_emp(gen);\n            }\n        }\n        \n        // Occasionally focus on worst employees\n        if (iter % 50 == 0 && no_improvement_count > 10) {\n            auto errors = get_errors(a, b);\n            vector<pair<int, int>> error_pairs;\n            for (int i = 0; i < N; i++) {\n                error_pairs.push_back({errors[i], i});\n            }\n            sort(error_pairs.rbegin(), error_pairs.rend());\n            \n            // Perturb top 2 worst employees\n            for (int k = 0; k < min(2, (int)error_pairs.size()); k++) {\n                int i = error_pairs[k].second;\n                if (dis_real(gen) < 0.5) {\n                    new_a[i] = dis_emp(gen);\n                } else {\n                    new_b[i] = dis_emp(gen);\n                }\n            }\n        }\n        \n        int new_error = simulate(new_a, new_b);\n        int diff = new_error - current_error;\n        \n        if (diff < 0 || dis_real(gen) < exp(-diff / temperature)) {\n            memcpy(a, new_a, sizeof(a));\n            memcpy(b, new_b, sizeof(b));\n            current_error = new_error;\n            no_improvement_count = 0;\n            if (new_error < best_error) {\n                best_error = new_error;\n                memcpy(best_a, new_a, sizeof(new_a));\n                memcpy(best_b, new_b, sizeof(new_b));\n            }\n        } else {\n            no_improvement_count++;\n        }\n        \n        // Restart mechanism\n        if (no_improvement_count > 30 && restart_count < 3) {\n            memcpy(a, best_a, sizeof(a));\n            memcpy(b, best_b, sizeof(b));\n            current_error = best_error;\n            temperature = 60.0;\n            no_improvement_count = 0;\n            restart_count++;\n        }\n        \n        temperature *= cooling_rate;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int n, l;\n    cin >> n >> l;\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n#include <functional>\n#include <set>\n#include <queue>\n#include <map>\n#include <random>\n\nusing namespace std;\n\n// Query function with limit checking\nvector<pair<int, int>> query(const vector<int>& cities, int &queries_used, int Q) {\n    if (queries_used >= Q) {\n        return {};\n    }\n    \n    int l = cities.size();\n    cout << \"? \" << l;\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    queries_used++;\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < l - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        edges.emplace_back(min(a, b), max(a, b));\n    }\n    return edges;\n}\n\n// Calculate expected squared distance between two uniform distributions in rectangles\ndouble expected_squared_distance(int i, int j, const vector<int>& lx, const vector<int>& rx, \n                                 const vector<int>& ly, const vector<int>& ry) {\n    double center_x_i = (lx[i] + rx[i]) / 2.0;\n    double center_y_i = (ly[i] + ry[i]) / 2.0;\n    double center_x_j = (lx[j] + rx[j]) / 2.0;\n    double center_y_j = (ly[j] + ry[j]) / 2.0;\n    \n    double width_i = rx[i] - lx[i];\n    double height_i = ry[i] - ly[i];\n    double width_j = rx[j] - lx[j];\n    double height_j = ry[j] - ry[j];\n    \n    // Expected squared distance = squared distance between centers + variances\n    double dx_center = center_x_i - center_x_j;\n    double dy_center = center_y_i - center_y_j;\n    double variance_x = (width_i * width_i + width_j * width_j) / 12.0;\n    double variance_y = (height_i * height_i + height_j * height_j) / 12.0;\n    \n    return dx_center * dx_center + dy_center * dy_center + variance_x + variance_y;\n}\n\n// Calculate expected distance (approximation)\ndouble expected_distance(int i, int j, const vector<int>& lx, const vector<int>& rx, \n                         const vector<int>& ly, const vector<int>& ry) {\n    return sqrt(expected_squared_distance(i, j, lx, rx, ly, ry));\n}\n\n// Disjoint Set Union for Kruskal's algorithm\nstruct DSU {\n    vector<int> parent, rank;\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    bool unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<int> lx(N), rx(N), ly(N), ry(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Sort groups by size (largest first)\n    vector<int> group_order(M);\n    for (int i = 0; i < M; i++) group_order[i] = i;\n    sort(group_order.begin(), group_order.end(), [&](int i, int j) {\n        return G[i] > G[j];\n    });\n    \n    // Compute all centers\n    vector<pair<double, double>> centers(N);\n    for (int i = 0; i < N; i++) {\n        centers[i].first = (lx[i] + rx[i]) / 2.0;\n        centers[i].second = (ly[i] + ry[i]) / 2.0;\n    }\n    \n    // Initialize groups using a more sophisticated clustering\n    vector<vector<int>> groups(M);\n    vector<bool> assigned(N, false);\n    \n    // Use a priority queue to build groups by adding the closest city to the current group\n    for (int gi : group_order) {\n        int needed = G[gi];\n        \n        // Find the best seed: city with smallest rectangle (most precise)\n        int best_seed = -1;\n        double best_area = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double area = (rx[i] - lx[i]) * (ry[i] - ly[i]);\n                if (area < best_area) {\n                    best_area = area;\n                    best_seed = i;\n                }\n            }\n        }\n        \n        if (best_seed == -1) continue;\n        \n        // Start group with seed\n        groups[gi].push_back(best_seed);\n        assigned[best_seed] = true;\n        needed--;\n        \n        // Use a priority queue to add cities that minimize the maximum distance to the group\n        while (needed > 0) {\n            int best_city = -1;\n            double best_score = 1e18;\n            \n            for (int i = 0; i < N; i++) {\n                if (assigned[i]) continue;\n                \n                // Calculate the maximum distance to any city in the group\n                double max_dist = 0;\n                for (int c : groups[gi]) {\n                    double dist = expected_distance(i, c, lx, rx, ly, ry);\n                    max_dist = max(max_dist, dist);\n                }\n                \n                // Also consider the area of the rectangle (smaller is better)\n                double area = (rx[i] - lx[i]) * (ry[i] - ly[i]);\n                double score = max_dist + area * 1e-6;  // Small weight for area\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_city = i;\n                }\n            }\n            \n            if (best_city == -1) break;\n            \n            groups[gi].push_back(best_city);\n            assigned[best_city] = true;\n            needed--;\n        }\n    }\n    \n    // Store all discovered edges with their heuristic scores\n    vector<vector<pair<double, pair<int, int>>>> group_edges_with_score(M);\n    int queries_used = 0;\n    \n    // Process each group with efficient query strategy\n    for (int g = 0; g < M && queries_used < Q; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        set<pair<int, int>> discovered_edges;\n        \n        // Strategy 1: Query entire group if small enough\n        if (sz <= L && queries_used < Q) {\n            auto edges = query(groups[g], queries_used, Q);\n            for (auto& e : edges) {\n                if (discovered_edges.find(e) == discovered_edges.end()) {\n                    double dist = expected_distance(e.first, e.second, lx, rx, ly, ry);\n                    group_edges_with_score[g].push_back({dist, e});\n                    discovered_edges.insert(e);\n                }\n            }\n        }\n        \n        // Strategy 2: Use overlapping windows with multiple sorting strategies\n        if (sz > L && queries_used < Q) {\n            // Try different sorting strategies to discover diverse edges\n            vector<function<bool(int, int)>> sort_functions = {\n                [&](int i, int j) { return centers[i].first < centers[j].first; },\n                [&](int i, int j) { return centers[i].second < centers[j].second; },\n                [&](int i, int j) { \n                    return (centers[i].first + centers[i].second) < \n                           (centers[j].first + centers[j].second);\n                }\n            };\n            \n            for (auto& sort_func : sort_functions) {\n                if (queries_used >= Q) break;\n                \n                vector<int> sorted_group = groups[g];\n                sort(sorted_group.begin(), sorted_group.end(), sort_func);\n                \n                int start = 0;\n                while (start < sz - 1 && queries_used < Q) {\n                    int end = min(start + L, sz);\n                    vector<int> window(sorted_group.begin() + start, sorted_group.begin() + end);\n                    \n                    if (window.size() >= 2) {\n                        auto edges = query(window, queries_used, Q);\n                        for (auto& e : edges) {\n                            if (discovered_edges.find(e) == discovered_edges.end()) {\n                                double dist = expected_distance(e.first, e.second, lx, rx, ly, ry);\n                                group_edges_with_score[g].push_back({dist, e});\n                                discovered_edges.insert(e);\n                            }\n                        }\n                    }\n                    \n                    // Move forward by L/2 for more overlap\n                    start = start + max(1, L / 2);\n                }\n            }\n        }\n        \n        // Strategy 3: For large groups, use random subsets\n        if (sz > 2 * L && queries_used < Q) {\n            random_device rd;\n            mt19937 gen(rd());\n            \n            int attempts = min(2, (Q - queries_used));\n            for (int attempt = 0; attempt < attempts && queries_used < Q; attempt++) {\n                shuffle(groups[g].begin(), groups[g].end(), gen);\n                vector<int> subset(groups[g].begin(), groups[g].begin() + min(L, sz));\n                \n                auto edges = query(subset, queries_used, Q);\n                for (auto& e : edges) {\n                    if (discovered_edges.find(e) == discovered_edges.end()) {\n                        double dist = expected_distance(e.first, e.second, lx, rx, ly, ry);\n                        group_edges_with_score[g].push_back({dist, e});\n                        discovered_edges.insert(e);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        // Output cities in group\n        for (int j = 0; j < (int)groups[g].size(); j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[g][j];\n        }\n        cout << endl;\n        \n        // Build MST using Kruskal's algorithm\n        vector<pair<double, pair<int, int>>> edges_for_kruskal = group_edges_with_score[g];\n        \n        // Sort by expected distance (heuristic for true distance)\n        sort(edges_for_kruskal.begin(), edges_for_kruskal.end());\n        \n        // Create mapping from global city index to local index in group\n        map<int, int> global_to_local;\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            global_to_local[groups[g][i]] = i;\n        }\n        \n        // Run Kruskal's algorithm\n        DSU dsu(groups[g].size());\n        vector<pair<int, int>> mst_edges;\n        \n        for (auto& we : edges_for_kruskal) {\n            auto& e = we.second;\n            int u = global_to_local[e.first];\n            int v = global_to_local[e.second];\n            if (dsu.unite(u, v)) {\n                mst_edges.push_back(e);\n                if (mst_edges.size() == groups[g].size() - 1) break;\n            }\n        }\n        \n        // If we don't have enough edges, add all possible edges with expected distances\n        if (mst_edges.size() < groups[g].size() - 1) {\n            // Generate all possible edges with expected distances\n            vector<pair<double, pair<int, int>>> all_edges;\n            for (int i = 0; i < groups[g].size(); i++) {\n                for (int j = i + 1; j < groups[g].size(); j++) {\n                    int city_i = groups[g][i];\n                    int city_j = groups[g][j];\n                    double dist = expected_distance(city_i, city_j, lx, rx, ly, ry);\n                    all_edges.push_back({dist, {city_i, city_j}});\n                }\n            }\n            \n            // Sort by expected distance and add to MST\n            sort(all_edges.begin(), all_edges.end());\n            for (auto& we : all_edges) {\n                auto& e = we.second;\n                // Check if edge already exists in mst_edges\n                bool exists = false;\n                for (auto& edge : mst_edges) {\n                    if (edge == e) {\n                        exists = true;\n                        break;\n                    }\n                }\n                if (!exists) {\n                    int u = global_to_local[e.first];\n                    int v = global_to_local[e.second];\n                    if (dsu.unite(u, v)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == groups[g].size() - 1) break;\n                    }\n                }\n            }\n        }\n        \n        // Output edges\n        for (auto& e : mst_edges) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <utility>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n\n    vector<string> actions;\n    int cx = targets[0].first, cy = targets[0].second;\n    const int MAX_ACTIONS = 800;\n\n    for (int k = 1; k < M; ++k) {\n        int tx = targets[k].first, ty = targets[k].second;\n        while ((cx != tx || cy != ty) && actions.size() < MAX_ACTIONS) {\n            if (cx == tx) {\n                if (ty == 0 && cy > 0) {\n                    actions.push_back(\"S L\");\n                    cy = 0;\n                } else if (ty == N - 1 && cy < N - 1) {\n                    actions.push_back(\"S R\");\n                    cy = N - 1;\n                } else {\n                    if (cy < ty) {\n                        actions.push_back(\"M R\");\n                        cy++;\n                    } else {\n                        actions.push_back(\"M L\");\n                        cy--;\n                    }\n                }\n            } else if (cy == ty) {\n                if (tx == 0 && cx > 0) {\n                    actions.push_back(\"S U\");\n                    cx = 0;\n                } else if (tx == N - 1 && cx < N - 1) {\n                    actions.push_back(\"S D\");\n                    cx = N - 1;\n                } else {\n                    if (cx < tx) {\n                        actions.push_back(\"M D\");\n                        cx++;\n                    } else {\n                        actions.push_back(\"M U\");\n                        cx--;\n                    }\n                }\n            } else {\n                if (tx == 0 || tx == N - 1 || ty == 0 || ty == N - 1) {\n                    // Target at boundary: prioritize aligning with the boundary direction\n                    if (ty == 0 || ty == N - 1) {\n                        // Horizontal boundary: move vertically to align row first\n                        if (cx < tx) {\n                            actions.push_back(\"M D\");\n                            cx++;\n                        } else if (cx > tx) {\n                            actions.push_back(\"M U\");\n                            cx--;\n                        }\n                    } else {\n                        // Vertical boundary: move horizontally to align column first\n                        if (cy < ty) {\n                            actions.push_back(\"M R\");\n                            cy++;\n                        } else if (cy > ty) {\n                            actions.push_back(\"M L\");\n                            cy--;\n                        }\n                    }\n                } else {\n                    // Target not at boundary: move in the direction of larger difference\n                    if (abs(cx - tx) >= abs(cy - ty)) {\n                        if (cx < tx) {\n                            actions.push_back(\"M D\");\n                            cx++;\n                        } else {\n                            actions.push_back(\"M U\");\n                            cx--;\n                        }\n                    } else {\n                        if (cy < ty) {\n                            actions.push_back(\"M R\");\n                            cy++;\n                        } else {\n                            actions.push_back(\"M L\");\n                            cy--;\n                        }\n                    }\n                }\n            }\n        }\n        if (actions.size() >= MAX_ACTIONS) {\n            break;\n        }\n    }\n\n    // Output actions\n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n\n    return 0;\n}"}}}