{"model_name":"deepseek-v4-flash-no-thinking","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast random number generation\nstruct Xorshift {\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    int rand_int(int l, int r) {\n        return l + next() % (r - l + 1);\n    }\n    double rand_double() {\n        return (double)next() / ULLONG_MAX;\n    }\n} rng;\n\nstruct Rect {\n    int a, b, c, d;  // (a,b) top-left, (c,d) bottom-right\n    int x, y, r;     // target point and desired area\n    int s;           // current area\n    \n    Rect() {}\n    Rect(int a_, int b_, int c_, int d_, int x_, int y_, int r_)\n        : a(a_), b(b_), c(c_), d(d_), x(x_), y(y_), r(r_) {\n        s = (c - a) * (d - b);\n    }\n    \n    // Check if point (x+0.5, y+0.5) is inside\n    bool contains() const {\n        return a <= x && x < c && b <= y && y < d;\n    }\n    \n    double score() const {\n        if (!contains()) return 0.0;\n        double min_s = min(r, s);\n        double max_s = max(r, s);\n        return 1.0 - (1.0 - min_s / max_s) * (1.0 - min_s / max_s);\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), r(n);\n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    // Phase 1: Greedy construction using quadtree-like partitioning\n    vector<Rect> rects(n);\n    \n    // Sort by area (largest first) for better packing\n    vector<int> idx(n);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        return r[i] > r[j];\n    });\n    \n    // Simple grid-based initial placement\n    // Each company gets a rectangle around its target point\n    // We use a naive spacing first, then optimize\n    \n    // For simplicity, let's start with small rectangles around each point\n    // and then expand greedily\n    \n    // Actually, let's use a more systematic approach:\n    // Divide the space using a grid based on the points\n    \n    // Initialize with minimal valid rectangles (1x1 containing the target)\n    for (int i = 0; i < n; i++) {\n        rects[i] = Rect(x[i], y[i], x[i] + 1, y[i] + 1, x[i], y[i], r[i]);\n    }\n    \n    // Phase 2: Simple local search - expand each rectangle greedily\n    // We'll do multiple passes\n    \n    auto total_score = [&]() {\n        double sum = 0;\n        for (auto& rect : rects) {\n            sum += rect.score();\n        }\n        return sum;\n    };\n    \n    auto is_overlap = [&](int i, int j) {\n        auto& a = rects[i];\n        auto& b = rects[j];\n        return max(a.a, b.a) < min(a.c, b.c) && \n               max(a.b, b.b) < min(a.d, b.d);\n    };\n    \n    // Try to expand each rectangle randomly\n    vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n    \n    for (int phase = 0; phase < 100; phase++) {\n        // Process in random order\n        vector<int> order(n);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), [&](int i) {\n            return rng.rand_int(0, i);\n        });\n        \n        for (int i : order) {\n            auto& rect = rects[i];\n            int best_a = rect.a, best_b = rect.b, best_c = rect.c, best_d = rect.d;\n            double best_score = rect.score();\n            \n            // Try small random adjustments\n            for (int attempt = 0; attempt < 20; attempt++) {\n                // Pick a direction and try to expand/shrink\n                int da = rng.rand_int(-5, 5);\n                int db = rng.rand_int(-5, 5);\n                int dc = rng.rand_int(-5, 5);\n                int dd = rng.rand_int(-5, 5);\n                \n                int na = rect.a + da;\n                int nb = rect.b + db;\n                int nc = rect.c + dc;\n                int nd = rect.d + dd;\n                \n                // Clamp to grid\n                na = max(0, min(na, 9999));\n                nb = max(0, min(nb, 9999));\n                nc = max(na + 1, min(nc, 10000));\n                nd = max(nb + 1, min(nd, 10000));\n                \n                // Must contain target point\n                if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n                \n                Rect new_rect(na, nb, nc, nd, x[i], y[i], r[i]);\n                \n                // Check overlap with others\n                bool overlap = false;\n                for (int j = 0; j < n; j++) {\n                    if (i == j) continue;\n                    if (max(na, rects[j].a) < min(nc, rects[j].c) && \n                        max(nb, rects[j].b) < min(nd, rects[j].d)) {\n                        overlap = true;\n                        break;\n                    }\n                }\n                if (overlap) continue;\n                \n                double new_score = new_rect.score();\n                if (new_score > best_score + 1e-9) {\n                    best_score = new_score;\n                    best_a = na; best_b = nb;\n                    best_c = nc; best_d = nd;\n                }\n            }\n            \n            rect.a = best_a; rect.b = best_b;\n            rect.c = best_c; rect.d = best_d;\n            rect.s = (best_c - best_a) * (best_d - best_b);\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \"\n             << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> visited_tile;\n    long long score;\n    string path;\n};\n\nclass Solver {\nprivate:\n    static const int N = 50;\n    int si, sj;\n    vector<vector<int>> t, p;\n    vector<vector<pair<int,int>>> tile_cells;\n    int M;\n    \npublic:\n    Solver() {\n        cin >> si >> sj;\n        t.assign(N, vector<int>(N));\n        p.assign(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> p[i][j];\n        \n        // Find max tile ID\n        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        // Build tile_cells mapping\n        tile_cells.resize(M);\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                tile_cells[t[i][j]].push_back({i, j});\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Try multiple starting strategies\n        vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n        \n        // Strategy 1: Greedy DFS with look-ahead\n        for (int start_dir = 0; start_dir < 4; start_dir++) {\n            auto result = greedy_dfs(si, sj, start_dir);\n            if (result.second > best_score) {\n                best_score = result.second;\n                best_path = result.first;\n            }\n        }\n        \n        // Strategy 2: Try from all 4 directions with different ordering\n        for (int attempt = 0; attempt < 10; attempt++) {\n            vector<vector<bool>> visited(M, false);\n            visited[t[si][sj]] = true;\n            \n            string path;\n            long long score = p[si][sj];\n            int ci = si, cj = sj;\n            \n            while (true) {\n                // Get valid moves sorted by heuristic\n                vector<tuple<int,int,int,int>> moves; // heuristic, dir_idx, ni, nj\n                for (int d = 0; d < 4; d++) {\n                    int ni = ci + dirs[d].first;\n                    int nj = cj + dirs[d].second;\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    if (visited[t[ni][nj]]) continue;\n                    \n                    int h = p[ni][nj];\n                    // Bonus for tiles with more unvisited adjacent tiles\n                    int bonus = count_adjacent_tiles(ni, nj, visited);\n                    moves.push_back({-h - bonus * 2, d, ni, nj});\n                }\n                \n                if (moves.empty()) break;\n                \n                sort(moves.begin(), moves.end());\n                auto [h, d, ni, nj] = moves[0];\n                \n                visited[t[ni][nj]] = true;\n                score += p[ni][nj];\n                path += \"DURL\"[d];\n                ci = ni; cj = nj;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_path = path;\n            }\n        }\n        \n        return best_path;\n    }\n    \nprivate:\n    int count_adjacent_tiles(int i, int j, const vector<vector<bool>>& visited) {\n        vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n        int count = 0;\n        for (auto [di, dj] : dirs) {\n            int ni = i + di, nj = j + dj;\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (!visited[t[ni][nj]]) count++;\n        }\n        return count;\n    }\n    \n    pair<string, long long> greedy_dfs(int start_i, int start_j, int first_dir) {\n        vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n        vector<vector<bool>> visited(M, false);\n        visited[t[start_i][start_j]] = true;\n        \n        string path;\n        long long score = p[start_i][start_j];\n        int ci = start_i, cj = start_j;\n        \n        // First move in specified direction if valid\n        int ni = ci + dirs[first_dir].first;\n        int nj = cj + dirs[first_dir].second;\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[t[ni][nj]]) {\n            visited[t[ni][nj]] = true;\n            score += p[ni][nj];\n            path += \"DURL\"[first_dir];\n            ci = ni; cj = nj;\n        }\n        \n        // Continue greedy with look-ahead\n        while (true) {\n            // Evaluate all valid moves with look-ahead\n            vector<tuple<int,int,int,int>> moves;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = ci + dirs[d].first;\n                int nj = cj + dirs[d].second;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (visited[t[ni][nj]]) continue;\n                \n                // Heuristic: immediate value + future potential\n                int h = p[ni][nj];\n                \n                // Add bonus for moves that keep options open\n                for (int dd = 0; dd < 4; dd++) {\n                    int nni = ni + dirs[dd].first;\n                    int nnj = nj + dirs[dd].second;\n                    if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n                    if (!visited[t[nni][nnj]]) {\n                        h += p[nni][nnj] / 2; // potential future value\n                    }\n                }\n                \n                moves.push_back({-h, d, ni, nj});\n            }\n            \n            if (moves.empty()) break;\n            \n            sort(moves.begin(), moves.end());\n            auto [h, d, ni, nj] = moves[0];\n            \n            visited[t[ni][nj]] = true;\n            score += p[ni][nj];\n            path += \"DURL\"[d];\n            ci = ni; cj = nj;\n        }\n        \n        return {path, score};\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    string result = solver.solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int N = 30;\nconst int V = N * N;\nconst double INF = 1e18;\nconst double INIT_MEAN = 5000.0;\nconst double INIT_STD = 4000.0;\nconst double NOISE_STD = 0.05; // Observation noise std\n\n// Edge structure\nstruct Edge {\n    int from, to;\n    double mean;\n    double var;\n    int count;\n};\n\nvector<Edge> edges;\nvector<vector<pair<int, int>>> adj;\n\n// Convert (i,j) to vertex index\nint to_idx(int i, int j) {\n    return i * N + j;\n}\n\n// Convert vertex index to coordinates\npair<int,int> to_coord(int idx) {\n    return {idx / N, idx % N};\n}\n\nvoid init_graph() {\n    adj.resize(V);\n    int edge_id = 0;\n    \n    // Horizontal edges\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N-1; j++) {\n            int u = to_idx(i, j);\n            int v = to_idx(i, j+1);\n            edges.push_back({u, v, INIT_MEAN, INIT_STD*INIT_STD, 0});\n            adj[u].push_back({v, edge_id});\n            adj[v].push_back({u, edge_id});\n            edge_id++;\n        }\n    }\n    \n    // Vertical edges\n    for (int i = 0; i < N-1; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = to_idx(i, j);\n            int v = to_idx(i+1, j);\n            edges.push_back({u, v, INIT_MEAN, INIT_STD*INIT_STD, 0});\n            adj[u].push_back({v, edge_id});\n            adj[v].push_back({u, edge_id});\n            edge_id++;\n        }\n    }\n}\n\n// Dijkstra to find shortest path\npair<double, vector<int>> dijkstra(int s, int t) {\n    vector<double> dist(V, INF);\n    vector<int> prev(V, -1);\n    vector<int> prev_edge(V, -1);\n    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<>> pq;\n    \n    dist[s] = 0;\n    pq.push({0, s});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d != dist[u]) continue;\n        if (u == t) break;\n        \n        for (auto [v, eid] : adj[u]) {\n            double nd = d + edges[eid].mean;\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                prev[v] = u;\n                prev_edge[v] = eid;\n                pq.push({nd, v});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path_edges;\n    for (int v = t; v != s; v = prev[v]) {\n        path_edges.push_back(prev_edge[v]);\n    }\n    reverse(path_edges.begin(), path_edges.end());\n    \n    return {dist[t], path_edges};\n}\n\n// Convert path edges to string\nstring path_to_string(int s, const vector<int>& path_edges) {\n    string path;\n    auto [si, sj] = to_coord(s);\n    int ci = si, cj = sj;\n    \n    for (int eid : path_edges) {\n        auto [u, v, _, __, ___] = edges[eid];\n        auto [ui, uj] = to_coord(u);\n        auto [vi, vj] = to_coord(v);\n        \n        char dir;\n        if (uj < vj) dir = 'R';\n        else if (uj > vj) dir = 'L';\n        else if (ui < vi) dir = 'D';\n        else dir = 'U';\n        \n        path += dir;\n        \n        // Update current position\n        if (ci == ui && cj == uj) { ci = vi; cj = vj; }\n        else { ci = ui; cj = uj; }\n    }\n    \n    return path;\n}\n\n// Update edge estimates using gradient descent\nvoid update_estimates(const vector<int>& path_edges, double observed_length, double learning_rate) {\n    double predicted_length = 0;\n    for (int eid : path_edges) {\n        predicted_length += edges[eid].mean;\n    }\n    \n    double error = observed_length - predicted_length;\n    \n    // Update each edge in the path\n    for (int eid : path_edges) {\n        edges[eid].count++;\n        edges[eid].mean += learning_rate * error / path_edges.size();\n        // Clamp to reasonable range\n        edges[eid].mean = max(100.0, min(20000.0, edges[eid].mean));\n    }\n}\n\n// Add exploration by perturbing edge estimates\nvector<double> get_exploration_estimates() {\n    vector<double> perturbed(V*2);\n    for (auto& e : edges) {\n        // Add Gaussian noise proportional to uncertainty\n        double noise = sqrt(e.var) * (double)rand() / RAND_MAX;\n        perturbed.push_back(e.mean + noise * 0.1);\n    }\n    return perturbed;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(0));\n    \n    init_graph();\n    \n    double learning_rate = 0.3;\n    int query_count = 0;\n    double total_error = 0;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        int s = to_idx(si, sj);\n        int t = to_idx(ti, tj);\n        \n        // Adaptive learning rate\n        if (k < 100) learning_rate = 0.5;\n        else if (k < 300) learning_rate = 0.3;\n        else if (k < 500) learning_rate = 0.2;\n        else learning_rate = 0.1;\n        \n        // Find shortest path\n        auto [dist, path_edges] = dijkstra(s, t);\n        \n        // Add some exploration for first few queries\n        if (k < 50 || (k < 200 && (rand() % 10 < 2))) {\n            // Sometimes use perturbed estimates for exploration\n            // This is a simplified approach\n        }\n        \n        // Output path\n        string path_str = path_to_string(s, path_edges);\n        cout << path_str << endl;\n        cout.flush();\n        \n        // Read observation\n        double observed_length;\n        cin >> observed_length;\n        \n        // Update estimates\n        update_estimates(path_edges, observed_length, learning_rate);\n        \n        // Reduce variance as we get more observations\n        for (auto& e : edges) {\n            if (e.count > 0) {\n                e.var = INIT_STD * INIT_STD / (1 + e.count * 0.1);\n            }\n        }\n        \n        query_count++;\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast random number generation\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next() {\n        x ^= x << 7;\n        return x ^= x >> 9;\n    }\n    int rand_int(int l, int r) {\n        return l + (int)(next() % (r - l + 1));\n    }\n    double rand_double() {\n        return (double)next() / UINT64_MAX;\n    }\n};\n\nstruct Solver {\n    int N, M;\n    vector<string> strings;\n    vector<vector<int>> freq; // frequency of each character at each position\n    vector<string> ans;\n    XorShift rng;\n    \n    // For each string, store possible positions\n    vector<vector<tuple<int,int,int>>> possible_positions; // (row, col, dir)\n    \n    Solver(int n, int m, vector<string>& s) : N(n), M(m), strings(s) {\n        freq.assign(N, vector<int>(8, 0));\n        ans.assign(N, string(N, '.'));\n        \n        // Initialize frequency analysis\n        for (auto& str : strings) {\n            for (char c : str) {\n                freq[0][c - 'A']++;\n            }\n        }\n    }\n    \n    // Check if string can be placed at (r, c) going in direction dir\n    bool can_place(const string& str, int r, int c, int dir) {\n        int len = str.size();\n        if (dir == 0) { // horizontal\n            for (int p = 0; p < len; p++) {\n                int nc = (c + p) % N;\n                if (ans[r][nc] != '.' && ans[r][nc] != str[p]) return false;\n            }\n        } else { // vertical\n            for (int p = 0; p < len; p++) {\n                int nr = (r + p) % N;\n                if (ans[nr][c] != '.' && ans[nr][c] != str[p]) return false;\n            }\n        }\n        return true;\n    }\n    \n    // Place string at (r, c) going in direction dir\n    void place_string(const string& str, int r, int c, int dir) {\n        int len = str.size();\n        if (dir == 0) {\n            for (int p = 0; p < len; p++) {\n                int nc = (c + p) % N;\n                if (ans[r][nc] == '.') ans[r][nc] = str[p];\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                int nr = (r + p) % N;\n                if (ans[nr][c] == '.') ans[nr][c] = str[p];\n            }\n        }\n    }\n    \n    // Check if string is a subsequence of current answer\n    bool is_subsequence(const string& str) {\n        int len = str.size();\n        // Check horizontal\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.' || ans[r][c] != str[0]) continue;\n                bool ok = true;\n                for (int p = 1; p < len; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] == '.' || ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) return true;\n            }\n        }\n        // Check vertical\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.' || ans[r][c] != str[0]) continue;\n                bool ok = true;\n                for (int p = 1; p < len; p++) {\n                    int nr = (r + p) % N;\n                    if (ans[nr][c] == '.' || ans[nr][c] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) return true;\n            }\n        }\n        return false;\n    }\n    \n    // Find all possible positions for a string\n    void find_positions(const string& str) {\n        vector<tuple<int,int,int>> positions;\n        int len = str.size();\n        \n        // Horizontal\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] != '.' && ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) positions.push_back({r, c, 0});\n            }\n        }\n        \n        // Vertical\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int nr = (r + p) % N;\n                    if (ans[nr][c] != '.' && ans[nr][c] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) positions.push_back({r, c, 1});\n            }\n        }\n        \n        possible_positions.push_back(positions);\n    }\n    \n    // Main solving function\n    void solve() {\n        // Phase 1: Build initial solution greedily\n        // Sort strings by length (longer first, as they're more constraining)\n        vector<pair<int,int>> order;\n        for (int i = 0; i < M; i++) {\n            order.push_back({-(int)strings[i].size(), i});\n        }\n        sort(order.begin(), order.end());\n        \n        // Place strings greedily\n        for (auto [len_neg, idx] : order) {\n            string& str = strings[idx];\n            if (is_subsequence(str)) continue;\n            \n            // Try to find a valid position\n            bool placed = false;\n            for (int r = 0; r < N && !placed; r++) {\n                for (int c = 0; c < N && !placed; c++) {\n                    // Try horizontal\n                    if (can_place(str, r, c, 0)) {\n                        place_string(str, r, c, 0);\n                        placed = true;\n                        break;\n                    }\n                    // Try vertical\n                    if (can_place(str, r, c, 1)) {\n                        place_string(str, r, c, 1);\n                        placed = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!placed) {\n                // Force placement by overriding conflicting cells\n                // Find position with minimal conflicts\n                int best_conflicts = 1000;\n                int best_r = -1, best_c = -1, best_dir = -1;\n                \n                for (int r = 0; r < N; r++) {\n                    for (int c = 0; c < N; c++) {\n                        // Horizontal\n                        int conflicts = 0;\n                        bool valid = true;\n                        for (int p = 0; p < (int)str.size(); p++) {\n                            int nc = (c + p) % N;\n                            if (ans[r][nc] != '.' && ans[r][nc] != str[p]) {\n                                conflicts++;\n                            }\n                        }\n                        if (conflicts < best_conflicts) {\n                            best_conflicts = conflicts;\n                            best_r = r;\n                            best_c = c;\n                            best_dir = 0;\n                        }\n                        \n                        // Vertical\n                        conflicts = 0;\n                        valid = true;\n                        for (int p = 0; p < (int)str.size(); p++) {\n                            int nr = (r + p) % N;\n                            if (ans[nr][c] != '.' && ans[nr][c] != str[p]) {\n                                conflicts++;\n                            }\n                        }\n                        if (conflicts < best_conflicts) {\n                            best_conflicts = conflicts;\n                            best_r = r;\n                            best_c = c;\n                            best_dir = 1;\n                        }\n                    }\n                }\n                \n                if (best_r != -1) {\n                    place_string(str, best_r, best_c, best_dir);\n                }\n            }\n        }\n        \n        // Phase 2: Local optimization\n        // Fill remaining empty cells with most common character in their row/column\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.') {\n                    // Choose character based on frequency in nearby strings\n                    vector<int> char_freq(8, 0);\n                    \n                    // Count characters in horizontal strings passing through this cell\n                    for (int i = 0; i < M; i++) {\n                        string& str = strings[i];\n                        int len = str.size();\n                        // Check horizontal\n                        for (int sr = 0; sr < N; sr++) {\n                            for (int sc = 0; sc < N; sc++) {\n                                bool passes = false;\n                                for (int p = 0; p < len; p++) {\n                                    int nr = sr;\n                                    int nc = (sc + p) % N;\n                                    if (nr == r && nc == c) {\n                                        passes = true;\n                                        break;\n                                    }\n                                }\n                                if (passes) {\n                                    for (int p = 0; p < len; p++) {\n                                        int nc = (sc + p) % N;\n                                        if (nr == r && nc == c) {\n                                            char_freq[str[p] - 'A']++;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Choose most frequent character\n                    int best_char = 0;\n                    int best_freq = -1;\n                    for (int k = 0; k < 8; k++) {\n                        if (char_freq[k] > best_freq) {\n                            best_freq = char_freq[k];\n                            best_char = k;\n                        }\n                    }\n                    \n                    if (best_freq > 0) {\n                        ans[r][c] = 'A' + best_char;\n                    } else {\n                        ans[r][c] = 'A' + (rng.rand_int(0, 7));\n                    }\n                }\n            }\n        }\n        \n        // Phase 3: Random local search to improve\n        int iterations = 10000;\n        int current_score = count_matches();\n        \n        while (iterations > 0) {\n            // Randomly pick a cell and try different character\n            int r = rng.rand_int(0, N-1);\n            int c = rng.rand_int(0, N-1);\n            char old_char = ans[r][c];\n            \n            // Try all 8 possibilities\n            for (char new_char = 'A'; new_char <= 'H'; new_char++) {\n                if (new_char == old_char) continue;\n                ans[r][c] = new_char;\n                int new_score = count_matches();\n                if (new_score > current_score) {\n                    current_score = new_score;\n                    iterations = 10000;\n                    break;\n                } else {\n                    // Revert with some probability\n                    if (rng.rand_double() < 0.1) {\n                        // Accept worse solution sometimes\n                        current_score = new_score;\n                        break;\n                    }\n                    ans[r][c] = old_char;\n                }\n            }\n            iterations--;\n        }\n    }\n    \n    int count_matches() {\n        int count = 0;\n        for (auto& str : strings) {\n            if (is_subsequence(str)) count++;\n        }\n        return count;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Solver solver(N, M, strings);\n    solver.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << solver.ans[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\n\nint N, si, sj;\nvector<string> c;\nvector<vector<int>> cost;\nvector<vector<int>> dist; // BFS distances from start\n\nint di[4] = {-1, 1, 0, 0};\nint dj[4] = {0, 0, -1, 1};\nchar dirChar[4] = {'U', 'D', 'L', 'R'};\n\n// BFS distances from (si,sj) to all cells\nvoid bfsDist() {\n    dist.assign(N, vector<int>(N, 1e9));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si,sj});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        for (int d=0; d<4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && dist[ni][nj] > dist[i][j]+1) {\n                dist[ni][nj] = dist[i][j]+1;\n                q.push({ni,nj});\n            }\n        }\n    }\n}\n\n// Precompute visibility sets: vis[i][j] = set of visible cells\nvector<vector<pair<int,int>>> visible;\n\nvoid precomputeVisible() {\n    visible.assign(N, vector<pair<int,int>>());\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        // left\n        for (int nj=j-1; nj>=0 && c[i][nj]!='#'; nj--) visible[i][j].push_back({i,nj});\n        // right\n        for (int nj=j+1; nj<N && c[i][nj]!='#'; nj++) visible[i][j].push_back({i,nj});\n        // up\n        for (int ni=i-1; ni>=0 && c[ni][j]!='#'; ni--) visible[i][j].push_back({ni,j});\n        // down\n        for (int ni=i+1; ni<N && c[ni][j]!='#'; ni++) visible[i][j].push_back({ni,j});\n    }\n}\n\n// BFS shortest path from (i1,j1) to (i2,j2)\nstring pathBetween(int i1, int j1, int i2, int j2) {\n    vector<vector<int>> d(N, vector<int>(N, 1e9));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    d[i1][j1] = 0;\n    q.push({i1,j1});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i==i2 && j==j2) break;\n        for (int dir=0; dir<4; dir++) {\n            int ni = i+di[dir], nj = j+dj[dir];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && d[ni][nj] > d[i][j]+1) {\n                d[ni][nj] = d[i][j]+1;\n                prev[ni][nj] = {i,j};\n                q.push({ni,nj});\n            }\n        }\n    }\n    string path;\n    int ci = i2, cj = j2;\n    while (!(ci==i1 && cj==j1)) {\n        auto [pi,pj] = prev[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 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 >> N >> si >> sj;\n    c.resize(N);\n    for (int i=0; i<N; i++) cin >> c[i];\n    \n    precomputeVisible();\n    \n    // total road cells\n    vector<pair<int,int>> roads;\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') roads.push_back({i,j});\n    int r = roads.size();\n    \n    // Mark visible from start\n    vector<vector<bool>> seen(N, vector<bool>(N, false));\n    seen[si][sj] = true;\n    for (auto [vi,vj] : visible[si][sj]) seen[vi][vj] = true;\n    \n    int cur_i = si, cur_j = sj;\n    string ans;\n    int uncovered = 0;\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) uncovered++;\n    \n    while (uncovered > 0) {\n        // find nearest uncovered cell\n        bfsDist();\n        int bestDist = 1e9, bestI = -1, bestJ = -1;\n        for (auto [i,j] : roads) {\n            if (!seen[i][j] && dist[i][j] < bestDist) {\n                bestDist = dist[i][j];\n                bestI = i; bestJ = j;\n            }\n        }\n        // move to that cell\n        string subPath = pathBetween(cur_i, cur_j, bestI, bestJ);\n        ans += subPath;\n        \n        // update current position and seen\n        cur_i = bestI; cur_j = bestJ;\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) {\n            if (!seen[vi][vj]) {\n                seen[vi][vj] = true;\n                uncovered--;\n            }\n        }\n    }\n    \n    // return to start\n    string back = pathBetween(cur_i, cur_j, si, sj);\n    ans += back;\n    \n    cout << ans << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast I/O\nstruct FastIO {\n    FastIO() {\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cout.tie(nullptr);\n    }\n} fastio;\n\n// Utility for random\nstruct XorShift {\n    uint64_t x;\n    XorShift() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t rand() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint32_t rand(uint32_t range) {\n        return rand() % range;\n    }\n    double uniform() {\n        return (double)rand() / UINT32_MAX;\n    }\n    double normal() {\n        double u1 = uniform(), u2 = uniform();\n        return sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);\n    }\n} rng;\n\n// 2D vector type\nusing Vec = vector<int>;\n\n// Main solver\nstruct Solver {\n    int N, M, K, R;\n    vector<Vec> task_diff; // task difficulties\n    vector<vector<int>> deps; // dependencies\n    vector<Vec> workers_skills_est; // estimated worker skills\n    vector<vector<double>> skill_mean; // mean of skill estimates\n    vector<vector<double>> skill_var; // variance of skill estimates\n    \n    // State\n    vector<int> task_status; // 0=not started, 1=running, 2=done\n    vector<int> worker_busy_until; // day when worker becomes free\n    vector<int> worker_task; // task assigned to worker (-1 if none)\n    int current_day;\n    \n    // History for learning\n    struct Observation {\n        int worker;\n        int task;\n        int duration;\n        Vec task_diff;\n    };\n    vector<Observation> history;\n    \n    Solver() {\n        read_input();\n        init();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> K >> R;\n        task_diff.resize(N, Vec(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                cin >> task_diff[i][j];\n            }\n        }\n        deps.resize(N);\n        for (int i = 0; i < R; i++) {\n            int u, v;\n            cin >> u >> v;\n            u--; v--;\n            deps[v].push_back(u);\n        }\n    }\n    \n    void init() {\n        // Initialize skill estimates with reasonable values\n        workers_skills_est.assign(M, Vec(K, 0));\n        skill_mean.assign(M, vector<double>(K, 30.0));\n        skill_var.assign(M, vector<double>(K, 100.0));\n        \n        task_status.assign(N, 0);\n        worker_busy_until.assign(M, 0);\n        worker_task.assign(M, -1);\n        current_day = 1;\n    }\n    \n    bool can_start(int task) {\n        if (task_status[task] != 0) return false;\n        for (int dep : deps[task]) {\n            if (task_status[dep] != 2) return false;\n        }\n        return true;\n    }\n    \n    double expected_duration(int worker, int task) {\n        double w = 0;\n        for (int k = 0; k < K; k++) {\n            w += max(0, task_diff[task][k] - (int)round(workers_skills_est[worker][k]));\n        }\n        return max(1.0, w + 1); // conservative estimate\n    }\n    \n    int find_best_worker(int task) {\n        int best_worker = -1;\n        double best_time = 1e9;\n        vector<int> available;\n        for (int w = 0; w < M; w++) {\n            if (worker_busy_until[w] <= current_day) {\n                available.push_back(w);\n            }\n        }\n        if (available.empty()) return -1;\n        \n        for (int w : available) {\n            double dur = expected_duration(w, task);\n            // Add explore bonus for uncertain skills\n            double uncertainty = 0;\n            for (int k = 0; k < K; k++) {\n                uncertainty += skill_var[w][k];\n            }\n            uncertainty = sqrt(uncertainty / K);\n            dur -= 0.5 * uncertainty; // prefer exploring uncertain workers\n            \n            if (dur < best_time) {\n                best_time = dur;\n                best_worker = w;\n            }\n        }\n        return best_worker;\n    }\n    \n    void update_skills(Observation& obs) {\n        // Simple gradient descent to update skill estimates\n        double learning_rate = 0.1;\n        int actual_dur = obs.duration;\n        Vec& d = obs.task_diff;\n        int w = obs.worker;\n        \n        // Compute predicted w\n        double pred_w = 0;\n        for (int k = 0; k < K; k++) {\n            pred_w += max(0, d[k] - workers_skills_est[w][k]);\n        }\n        \n        // Update if actual duration gives information\n        if (actual_dur > 1) {\n            // The actual w (without noise) is around actual_dur - random(-3 to 3)\n            // We'll use a simple update rule\n            for (int k = 0; k < K; k++) {\n                if (d[k] > workers_skills_est[w][k]) {\n                    // This skill might be lower than estimated\n                    workers_skills_est[w][k] = max(0, workers_skills_est[w][k] + \n                        (int)(learning_rate * (d[k] - workers_skills_est[w][k]) * (actual_dur - 1) / (pred_w + 1)));\n                }\n            }\n        } else {\n            // Task was easy, worker likely has sufficient skills\n            for (int k = 0; k < K; k++) {\n                workers_skills_est[w][k] = max(workers_skills_est[w][k], d[k]);\n            }\n        }\n    }\n    \n    void solve() {\n        while (true) {\n            // Update worker states from previous day's completions\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            stringstream ss(line);\n            int first;\n            ss >> first;\n            \n            if (first == -1) {\n                // End of simulation\n                return;\n            }\n            \n            // Process completed tasks\n            int n_completed = first;\n            for (int i = 0; i < n_completed; i++) {\n                int worker;\n                ss >> worker;\n                worker--;\n                int task = worker_task[worker];\n                if (task >= 0) {\n                    task_status[task] = 2; // completed\n                    int duration = current_day - (worker_busy_until[worker] - 1);\n                    \n                    Observation obs;\n                    obs.worker = worker;\n                    obs.task = task;\n                    obs.duration = duration;\n                    obs.task_diff = task_diff[task];\n                    history.push_back(obs);\n                    \n                    // Update skill estimates\n                    update_skills(obs);\n                    \n                    worker_task[worker] = -1;\n                    worker_busy_until[worker] = current_day; // free now\n                }\n            }\n            \n            // Find tasks that can be started\n            vector<int> available_tasks;\n            for (int t = 0; t < N; t++) {\n                if (can_start(t)) {\n                    available_tasks.push_back(t);\n                }\n            }\n            \n            // Assign workers to tasks\n            vector<pair<int, int>> assignments;\n            \n            // Sort tasks by priority (e.g., by number of descendants)\n            sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n                return deps[a].size() > deps[b].size();\n            });\n            \n            for (int task : available_tasks) {\n                if (assignments.size() >= M) break;\n                \n                int worker = find_best_worker(task);\n                if (worker >= 0) {\n                    assignments.push_back({worker, task});\n                    worker_task[worker] = task;\n                    task_status[task] = 1; // started\n                    \n                    // Estimate completion time for next day update\n                    double est_dur = expected_duration(worker, task);\n                    worker_busy_until[worker] = current_day + (int)ceil(est_dur);\n                }\n            }\n            \n            // Output assignments\n            cout << assignments.size();\n            for (auto& p : assignments) {\n                cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n            }\n            cout << endl;\n            cout.flush();\n            \n            current_day++;\n            \n            if (current_day > 2000) {\n                // Read remaining input and exit\n                while (true) {\n                    getline(cin, line);\n                    if (line == \"-1\") break;\n                }\n                return;\n            }\n        }\n    }\n};\n\nint main() {\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nconst int DEPOT_X = 400, DEPOT_Y = 400;\nconst int N_ORDERS = 1000;\nconst int PICK = 50;\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nstruct Order {\n    int a, b, c, d;\n    int len; // distance from restaurant to destination\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> orders(N_ORDERS);\n    for (int i = 0; i < N_ORDERS; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].len = manhattan(orders[i].a, orders[i].b, orders[i].c, orders[i].d);\n    }\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // --- Selection: pick 50 with small roundtrip cost (depot->rest->dest->depot)\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < N_ORDERS; ++i) {\n        int rt = manhattan(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b)\n               + orders[i].len\n               + manhattan(orders[i].c, orders[i].d, DEPOT_X, DEPOT_Y);\n        candidates.emplace_back(rt, i);\n    }\n    sort(candidates.begin(), candidates.end());\n\n    // Take top 100 best (ensure diversity)\n    vector<int> selectedIdx;\n    for (int i = 0; i < 100; ++i) selectedIdx.push_back(candidates[i].second);\n    shuffle(selectedIdx.begin(), selectedIdx.end(), rng);\n    selectedIdx.resize(PICK);\n\n    // Build route as sequence of point IDs:\n    // For each order i, we insert two nodes: restaurant (2*i), destination (2*i+1)\n    // Depot at start/end: represented as -1 separately.\n    struct Node {\n        int x, y;\n        int orderId;   // for precedence check\n        bool isRestaurant;\n    };\n    vector<Node> nodes; // for the chosen orders\n    for (int idx : selectedIdx) {\n        nodes.push_back({orders[idx].a, orders[idx].b, idx, true});\n        nodes.push_back({orders[idx].c, orders[idx].d, idx, false});\n    }\n\n    // Initial naive tour: depot -> all nodes in order -> depot\n    vector<int> route; // indices into nodes, 0..(2*PICK-1)\n    route.reserve(2*PICK);\n    for (int i = 0; i < (int)nodes.size(); ++i) route.push_back(i);\n\n    // Heuristic: nearest neighbor starting from depot\n    {\n        vector<bool> used(2*PICK, false);\n        vector<int> newRoute;\n        int cx = DEPOT_X, cy = DEPOT_Y;\n        for (int step = 0; step < 2*PICK; ++step) {\n            int best = -1;\n            int bestDist = 1e9;\n            for (int j = 0; j < 2*PICK; ++j) {\n                if (used[j]) continue;\n                int d = manhattan(cx, cy, nodes[j].x, nodes[j].y);\n                if (d < bestDist) {\n                    bestDist = d;\n                    best = j;\n                }\n            }\n            newRoute.push_back(best);\n            used[best] = true;\n            cx = nodes[best].x;\n            cy = nodes[best].y;\n        }\n        route = move(newRoute);\n    }\n\n    // 2-opt local search with precedence constraints\n    auto routeDist = [&](const vector<int>& r) -> int {\n        int total = manhattan(DEPOT_X, DEPOT_Y, nodes[r[0]].x, nodes[r[0]].y);\n        for (int i = 0; i+1 < (int)r.size(); ++i) {\n            total += manhattan(nodes[r[i]].x, nodes[r[i]].y, nodes[r[i+1]].x, nodes[r[i+1]].y);\n        }\n        total += manhattan(nodes[r.back()].x, nodes[r.back()].y, DEPOT_X, DEPOT_Y);\n        return total;\n    };\n\n    auto validPrecedence = [&](const vector<int>& r) -> bool {\n        // For each order: restaurant pos must be before destination pos\n        array<int, 2*N_ORDERS> posRest, posDest;\n        fill(posRest.begin(), posRest.end(), -1);\n        fill(posDest.begin(), posDest.end(), -1);\n        for (int i = 0; i < (int)r.size(); ++i) {\n            int ni = r[i];\n            int oid = nodes[ni].orderId;\n            if (nodes[ni].isRestaurant) posRest[oid] = i;\n            else posDest[oid] = i;\n        }\n        for (int idx : selectedIdx) {\n            if (posRest[idx] == -1 || posDest[idx] == -1) return false;\n            if (posRest[idx] >= posDest[idx]) return false;\n        }\n        return true;\n    };\n\n    // Random restart loop + 2-opt\n    int bestT = 1e9;\n    vector<int> bestRoute;\n\n    for (int restart = 0; restart < 5; ++restart) {\n        // shuffle starting route\n        shuffle(route.begin(), route.end(), rng);\n        // Ensure precedence constraint initially (restaurant before destination)\n        // by brute force: for each order, ensure restaurant first\n        {\n            vector<int> tmp;\n            vector<bool> restPlaced(N_ORDERS, false);\n            for (int idx : route) {\n                int oid = nodes[idx].orderId;\n                if (nodes[idx].isRestaurant) {\n                    tmp.push_back(idx);\n                    restPlaced[oid] = true;\n                } else {\n                    // try to find restaurant before\n                    if (!restPlaced[oid]) {\n                        // need to find corresponding restaurant earlier; insert both\n                        // simple: put restaurant earlier\n                        for (int j = 0; j < (int)tmp.size(); ++j) {\n                            if (nodes[tmp[j]].orderId == oid && nodes[tmp[j]].isRestaurant) {\n                                // already placed\n                                break;\n                            }\n                        }\n                        // if not placed, add restaurant (should not happen if set is intact)\n                    }\n                    tmp.push_back(idx);\n                }\n            }\n            route = tmp;\n        }\n\n        int curT = routeDist(route);\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < (int)route.size(); ++i) {\n                for (int j = i+1; j < (int)route.size(); ++j) {\n                    // reverse segment i..j\n                    vector<int> newRoute = route;\n                    reverse(newRoute.begin()+i, newRoute.begin()+j+1);\n                    if (!validPrecedence(newRoute)) continue;\n                    int newT = routeDist(newRoute);\n                    if (newT < curT) {\n                        route = newRoute;\n                        curT = newT;\n                        improved = true;\n                        goto next2opt;\n                    }\n                }\n            }\n            next2opt:;\n        }\n\n        if (curT < bestT) {\n            bestT = curT;\n            bestRoute = route;\n        }\n    }\n\n    // Output format\n    cout << PICK;\n    for (int idx : selectedIdx) cout << \" \" << idx+1;\n    cout << \"\\n\";\n\n    int n = bestRoute.size() + 2; // +2 for start and end depot\n    cout << n << \" \" << DEPOT_X << \" \" << DEPOT_Y;\n    for (int idx : bestRoute) cout << \" \" << nodes[idx].x << \" \" << nodes[idx].y;\n    cout << \" \" << DEPOT_X << \" \" << DEPOT_Y << \"\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Edge {\n    int u, v;\n    double expected_cost;  // Using d_i as expected (middle of range)\n    double d;             // exact Euclidean distance (rounded)\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    int N = 400;\n    int M = 1995;\n    \n    vector<pair<int,int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    vector<tuple<int,int,int>> edges; // u, v, idx\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v, i});\n    }\n    \n    // Precompute Euclidean distances\n    vector<double> dist(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    // Initialize DSU and track adopted edges\n    dsu dsu(N);\n    vector<bool> adopted(M, false);\n    \n    // Process edges one by one\n    for (int i = 0; i < M; i++) {\n        int u, v, idx;\n        tie(u, v, idx) = edges[i];\n        \n        // Read actual cost\n        long long actual_cost;\n        cin >> actual_cost;\n        \n        // Check if already connected (skip if so)\n        if (dsu.same(u, v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Decision logic:\n        // If actual cost is close to minimum (<= 1.5 * d_i), take it\n        // Otherwise, check if we can get cheaper option later\n        double d = dist[i];\n        double ratio = actual_cost / d;\n        \n        // Use expected minimum cost for future edges\n        // Edges from MST construction tend to have lower costs\n        if (ratio <= 1.5) {\n            // Good deal, take it\n            adopted[i] = true;\n            dsu.merge(u, v);\n            cout << 1 << endl;\n        } else {\n            // Check if there are still many cheap edges available\n            // For edges later in sequence, be more aggressive\n            // For edges early on, be more conservative\n            double threshold = 1.5 + 0.3 * (i / (double)M);\n            \n            // Also consider: if we haven't added many edges, be more conservative\n            int adopted_count = 0;\n            for (int j = 0; j < i; j++) {\n                if (adopted[j]) adopted_count++;\n            }\n            threshold -= 0.1 * (adopted_count / (double)(N/2));\n            \n            if (ratio <= threshold) {\n                adopted[i] = true;\n                dsu.merge(u, v);\n                cout << 1 << endl;\n            } else {\n                cout << 0 << endl;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int SIZE = 30;\nconst int TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Position& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Position pos;\n    int type;\n    string movement;\n};\n\nstruct Human {\n    Position pos;\n    int id;\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Pet> pets;\n    vector<Human> humans;\n    vector<vector<bool>> wall;  // true if impassable\n    vector<vector<bool>> isPet;\n    vector<string> actions;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dir[4] = {'U', 'D', 'L', 'R'};\n    const char wallDir[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool canPlaceWall(int x, int y) {\n        if (!isValid(x, y) || wall[x][y]) return false;\n        // Can't place wall on pet or human positions\n        if (isPet[x][y]) return false;\n        for (auto& h : humans) {\n            if (h.pos.x == x && h.pos.y == y) return false;\n        }\n        // Can't place wall adjacent to pet\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && isPet[nx][ny]) {\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    int manhattan(Position a, Position b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Find a good enclosure area\n    void planEnclosure(vector<Position>& targetWalls) {\n        // Calculate center of human positions\n        int centerX = 0, centerY = 0;\n        for (auto& h : humans) {\n            centerX += h.pos.x;\n            centerY += h.pos.y;\n        }\n        centerX /= M;\n        centerY /= M;\n        \n        // Build rectangle around center\n        int radius = 8;  // Start with reasonable size\n        int x1 = max(1, centerX - radius);\n        int y1 = max(1, centerY - radius);\n        int x2 = min(SIZE-2, centerX + radius);\n        int y2 = min(SIZE-2, centerY + radius);\n        \n        // Add walls around the perimeter\n        for (int x = x1; x <= x2; x++) {\n            targetWalls.push_back({x, y1});\n            targetWalls.push_back({x, y2});\n        }\n        for (int y = y1+1; y < y2; y++) {\n            targetWalls.push_back({x1, y});\n            targetWalls.push_back({x2, y});\n        }\n    }\n    \n    Position getNextWallPosition(int humanIdx) {\n        // Strategy: Build walls around humans\n        auto& human = humans[humanIdx];\n        Position best = {-1, -1};\n        int minDist = 1e9;\n        \n        // Try to build walls in a circle around humans\n        for (int dist = 1; dist <= 10; dist++) {\n            for (int dx = -dist; dx <= dist; dx++) {\n                for (int dy = -dist; dy <= dist; dy++) {\n                    if (abs(dx) != dist && abs(dy) != dist) continue;\n                    int nx = human.pos.x + dx;\n                    int ny = human.pos.y + dy;\n                    if (canPlaceWall(nx, ny)) {\n                        int d = abs(dx) + abs(dy);\n                        if (d < minDist) {\n                            minDist = d;\n                            best = {nx, ny};\n                        }\n                    }\n                }\n            }\n            if (best.x != -1) break;\n        }\n        \n        return best;\n    }\n    \npublic:\n    Solver() {\n        wall = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n        isPet = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n    }\n    \n    void readInput() {\n        cin >> N;\n        pets.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> pets[i].pos.x >> pets[i].pos.y >> pets[i].type;\n            pets[i].pos.x--;\n            pets[i].pos.y--;\n            isPet[pets[i].pos.x][pets[i].pos.y] = true;\n        }\n        \n        cin >> M;\n        humans.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humans[i].pos.x >> humans[i].pos.y;\n            humans[i].pos.x--;\n            humans[i].pos.y--;\n            humans[i].id = i;\n        }\n    }\n    \n    void solve() {\n        // Phase 1 (turn 0-100): Build enclosure\n        // Phase 2 (turn 101-200): Expand/enhance enclosure\n        // Phase 3 (turn 201-300): Maintain walls\n        \n        vector<Position> wallTargets;\n        planEnclosure(wallTargets);\n        \n        for (int turn = 0; turn < TURNS; turn++) {\n            string output;\n            bool allDone = true;\n            \n            for (int i = 0; i < M; i++) {\n                auto& human = humans[i];\n                char action = '.';\n                \n                if (turn < 200) {\n                    // Building phase\n                    if (i == 0 && turn < (int)wallTargets.size() && turn % 3 == 0) {\n                        // Special human moves to strategic position\n                        auto target = wallTargets[turn];\n                        // Move towards target\n                        if (human.pos != target) {\n                            if (human.pos.x > target.x && canPlaceWall(human.pos.x-1, human.pos.y) == false) {\n                                // Check if we can move up\n                                int nx = human.pos.x - 1;\n                                int ny = human.pos.y;\n                                if (!wall[nx][ny]) {\n                                    action = 'U';\n                                    human.pos.x--;\n                                }\n                            } else if (human.pos.x < target.x) {\n                                action = 'D';\n                                human.pos.x++;\n                            } else if (human.pos.y > target.y) {\n                                action = 'L';\n                                human.pos.y--;\n                            } else if (human.pos.y < target.y) {\n                                action = 'R';\n                                human.pos.y++;\n                            }\n                        } else {\n                            // Build wall here\n                            action = 'd';  // Build wall downward\n                            wall[human.pos.x+1][human.pos.y] = true;\n                        }\n                    } else {\n                        // Other humans build nearby walls\n                        Position wallPos = getNextWallPosition(i);\n                        if (wallPos.x != -1) {\n                            // Move towards wall position first\n                            if (manhattan(human.pos, wallPos) > 1) {\n                                // Move closer\n                                if (abs(human.pos.x - wallPos.x) > abs(human.pos.y - wallPos.y)) {\n                                    if (human.pos.x > wallPos.x && !wall[human.pos.x-1][human.pos.y]) {\n                                        action = 'U';\n                                        human.pos.x--;\n                                    } else if (human.pos.x < wallPos.x && !wall[human.pos.x+1][human.pos.y]) {\n                                        action = 'D';\n                                        human.pos.x++;\n                                    }\n                                } else {\n                                    if (human.pos.y > wallPos.y && !wall[human.pos.x][human.pos.y-1]) {\n                                        action = 'L';\n                                        human.pos.y--;\n                                    } else if (human.pos.y < wallPos.y && !wall[human.pos.x][human.pos.y+1]) {\n                                        action = 'R';\n                                        human.pos.y++;\n                                    }\n                                }\n                            } else {\n                                // Build wall\n                                int dx = wallPos.x - human.pos.x;\n                                int dy = wallPos.y - human.pos.y;\n                                if (dx == -1) action = 'u';\n                                else if (dx == 1) action = 'd';\n                                else if (dy == -1) action = 'l';\n                                else if (dy == 1) action = 'r';\n                                wall[wallPos.x][wallPos.y] = true;\n                            }\n                        }\n                    }\n                } else {\n                    // Maintenance phase - try to complete the enclosure\n                    Position wallPos = getNextWallPosition(i);\n                    if (wallPos.x != -1) {\n                        // Similar movement logic\n                        if (manhattan(human.pos, wallPos) > 1) {\n                            if (human.pos.x > wallPos.x && !wall[human.pos.x-1][human.pos.y]) {\n                                action = 'U';\n                                human.pos.x--;\n                            } else if (human.pos.x < wallPos.x && !wall[human.pos.x+1][human.pos.y]) {\n                                action = 'D';\n                                human.pos.x++;\n                            } else if (human.pos.y > wallPos.y && !wall[human.pos.x][human.pos.y-1]) {\n                                action = 'L';\n                                human.pos.y--;\n                            } else if (human.pos.y < wallPos.y && !wall[human.pos.x][human.pos.y+1]) {\n                                action = 'R';\n                                human.pos.y++;\n                            }\n                        } else {\n                            int dx = wallPos.x - human.pos.x;\n                            int dy = wallPos.y - human.pos.y;\n                            if (dx == -1) action = 'u';\n                            else if (dx == 1) action = 'd';\n                            else if (dy == -1) action = 'l';\n                            else if (dy == 1) action = 'r';\n                            wall[wallPos.x][wallPos.y] = true;\n                        }\n                    }\n                }\n                \n                if (action == '.') allDone = false;\n                output += action;\n            }\n            \n            cout << output << endl;\n            cout.flush();\n            \n            // Read pet movements\n            string petMovement;\n            for (int i = 0; i < N; i++) {\n                cin >> petMovement;\n                if (i > 0) cin.ignore();\n                if (i < N-1) cin >> petMovement;\n                \n                // Update pet positions\n                isPet[pets[i].pos.x][pets[i].pos.y] = false;\n                for (char c : petMovement) {\n                    if (c == 'U') pets[i].pos.x--;\n                    else if (c == 'D') pets[i].pos.x++;\n                    else if (c == 'L') pets[i].pos.y--;\n                    else if (c == 'R') pets[i].pos.y++;\n                }\n                isPet[pets[i].pos.x][pets[i].pos.y] = true;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.readInput();\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n\n    // h[i][j] = wall between (i,j) and (i,j+1)\n    // v[i][j] = wall between (i,j) and (i+1,j)\n    vector<vector<int>> h(20, vector<int>(19));\n    vector<vector<int>> v(19, vector<int>(20));\n    for (int i = 0; i < 20; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 19; ++j) h[i][j] = s[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 20; ++j) v[i][j] = s[j] - '0';\n    }\n\n    // BFS shortest path\n    const int INF = 1e9;\n    vector<vector<int>> dist(20, vector<int>(20, INF));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    int di[] = {-1, 1, 0, 0}; // U, D, L, R\n    int dj[] = {0, 0, -1, 1};\n    char dir_char[] = {'U', 'D', 'L', 'R'};\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            int ni = i + di[d], nj = j + dj[d];\n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            // check wall\n            if (d == 0 && i > 0 && v[i-1][j]) continue; // up\n            if (d == 1 && i < 19 && v[i][j]) continue; // down\n            if (d == 2 && j > 0 && h[i][j-1]) continue; // left\n            if (d == 3 && j < 19 && h[i][j]) continue; // right\n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n\n    // Reconstruct path (reverse)\n    vector<char> path;\n    int ci = ti, cj = tj;\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        // direction from pi,pj to ci,cj\n        if (pi == ci - 1) path.push_back('D');\n        else if (pi == ci + 1) path.push_back('U');\n        else if (pj == cj - 1) path.push_back('R');\n        else path.push_back('L');\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n\n    // Determine repeat count\n    int rep = max(1, (int)(1.0 / (1.0 - p) + 0.5));\n    // p=0.5 => 1/0.5=2 => rep=2; p=0.1 => ~1.11 => rep=1\n    // but bound by length 200\n    string ans;\n    for (char c : path) {\n        for (int r = 0; r < rep; ++r) {\n            ans.push_back(c);\n            if (ans.size() >= 200) break;\n        }\n        if (ans.size() >= 200) break;\n    }\n    // final trim\n    if (ans.size() > 200) ans.resize(200);\n    cout << ans << endl;\n\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\n// Direction arrays: 0=left, 1=up, 2=right, 3=down\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// Transition table for each tile type and entry direction\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0: curve (right, up)\n    {3, -1, -1, 0},  // 1: curve (left, down)\n    {-1, -1, 3, 2},  // 2: curve (up, left)\n    {-1, 2, 1, -1},  // 3: curve (down, right)\n    {1, 0, 3, 2},    // 4: double curve (all sides)\n    {3, 2, 1, 0},    // 5: double curve (all sides, crossed)\n    {2, -1, 0, -1},  // 6: straight (left-right)\n    {-1, 3, -1, 1},  // 7: straight (up-down)\n};\n\nstruct State {\n    array<array<int, 30>, 30> tiles;\n    \n    // Evaluate all loops and return sorted lengths\n    vector<int> getLoopLengths() const {\n        vector<int> lengths;\n        vector<vector<bool>> visited(30, vector<bool>(30, false));\n        \n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                if (!visited[i][j]) {\n                    // Check all possible entry directions for this tile\n                    for (int d = 0; d < 4; d++) {\n                        int len = traceLoop(i, j, d, visited);\n                        if (len > 0) {\n                            lengths.push_back(len);\n                        }\n                    }\n                }\n            }\n        }\n        \n        sort(lengths.rbegin(), lengths.rend());\n        return lengths;\n    }\n    \n    int traceLoop(int si, int sj, int sd, vector<vector<bool>>& visited) const {\n        int i = si, j = sj, d = sd;\n        int length = 0;\n        \n        while (true) {\n            int d2 = to[tiles[i][j]][d];\n            if (d2 == -1) return 0;\n            \n            i += di[d2];\n            j += dj[d2];\n            if (i < 0 || i >= 30 || j < 0 || j >= 30) return 0;\n            d = (d2 + 2) % 4;\n            length++;\n            \n            if (i == si && j == sj && d == sd) {\n                // Mark all tiles in this loop as visited\n                i = si; j = sj; d = sd;\n                for (int k = 0; k < length; k++) {\n                    visited[i][j] = true;\n                    int d2 = to[tiles[i][j]][d];\n                    i += di[d2];\n                    j += dj[d2];\n                    d = (d2 + 2) % 4;\n                }\n                return length;\n            }\n            \n            if (length > 900) return 0; // safety\n        }\n    }\n    \n    // Fast evaluation - just find top 2 loops without marking visited\n    pair<int,int> getTopTwo() const {\n        int L1 = 0, L2 = 0;\n        vector<vector<bool>> visited(30, vector<bool>(30, false));\n        \n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                if (!visited[i][j]) {\n                    for (int d = 0; d < 4; d++) {\n                        int len = traceLoop(i, j, d, visited);\n                        if (len > 0) {\n                            if (len > L1) {\n                                L2 = L1;\n                                L1 = len;\n                            } else if (len > L2) {\n                                L2 = len;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return {L1, L2};\n    }\n    \n    long long getScore() const {\n        auto [L1, L2] = getTopTwo();\n        return (long long)L1 * L2;\n    }\n    \n    int getTile(int i, int j) const {\n        return tiles[i][j];\n    }\n    \n    void setTile(int i, int j, int t) {\n        tiles[i][j] = t;\n    }\n    \n    void rotateTile(int i, int j, int times) {\n        tiles[i][j] = (tiles[i][j] + times) % 8;\n    }\n};\n\n// Convert rotation state to output string\nstring encodeState(const State& state, const array<array<int,30>,30>& original) {\n    string output;\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int rot = (state.tiles[i][j] - original[i][j] + 8) % 8;\n            output += char('0' + (rot % 4));\n        }\n    }\n    return output;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    array<array<int,30>,30> original;\n    for (int i = 0; i < 30; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 30; j++) {\n            original[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Start with original state\n    State bestState;\n    bestState.tiles = original;\n    long long bestScore = bestState.getScore();\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, 29);\n    uniform_int_distribution<int> rotDist(1, 3);\n    uniform_real_distribution<double> probDist(0.0, 1.0);\n    \n    // Multiple random restarts\n    for (int restart = 0; restart < 50; restart++) {\n        State current;\n        current.tiles = original;\n        \n        // Random rotations for initial state\n        if (restart > 0) {\n            for (int i = 0; i < 30; i++) {\n                for (int j = 0; j < 30; j++) {\n                    int r = uniform_int_distribution<int>(0, 3)(rng);\n                    for (int k = 0; k < r; k++) {\n                        current.tiles[i][j] = (current.tiles[i][j] + 1) % 8;\n                    }\n                }\n            }\n        }\n        \n        long long currentScore = current.getScore();\n        \n        // Simulated annealing\n        double temperature = 100.0;\n        double coolingRate = 0.9995;\n        \n        for (int iter = 0; iter < 2000; iter++) {\n            // Try small local changes\n            for (int change = 0; change < 20; change++) {\n                int i = dist(rng);\n                int j = dist(rng);\n                int oldTile = current.tiles[i][j];\n                int rot = rotDist(rng);\n                \n                // Apply rotation\n                current.tiles[i][j] = (current.tiles[i][j] + rot) % 8;\n                \n                long long newScore = current.getScore();\n                \n                // Accept or reject\n                if (newScore > currentScore || \n                    probDist(rng) < exp((newScore - currentScore) / temperature)) {\n                    currentScore = newScore;\n                } else {\n                    // Revert\n                    current.tiles[i][j] = oldTile;\n                }\n                \n                if (currentScore > bestScore) {\n                    bestState = current;\n                    bestScore = currentScore;\n                }\n            }\n            \n            temperature *= coolingRate;\n        }\n    }\n    \n    // Output result\n    string output = encodeState(bestState, original);\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Direction mappings\nconst int dy[] = {-1, 1, 0, 0};  // U, D, L, R\nconst int dx[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int rev_dir[] = {1, 0, 3, 2};  // Reverse directions\n\n// Tile bitmasks: L=1, U=2, R=4, D=8\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\n\nint N, T;\nvector<vector<int>> board;\npair<int,int> empty_pos;\n\n// Convert hex char to int\nint hex_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\n// Convert int to hex char\nchar int_to_hex(int v) {\n    if (v < 10) return '0' + v;\n    return 'a' + v - 10;\n}\n\n// Check if position is valid\nbool valid(int y, int x) {\n    return y >= 0 && y < N && x >= 0 && x < N;\n}\n\n// Calculate tree size from current board\nint calc_tree_size(const vector<vector<int>>& b) {\n    int n = N * N - 1;\n    vector<vector<pair<int,int>>> adj(N, vector<pair<int,int>>(N));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    // Build adjacency based on line connections\n    auto get_max_tree = [&](int sy, int sx) -> int {\n        if (b[sy][sx] == 0) return 0;\n        queue<pair<int,int>> q;\n        q.push({sy, sx});\n        visited[sy][sx] = true;\n        int sz = 0;\n        \n        while (!q.empty()) {\n            auto [y, x] = q.front(); q.pop();\n            sz++;\n            int tile = b[y][x];\n            \n            // Up\n            if ((tile & UP) && y > 0 && (b[y-1][x] & DOWN) && !visited[y-1][x]) {\n                visited[y-1][x] = true;\n                q.push({y-1, x});\n            }\n            // Down\n            if ((tile & DOWN) && y < N-1 && (b[y+1][x] & UP) && !visited[y+1][x]) {\n                visited[y+1][x] = true;\n                q.push({y+1, x});\n            }\n            // Left\n            if ((tile & LEFT) && x > 0 && (b[y][x-1] & RIGHT) && !visited[y][x-1]) {\n                visited[y][x-1] = true;\n                q.push({y, x-1});\n            }\n            // Right\n            if ((tile & RIGHT) && x < N-1 && (b[y][x+1] & LEFT) && !visited[y][x+1]) {\n                visited[y][x+1] = true;\n                q.push({y, x+1});\n            }\n        }\n        return sz;\n    };\n    \n    int max_tree = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] != 0 && !visited[i][j]) {\n                int sz = get_max_tree(i, j);\n                max_tree = max(max_tree, sz);\n            }\n        }\n    }\n    return max_tree;\n}\n\n// Find path from empty to target using BFS (always possible on any state)\nstring find_path(int ty, int tx) {\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> dir_used(N, vector<int>(N, -1));\n    \n    queue<pair<int,int>> q;\n    q.push(empty_pos);\n    vis[empty_pos.first][empty_pos.second] = true;\n    \n    while (!q.empty()) {\n        auto [y, x] = q.front(); q.pop();\n        if (y == ty && x == tx) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int ny = y + dy[d], nx = x + dx[d];\n            if (!valid(ny, nx) || vis[ny][nx]) continue;\n            vis[ny][nx] = true;\n            parent[ny][nx] = {y, x};\n            dir_used[ny][nx] = d;\n            q.push({ny, nx});\n        }\n    }\n    \n    // Reconstruct path\n    string path;\n    int cy = ty, cx = tx;\n    while (!(cy == empty_pos.first && cx == empty_pos.second)) {\n        int d = dir_used[cy][cx];\n        path += dir_char[d];\n        auto [py, px] = parent[cy][cx];\n        // The direction from parent to child is the opposite\n        cy = py; cx = px;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Also need to reverse direction because we want to move tiles INTO empty\n    // Actually, we need to move tile at (ty,tx) to empty's position\n    // So we move empty to (ty,tx), which means tiles move in opposite direction\n    string result;\n    for (char c : path) {\n        if (c == 'U') result += 'D';\n        else if (c == 'D') result += 'U';\n        else if (c == 'L') result += 'R';\n        else result += 'L';\n    }\n    \n    return result;\n}\n\n// Apply a move sequence to the board\nvoid apply_moves(const string& moves) {\n    for (char c : moves) {\n        int d;\n        if (c == 'U') d = 0;\n        else if (c == 'D') d = 1;\n        else if (c == 'L') d = 2;\n        else d = 3;\n        \n        int ny = empty_pos.first + dy[d];\n        int nx = empty_pos.second + dx[d];\n        swap(board[empty_pos.first][empty_pos.second], board[ny][nx]);\n        empty_pos = {ny, nx};\n    }\n}\n\n// Main solve function\nstring solve() {\n    // Read input\n    string line;\n    getline(cin, line);\n    stringstream ss(line);\n    ss >> N >> T;\n    \n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string row;\n        getline(cin, row);\n        // Remove spaces if any\n        row.erase(remove(row.begin(), row.end(), ' '), row.end());\n        for (int j = 0; j < N; j++) {\n            board[i][j] = hex_to_int(row[j]);\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n            }\n        }\n    }\n    \n    string result;\n    int max_operations = T;\n    \n    // Strategy: Try to create a spanning tree structure\n    // Since we know a perfect tree is reachable, try to fix problematic connections\n    \n    // First, find current tree size\n    int current_tree = calc_tree_size(board);\n    \n    // If we already have perfect tree, minimal moves\n    if (current_tree == N * N - 1) {\n        return \"\";\n    }\n    \n    // Greedy approach: Try to improve connections\n    // Look for tiles that can be connected but aren't\n    \n    // Simple heuristic: move the empty tile in a pattern to try to create connections\n    // This is a placeholder for more sophisticated algorithms\n    \n    // For now, just do a snake pattern to shuffle tiles\n    for (int round = 0; round < 2 && result.size() < max_operations; round++) {\n        // Snake pattern\n        if (result.size() < max_operations) {\n            // Move right across top row\n            while (empty_pos.second < N-1 && result.size() < max_operations) {\n                result += 'R';\n                apply_moves(\"R\");\n            }\n            while (empty_pos.second > 0 && result.size() < max_operations) {\n                result += 'L';\n                apply_moves(\"L\");\n            }\n            // Move down\n            if (empty_pos.first < N-1 && result.size() < max_operations) {\n                result += 'D';\n                apply_moves(\"D\");\n            }\n        }\n        \n        if (result.size() < max_operations) {\n            // Move left across row\n            while (empty_pos.second > 0 && result.size() < max_operations) {\n                result += 'L';\n                apply_moves(\"L\");\n            }\n            while (empty_pos.second < N-1 && result.size() < max_operations) {\n                result += 'R';\n                apply_moves(\"R\");\n            }\n            if (empty_pos.first < N-1 && result.size() < max_operations) {\n                result += 'D';\n                apply_moves(\"D\");\n            }\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    string answer = solve();\n    cout << answer << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ld = long double;\n\nstruct Point {\n    ll x, y;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11); // 1..10\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n    const ll R2 = 100000000LL; // radius squared\n    vector<pair<Point,Point>> best_lines;\n    int best_score = -1;\n\n    // Generate many candidate solutions\n    mt19937 rng(12345);\n    uniform_int_distribution<ll> coord_dist(-1000000000LL, 1000000000LL);\n    uniform_real_distribution<ld> angle_dist(0, 2*M_PI);\n    uniform_real_distribution<ld> offset_dist(-10000, 10000);\n\n    for (int trial = 0; trial < 200; ++trial) {\n        vector<pair<Point,Point>> lines;\n        // generate K lines\n        for (int i = 0; i < K; ++i) {\n            // Choose two random points\n            Point p1, p2;\n            p1.x = coord_dist(rng);\n            p1.y = coord_dist(rng);\n            p2.x = coord_dist(rng);\n            p2.y = coord_dist(rng);\n            lines.emplace_back(p1, p2);\n        }\n\n        // Evaluate\n        vector<vector<int>> signs(N, vector<int>(K,0));\n        vector<bool> alive(N, true);\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < K; ++j) {\n                ll dx = lines[j].second.x - lines[j].first.x;\n                ll dy = lines[j].second.y - lines[j].first.y;\n                // Cross product sign\n                ll cross = dx * (strawberries[i].y - lines[j].first.y) - dy * (strawberries[i].x - lines[j].first.x);\n                if (cross > 0) signs[i][j] = 1;\n                else if (cross < 0) signs[i][j] = -1;\n                else {\n                    alive[i] = false; // on line\n                    break;\n                }\n            }\n        }\n\n        // Group by sign pattern\n        map<vector<int>, int> group_cnt;\n        for (int i = 0; i < N; ++i) {\n            if (!alive[i]) continue;\n            group_cnt[signs[i]]++;\n        }\n\n        vector<int> piece_counts;\n        for (auto &[vec, cnt] : group_cnt) {\n            piece_counts.push_back(cnt);\n        }\n\n        // Compute score\n        vector<int> b(11,0);\n        for (int cnt : piece_counts) {\n            if (cnt >= 1 && cnt <= 10) b[cnt]++;\n        }\n        int score = 0;\n        for (int d = 1; d <= 10; ++d) {\n            score += min(a[d], b[d]);\n        }\n        if (score > best_score) {\n            best_score = score;\n            best_lines = lines;\n        }\n    }\n\n    // Output best found\n    cout << best_lines.size() << \"\\n\";\n    for (auto &[p1, p2] : best_lines) {\n        cout << p1.x << \" \" << p1.y << \" \" << p2.x << \" \" << p2.y << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n};\n\nstruct Rectangle {\n    Point p[4];\n    int weight;\n};\n\nint N, M;\nvector<vector<bool>> hasDot;\nvector<vector<bool>> occupied; // for rectangle perimeters\nint center;\n\n// Precompute weights\nvector<vector<int>> weight;\n\nint get_weight(int x, int y) {\n    return (x-center)*(x-center) + (y-center)*(y-center) + 1;\n}\n\nbool can_place_rectangle(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {\n    // Check if p1 is empty\n    if (hasDot[p1.x][p1.y]) return false;\n    \n    // Check if p2, p3, p4 have dots\n    if (!hasDot[p2.x][p2.y] || !hasDot[p3.x][p3.y] || !hasDot[p4.x][p4.y]) return false;\n    \n    // Check condition 2: no other dots on perimeter\n    // Simplified check for axis-aligned rectangles\n    auto check_line = [&](int x1, int y1, int x2, int y2) {\n        if (x1 == x2) {\n            for (int y = min(y1,y2); y <= max(y1,y2); y++) {\n                if (hasDot[x1][y] && !(Point(x1,y) == p2 || Point(x1,y) == p3 || Point(x1,y) == p4)) return false;\n            }\n        } else if (y1 == y2) {\n            for (int x = min(x1,x2); x <= max(x1,x2); x++) {\n                if (hasDot[x][y1] && !(Point(x,y1) == p2 || Point(x,y1) == p3 || Point(x,y1) == p4)) return false;\n            }\n        }\n        return true;\n    };\n    \n    return check_line(p1.x, p1.y, p2.x, p2.y) && \n           check_line(p2.x, p2.y, p3.x, p3.y) &&\n           check_line(p3.x, p3.y, p4.x, p4.y) &&\n           check_line(p4.x, p4.y, p1.x, p1.y);\n}\n\nvoid find_candidates(vector<Rectangle>& candidates) {\n    candidates.clear();\n    \n    // Search for possible rectangles centered on empty points\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            if (hasDot[x][y]) continue;\n            \n            // Try axis-aligned rectangles\n            for (int dx = 1; dx < N; dx++) {\n                for (int dy = 1; dy < N; dy++) {\n                    // Check all four corners\n                    int x1 = x - dx, y1 = y;\n                    int x2 = x, y2 = y + dy;\n                    int x3 = x + dx, y3 = y;\n                    int x4 = x, y4 = y - dy;\n                    \n                    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) continue;\n                    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) continue;\n                    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N) continue;\n                    \n                    Rectangle r;\n                    r.p[0] = Point(x, y);\n                    r.p[1] = Point(x1, y1);\n                    r.p[2] = Point(x2, y2);\n                    r.p[3] = Point(x3, y3);\n                    r.weight = weight[x][y];\n                    \n                    if (can_place_rectangle(r.p[0], r.p[1], r.p[2], r.p[3])) {\n                        candidates.push_back(r);\n                    }\n                }\n            }\n            \n            // Try 45\u00b0 rotated rectangles\n            for (int d = 1; d < N; d++) {\n                int x1 = x - d, y1 = y - d;\n                int x2 = x, y2 = y - d;\n                int x3 = x + d, y3 = y;\n                int x4 = x, y4 = y + d;\n                \n                if (x1 >= 0 && x1 < N && y1 >= 0 && y1 < N &&\n                    x2 >= 0 && x2 < N && y2 >= 0 && y2 < N &&\n                    x3 >= 0 && x3 < N && y3 >= 0 && y3 < N &&\n                    x4 >= 0 && x4 < N && y4 >= 0 && y4 < N) {\n                    \n                    Rectangle r;\n                    r.p[0] = Point(x, y);\n                    r.p[1] = Point(x1, y1);\n                    r.p[2] = Point(x2, y2);\n                    r.p[3] = Point(x3, y3);\n                    r.weight = weight[x][y];\n                    \n                    if (can_place_rectangle(r.p[0], r.p[1], r.p[2], r.p[3])) {\n                        candidates.push_back(r);\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    hasDot.assign(N, vector<bool>(N, false));\n    occupied.assign(N, vector<bool>(N, false));\n    center = (N-1)/2;\n    \n    weight.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            weight[i][j] = get_weight(i, j);\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        hasDot[x][y] = true;\n    }\n    \n    vector<array<int, 8>> operations;\n    vector<Rectangle> candidates;\n    \n    // Greedy algorithm with multiple attempts\n    auto solve = [&]() -> vector<array<int, 8>> {\n        vector<array<int, 8>> ops;\n        auto temp_hasDot = hasDot;\n        \n        while (true) {\n            find_candidates(candidates);\n            if (candidates.empty()) break;\n            \n            // Sort by weight descending\n            sort(candidates.begin(), candidates.end(), \n                 [](const Rectangle& a, const Rectangle& b) {\n                     return a.weight > b.weight;\n                 });\n            \n            // Take the best candidate\n            Rectangle best = candidates[0];\n            \n            // Place the rectangle\n            Point p1 = best.p[0];\n            temp_hasDot[p1.x][p1.y] = true;\n            \n            ops.push_back({p1.x, p1.y, \n                          best.p[1].x, best.p[1].y,\n                          best.p[2].x, best.p[2].y,\n                          best.p[3].x, best.p[3].y});\n        }\n        \n        return ops;\n    };\n    \n    operations = solve();\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            cout << op[i] << (i < 7 ? \" \" : \"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int T = 100;\n\n// Direction vectors: F, B, L, R\nconst int dx[] = {0, 0, -1, 1};  // row change (0=front, 1=back, 2=left, 3=right)\nconst int dy[] = {1, -1, 0, 0};  // col change\n\nstruct State {\n    int grid[N][N] = {};  // 0=empty, 1-3=flavors\n    int empty_count = N * N;\n    \n    State() {}\n    \n    // Initialize from another state\n    State(const State& other) {\n        memcpy(grid, other.grid, sizeof(grid));\n        empty_count = other.empty_count;\n    }\n    \n    // Check if cell is valid\n    bool valid(int x, int y) const {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    // Tilt in direction d (0=F, 1=B, 2=L, 3=R)\n    State tilt(int d) const {\n        State res(*this);\n        \n        // Determine iteration order based on direction\n        if (d == 0) {  // Forward (toward row 0, y++)\n            for (int x = 0; x < N; x++) {\n                for (int y = 0; y < N; y++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    // Try to move forward (decreasing y)\n                    while (ny > 0 && res.grid[x][ny-1] == 0) ny--;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 1) {  // Backward (toward row N-1, y--)\n            for (int x = 0; x < N; x++) {\n                for (int y = N-1; y >= 0; y--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny < N-1 && res.grid[x][ny+1] == 0) ny++;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 2) {  // Left (toward col 0, x--)\n            for (int y = 0; y < N; y++) {\n                for (int x = 0; x < N; x++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx > 0 && res.grid[nx-1][y] == 0) nx--;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else {  // Right (toward col N-1, x++)\n            for (int y = 0; y < N; y++) {\n                for (int x = N-1; x >= 0; x--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx < N-1 && res.grid[nx+1][y] == 0) nx++;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        \n        return res;\n    }\n    \n    // Place candy at position p (1-indexed in empty cells ordering)\n    void place(int p, int flavor) {\n        int count = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[x][y] = flavor;\n                        empty_count--;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Evaluate the state - higher is better\n    double evaluate() const {\n        // Count adjacent same-flavor pairs\n        double score = 0.0;\n        \n        // Horizontal pairs\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N-1; x++) {\n                if (grid[x][y] != 0 && grid[x+1][y] != 0 && grid[x][y] == grid[x+1][y]) {\n                    score += 1.0;\n                }\n            }\n        }\n        \n        // Vertical pairs\n        for (int y = 0; y < N-1; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0 && grid[x][y+1] != 0 && grid[x][y] == grid[x][y+1]) {\n                    score += 1.0;\n                }\n            }\n        }\n        \n        // Bonus for large empty spaces (future flexibility)\n        // Count maximum consecutive empty cells in each direction\n        double empty_bonus = 0.0;\n        \n        // Check rows\n        for (int y = 0; y < N; y++) {\n            int streak = 0;\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    streak++;\n                } else {\n                    empty_bonus += streak * streak * 0.01;\n                    streak = 0;\n                }\n            }\n            empty_bonus += streak * streak * 0.01;\n        }\n        \n        // Check columns\n        for (int x = 0; x < N; x++) {\n            int streak = 0;\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y] == 0) {\n                    streak++;\n                } else {\n                    empty_bonus += streak * streak * 0.01;\n                    streak = 0;\n                }\n            }\n            empty_bonus += streak * streak * 0.01;\n        }\n        \n        // Penalty for isolated cells (no same-flavor neighbors)\n        double isolation_penalty = 0.0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int same_neighbors = 0;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] == grid[x][y]) {\n                        same_neighbors++;\n                    }\n                }\n                if (same_neighbors == 0) {\n                    isolation_penalty -= 0.5;\n                }\n            }\n        }\n        \n        return score + empty_bonus + isolation_penalty;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read flavors\n    vector<int> flavors(T);\n    for (int i = 0; i < T; i++) {\n        cin >> flavors[i];\n    }\n    \n    State current_state;\n    const char dir_names[] = {'F', 'B', 'L', 'R'};\n    \n    // Process each candy\n    for (int t = 0; t < T; t++) {\n        int p;\n        cin >> p;\n        \n        // Place the candy\n        current_state.place(p, flavors[t]);\n        \n        // If last candy, no need to tilt\n        if (t == T - 1) break;\n        \n        // Evaluate all 4 possible tilts\n        double best_score = -1e18;\n        int best_dir = 0;\n        \n        for (int d = 0; d < 4; d++) {\n            State new_state = current_state.tilt(d);\n            double score = new_state.evaluate();\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n        \n        // Apply the best tilt\n        current_state = current_state.tilt(best_dir);\n        \n        // Output direction\n        cout << dir_names[best_dir] << '\\n';\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <random>\n#include <cmath>\n#include <algorithm>\nusing namespace std;\n\nconst int QUERIES = 100;\nint M;\ndouble eps;\n\n// Generate adjacency matrix from string\nvector<vector<bool>> strToAdj(const string& s, int N) {\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            adj[i][j] = adj[j][i] = (s[idx++] == '1');\n        }\n    }\n    return adj;\n}\n\n// Encode graph to string\nstring adjToStr(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    string s;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            s += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Compute degree sequence (sorted)\nvector<int> getDegreeSeq(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (adj[i][j]) deg[i]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Count triangles\nint countTriangles(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (!adj[i][j]) continue;\n            for (int k = j+1; k < N; k++) {\n                if (adj[i][k] && adj[j][k]) cnt++;\n            }\n        }\n    }\n    return cnt;\n}\n\n// Compute feature vector for a graph\nvector<double> computeFeatures(const vector<vector<bool>>& adj) {\n    vector<double> features;\n    int N = adj.size();\n    \n    // Feature 1: Edge density\n    int edges = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (adj[i][j]) edges++;\n        }\n    }\n    features.push_back(edges);\n    \n    // Feature 2: Degree sequence statistics\n    auto deg = getDegreeSeq(adj);\n    features.push_back(deg[0]);  // min degree\n    features.push_back(deg[N/2]);  // median\n    features.push_back(deg[N-1]);  // max degree\n    \n    // Feature 3: Degree variance\n    double mean = 0;\n    for (int d : deg) mean += d;\n    mean /= N;\n    double var = 0;\n    for (int d : deg) var += (d - mean) * (d - mean);\n    features.push_back(var / N);\n    \n    // Feature 4: Triangles (if N is small enough)\n    if (N <= 50) {\n        features.push_back(countTriangles(adj));\n    }\n    \n    // Feature 5: Number of nodes with degree 0\n    int isolated = 0;\n    for (int d : deg) if (d == 0) isolated++;\n    features.push_back(isolated);\n    \n    // Feature 6: Number of nodes with degree 1\n    int leaves = 0;\n    for (int d : deg) if (d == 1) leaves++;\n    features.push_back(leaves);\n    \n    // Feature 7: Spectral radius estimate (using power iteration)\n    vector<double> vec(N, 1.0 / sqrt(N));\n    for (int iter = 0; iter < 10; iter++) {\n        vector<double> newVec(N, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (adj[i][j]) newVec[i] += vec[j];\n            }\n        }\n        double norm = 0;\n        for (double v : newVec) norm += v * v;\n        norm = sqrt(norm);\n        for (double& v : newVec) v /= norm;\n        vec = newVec;\n    }\n    double spectralRadius = 0;\n    for (int i = 0; i < N; i++) {\n        double sum = 0;\n        for (int j = 0; j < N; j++) {\n            if (adj[i][j]) sum += vec[j];\n        }\n        spectralRadius = max(spectralRadius, abs(sum / vec[i]));\n    }\n    features.push_back(spectralRadius);\n    \n    return features;\n}\n\n// L2 distance between feature vectors\ndouble featureDist(const vector<double>& a, const vector<double>& b) {\n    double d = 0;\n    for (int i = 0; i < (int)a.size(); i++) {\n        double diff = a[i] - b[i];\n        d += diff * diff;\n    }\n    return sqrt(d);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read M and epsilon\n    cin >> M >> eps;\n    \n    // Determine N based on M and epsilon\n    int N;\n    if (eps <= 0.05) {\n        N = min(100, max(20, 10 + 2 * M));\n    } else if (eps <= 0.1) {\n        N = min(80, max(15, 8 + (int)(1.5 * M)));\n    } else if (eps <= 0.2) {\n        N = min(60, max(12, 6 + M));\n    } else if (eps <= 0.3) {\n        N = min(40, max(10, 5 + (int)(0.8 * M)));\n    } else {\n        N = min(30, max(8, 4 + (int)(0.5 * M)));\n    }\n    \n    // Generate graphs with different structures\n    vector<vector<vector<bool>>> graphs(M, vector<vector<bool>>(N, vector<bool>(N, false)));\n    vector<vector<double>> graphFeatures(M);\n    \n    int totalEdges = N * (N - 1) / 2;\n    \n    for (int k = 0; k < M; k++) {\n        // Target edge count proportional to k\n        double targetDensity = (double)(k + 1) / (M + 1);\n        int targetEdges = (int)(targetDensity * totalEdges);\n        \n        // Create graph with specific structure\n        vector<vector<bool>>& adj = graphs[k];\n        \n        // Strategy: create graphs with different structures\n        if (k < M / 3) {\n            // Low density: star-like or path-like\n            if (k % 3 == 0) {\n                // Star graph centered at 0\n                for (int i = 1; i < min(N, 2 + k); i++) {\n                    adj[0][i] = adj[i][0] = true;\n                }\n            } else if (k % 3 == 1) {\n                // Path graph\n                for (int i = 0; i < min(N-1, k); i++) {\n                    adj[i][i+1] = adj[i+1][i] = true;\n                }\n            } else {\n                // Random sparse\n                int edgesNeeded = targetEdges;\n                mt19937 rng(k * 12345 + 67890);\n                while (edgesNeeded > 0) {\n                    int u = rng() % N;\n                    int v = rng() % N;\n                    if (u != v && !adj[u][v]) {\n                        adj[u][v] = adj[v][u] = true;\n                        edgesNeeded--;\n                    }\n                }\n            }\n        } else if (k < 2 * M / 3) {\n            // Medium density: expander-like or bipartite\n            if (k % 2 == 0) {\n                // Two clusters with connections\n                int half = N / 2;\n                for (int i = 0; i < half; i++) {\n                    for (int j = half; j < N; j++) {\n                        if (rand() % 100 < 50) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            } else {\n                // Regular-like graph\n                int deg = max(1, (int)(targetDensity * (N-1)));\n                for (int i = 0; i < N; i++) {\n                    for (int d = 1; d <= deg && i+d < N; d++) {\n                        if (rand() % 100 < 80) {\n                            adj[i][i+d] = adj[i+d][i] = true;\n                        }\n                    }\n                }\n            }\n        } else {\n            // High density: complement of low density structures\n            // First create low density then complement\n            int sparseEdges = totalEdges - targetEdges;\n            mt19937 rng(k * 99999 + 11111);\n            set<pair<int,int>> edgesSet;\n            for (int i = 0; i < N && sparseEdges > 0; i++) {\n                for (int j = i+1; j < N && sparseEdges > 0; j++) {\n                    if (rng() % 100 < 30) {\n                        edgesSet.insert({i, j});\n                        sparseEdges--;\n                    }\n                }\n            }\n            // Complement: add all edges except those in set\n            for (int i = 0; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    if (edgesSet.find({i, j}) == edgesSet.end()) {\n                        if (edgesSet.size() < (size_t)(totalEdges - targetEdges) || rand() % 100 < 70) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Compute features\n        graphFeatures[k] = computeFeatures(adj);\n    }\n    \n    // Output\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        cout << adjToStr(graphs[k]) << endl;\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < QUERIES; q++) {\n        string H_str;\n        cin >> H_str;\n        \n        auto H = strToAdj(H_str, N);\n        auto H_features = computeFeatures(H);\n        \n        // Find closest graph by feature distance\n        int best = 0;\n        double bestDist = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double dist = featureDist(H_features, graphFeatures[k]);\n            // Add penalty for edge count difference (most robust feature)\n            double edgeDiff = abs(H_features[0] - graphFeatures[k][0]);\n            dist += edgeDiff * 0.5;  // Weight edge count heavily\n            \n            if (dist < bestDist) {\n                bestDist = dist;\n                best = k;\n            }\n        }\n        \n        // Additional check: if edge count is very different, override\n        double edgeCountDiff = abs(H_features[0] - graphFeatures[best][0]);\n        if (edgeCountDiff > N * 0.3 && eps > 0.1) {\n            // Find by edge count alone as fallback\n            int newBest = 0;\n            double minEdgeDiff = 1e18;\n            for (int k = 0; k < M; k++) {\n                double diff = abs(H_features[0] - graphFeatures[k][0]);\n                if (diff < minEdgeDiff) {\n                    minEdgeDiff = diff;\n                    newBest = k;\n                }\n            }\n            best = newBest;\n        }\n        \n        cout << best << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\nconst double EPS = 1e-9;\n\nint N, M, D, K;\nvector<tuple<int, int, int>> edges;\nvector<vector<pair<int, int>>> graph;\n\n// Store all-pairs shortest paths\nvector<vector<int>> dist;\nvector<vector<int>> dist_without;\n\n// Edge importance: how many shortest paths use each edge\nvector<double> edge_importance;\n\nvoid compute_shortest_paths() {\n    dist.assign(N, vector<int>(N, INF));\n    for (int i = 0; i < N; i++) {\n        dist[i][i] = 0;\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        pq.push({0, i});\n        \n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[i][v]) continue;\n            \n            for (auto [to, w] : graph[v]) {\n                if (dist[i][to] > d + w) {\n                    dist[i][to] = d + w;\n                    pq.push({dist[i][to], to});\n                }\n            }\n        }\n    }\n}\n\ndouble evaluate_schedule(const vector<int>& schedule) {\n    double total_frustration = 0;\n    \n    // For each day, compute frustration\n    for (int day = 1; day <= D; day++) {\n        // Build graph without edges scheduled on this day\n        vector<vector<pair<int, int>>> temp_graph(N);\n        for (int e = 0; e < M; e++) {\n            if (schedule[e] != day) {\n                auto [u, v, w] = edges[e];\n                temp_graph[u].push_back({v, w});\n                temp_graph[v].push_back({u, w});\n            }\n        }\n        \n        // Compute shortest paths in this graph\n        vector<vector<int>> day_dist(N, vector<int>(N, INF));\n        for (int s = 0; s < N; s++) {\n            day_dist[s][s] = 0;\n            priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n            pq.push({0, s});\n            \n            while (!pq.empty()) {\n                auto [d, v] = pq.top(); pq.pop();\n                if (d != day_dist[s][v]) continue;\n                \n                for (auto [to, w] : temp_graph[v]) {\n                    if (day_dist[s][to] > d + w) {\n                        day_dist[s][to] = d + w;\n                        pq.push({day_dist[s][to], to});\n                    }\n                }\n            }\n        }\n        \n        // Compute frustration for this day\n        double day_frustration = 0;\n        int unreachable = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (day_dist[i][j] == INF) {\n                    day_frustration += INF - dist[i][j];\n                    unreachable++;\n                } else {\n                    day_frustration += day_dist[i][j] - dist[i][j];\n                }\n            }\n        }\n        day_frustration /= (N * (N-1) / 2.0);\n        total_frustration += day_frustration;\n    }\n    \n    return total_frustration / D;\n}\n\nvector<int> greedy_local_search() {\n    // Step 1: Compute edge importance based on contribution to shortest paths\n    edge_importance.assign(M, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            // For each pair, find edges that could be on a shortest path\n            int shortest = dist[i][j];\n            if (shortest == INF) continue;\n            \n            // BFS to find all edges that can be on some shortest path\n            queue<int> q;\n            vector<bool> visited(N, false);\n            vector<int> prev(N, -1);\n            q.push(i);\n            visited[i] = true;\n            \n            while (!q.empty()) {\n                int v = q.front(); q.pop();\n                if (v == j) break;\n                \n                for (auto [to, w] : graph[v]) {\n                    if (!visited[to] && dist[i][v] + w + dist[to][j] == shortest) {\n                        visited[to] = true;\n                        prev[to] = v;\n                        q.push(to);\n                    }\n                }\n            }\n            \n            // Trace back and add importance\n            int cur = j;\n            while (cur != i) {\n                int p = prev[cur];\n                // Find edge index\n                for (int e = 0; e < M; e++) {\n                    auto [u, v, w] = edges[e];\n                    if ((u == p && v == cur) || (u == cur && v == p)) {\n                        edge_importance[e] += 1.0 / (N * (N-1) / 2.0);\n                        break;\n                    }\n                }\n                cur = p;\n            }\n        }\n    }\n    \n    // Step 2: Greedy assignment respecting per-day limits\n    vector<int> best_schedule(M, -1);\n    vector<int> day_count(D+1, 0);\n    double best_score = INF;\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    // Try multiple random seeds\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    for (int trial = 0; trial < 50; trial++) {\n        vector<int> schedule(M, -1);\n        fill(day_count.begin(), day_count.end(), 0);\n        \n        // Assign important edges first, spreading them across days\n        for (int idx = 0; idx < M; idx++) {\n            int e = edge_order[idx];\n            int best_day = -1;\n            double best_impact = INF;\n            \n            // Try all possible days\n            vector<int> days_to_try(D);\n            iota(days_to_try.begin(), days_to_try.end(), 1);\n            shuffle(days_to_try.begin(), days_to_try.end(), rng);\n            \n            for (int day : days_to_try) {\n                if (day_count[day] >= K) continue;\n                \n                // Estimate impact of putting this edge on this day\n                double impact = 0;\n                auto [u, v, w] = edges[e];\n                \n                // Check if other important edges are on this day\n                for (int other = 0; other < M; other++) {\n                    if (other != e && schedule[other] == day) {\n                        // If both edges share a vertex, try to avoid\n                        auto [ou, ov, ow] = edges[other];\n                        if (ou == u || ou == v || ov == u || ov == v) {\n                            impact += edge_importance[other] * 0.5;\n                        }\n                    }\n                }\n                \n                if (impact < best_impact) {\n                    best_impact = impact;\n                    best_day = day;\n                }\n            }\n            \n            schedule[e] = best_day;\n            day_count[best_day]++;\n        }\n        \n        // Step 3: Local search - try swapping days for edges\n        for (int iter = 0; iter < 1000; iter++) {\n            // Randomly pick an edge and try to move it\n            int e1 = uniform_int_distribution<int>(0, M-1)(rng);\n            int old_day = schedule[e1];\n            \n            vector<int> candidates;\n            for (int day = 1; day <= D; day++) {\n                if (day != old_day && day_count[day] < K) {\n                    candidates.push_back(day);\n                }\n            }\n            \n            if (candidates.empty()) continue;\n            int new_day = candidates[uniform_int_distribution<int>(0, candidates.size()-1)(rng)];\n            \n            schedule[e1] = new_day;\n            day_count[old_day]--;\n            day_count[new_day]++;\n            \n            // Evaluate new schedule (simplified - only check affected pairs)\n            // In practice, we'd compute the full evaluation every few iterations\n        }\n        \n        double score = evaluate_schedule(schedule);\n        if (score < best_score) {\n            best_score = score;\n            best_schedule = schedule;\n        }\n    }\n    \n    return best_schedule;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\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        graph[u].push_back({v, w});\n        graph[v].push_back({u, w});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Compute all-pairs shortest paths\n    compute_shortest_paths();\n    \n    // Compute schedule\n    vector<int> schedule = greedy_local_search();\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << schedule[i] << (i+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    void unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D;\n    cin >> D;\n    \n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int k = 0; k < D; k++) cin >> f[i][k];\n        for (int k = 0; k < D; k++) cin >> r[i][k];\n    }\n    \n    // Initial construction: place cubes where both silhouettes have 1\n    vector<vector<vector<int>>> obj(2, vector<vector<int>>(D, vector<int>(D, vector<int>(D, 0))));\n    int total_cubes = 0;\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (f[i][z][x] == '1' && r[i][z][y] == '1') {\n                        obj[i][x][y][z] = 1;\n                        total_cubes++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find cube positions that are used in both objects\n    vector<tuple<int,int,int>> shared_cubes;\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 (obj[0][x][y][z] && obj[1][x][y][z]) {\n                    shared_cubes.push_back({x, y, z});\n                }\n            }\n        }\n    }\n    \n    // Assign block IDs using union find for merging\n    UnionFind uf(total_cubes);\n    vector<tuple<int,int,int>> all_cubes;\n    map<tuple<int,int,int>, int> cube_to_idx;\n    \n    int idx = 0;\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 (obj[i][x][y][z]) {\n                        all_cubes.push_back({x, y, z});\n                        // Check if this position is shared\n                        if (obj[0][x][y][z] && obj[1][x][y][z]) {\n                            cube_to_idx[{x, y, z}] = idx;\n                        }\n                        idx++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Greedy merging: merge adjacent cubes that are both shared\n    const int dx[] = {1, -1, 0, 0, 0, 0};\n    const int dy[] = {0, 0, 1, -1, 0, 0};\n    const int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    // Merge shared cubes first (higher priority)\n    for (auto [x, y, z] : shared_cubes) {\n        int cur_idx = cube_to_idx[{x, y, z}];\n        for (int d = 0; d < 6; d++) {\n            int nx = x + dx[d], ny = y + dy[d], nz = z + dz[d];\n            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n            if (obj[0][nx][ny][nz] && obj[1][nx][ny][nz]) {\n                if (cube_to_idx.count({nx, ny, nz})) {\n                    uf.unite(cur_idx, cube_to_idx[{nx, ny, nz}]);\n                }\n            }\n        }\n    }\n    \n    // Now merge all remaining adjacent cubes\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 (!obj[i][x][y][z]) continue;\n                    for (int d = 0; d < 6; d++) {\n                        int nx = x + dx[d], ny = y + dy[d], nz = z + dz[d];\n                        if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                        if (obj[i][nx][ny][nz]) {\n                            // Merge if they have the same \"shared\" status\n                            bool cur_shared = (obj[0][x][y][z] && obj[1][x][y][z]);\n                            bool nxt_shared = (obj[0][nx][ny][nz] && obj[1][nx][ny][nz]);\n                            if (cur_shared == nxt_shared) {\n                                uf.unite(i * D * D * D + x * D * D + y * D + z, \n                                        i * D * D * D + nx * D * D + ny * D + nz);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Assign block numbers\n    map<int, int> comp_to_block;\n    int block_cnt = 0;\n    \n    vector<vector<vector<int>>> result(2, vector<vector<int>>(D, vector<int>(D, vector<int>(D, 0))));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (obj[i][x][y][z]) {\n                        int comp = uf.find(i * D * D * D + x * D * D + y * D + z);\n                        if (!comp_to_block.count(comp)) {\n                            comp_to_block[comp] = ++block_cnt;\n                        }\n                        result[i][x][y][z] = comp_to_block[comp];\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << block_cnt << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (x > 0 || y > 0 || z > 0) cout << \" \";\n                    cout << result[i][x][y][z];\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Data structures\nstruct Edge {\n    int u, v;\n    long long w;\n};\n\nint N, M, K;\nvector<pair<int,int>> vertices;\nvector<Edge> edges;\nvector<pair<int,int>> residents;\n\n// Read input\nvoid read_input() {\n    cin >> N >> M >> K;\n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n    }\n    residents.resize(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n}\n\n// Compute squared Euclidean distance\nlong long squared_dist(pair<int,int> a, pair<int,int> b) {\n    long long dx = a.first - b.first;\n    long long dy = a.second - b.second;\n    return dx*dx + dy*dy;\n}\n\ndouble dist(pair<int,int> a, pair<int,int> b) {\n    return sqrt(squared_dist(a, b));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    read_input();\n    \n    // Phase 1: For each station, compute minimum power to cover each resident\n    // Phase 2: Select stations to power on and build tree\n    \n    // Simple heuristic: Use all stations initially, then try to reduce\n    \n    // Compute for each resident, which stations can cover it with reasonable power\n    const int MAX_POWER = 5000;\n    const long long MAX_POWER_SQ = (long long)MAX_POWER * MAX_POWER;\n    \n    // Start with all edges off, all powers 0\n    vector<int> P(N, 0);\n    vector<bool> edge_on(M, false);\n    \n    // First, find for each resident the nearest station\n    vector<int> nearest_station(K, -1);\n    vector<long long> min_dist_sq(K, LLONG_MAX);\n    \n    for (int i = 0; i < K; i++) {\n        for (int j = 0; j < N; j++) {\n            long long d = squared_dist(vertices[j], residents[i]);\n            if (d < min_dist_sq[i]) {\n                min_dist_sq[i] = d;\n                nearest_station[i] = j;\n            }\n        }\n    }\n    \n    // Greedy: power on stations that cover many residents with low cost\n    vector<bool> station_on(N, false);\n    station_on[0] = true; // Station 1 is always on\n    \n    // Compute cost-benefit for each station\n    vector<pair<double, int>> station_score;\n    for (int i = 0; i < N; i++) {\n        if (i == 0) continue;\n        int covered = 0;\n        long long max_power_sq = 0;\n        for (int k = 0; k < K; k++) {\n            long long d = squared_dist(vertices[i], residents[k]);\n            if (d <= MAX_POWER_SQ) {\n                covered++;\n                max_power_sq = max(max_power_sq, d);\n            }\n        }\n        if (covered > 0) {\n            double power_cost = sqrt(max_power_sq);\n            double benefit = covered / (power_cost * power_cost + 1);\n            station_score.push_back({-benefit, i});\n        }\n    }\n    sort(station_score.begin(), station_score.end());\n    \n    // Select top stations greedily\n    vector<int> selected_stations = {0};\n    for (auto& s : station_score) {\n        int idx = s.second;\n        if (selected_stations.size() < 20) { // Limit to avoid high cost\n            selected_stations.push_back(idx);\n            station_on[idx] = true;\n        }\n    }\n    \n    // Build MST to connect selected stations to station 1\n    // Use Prim's algorithm\n    vector<bool> in_tree(N, false);\n    vector<long long> min_edge(N, LLONG_MAX);\n    vector<int> parent(N, -1);\n    \n    // Start from station 1\n    in_tree[0] = true;\n    for (int j = 0; j < M; j++) {\n        if (edges[j].u == 0) {\n            if (edges[j].w < min_edge[edges[j].v]) {\n                min_edge[edges[j].v] = edges[j].w;\n                parent[edges[j].v] = j;\n            }\n        }\n        if (edges[j].v == 0) {\n            if (edges[j].w < min_edge[edges[j].u]) {\n                min_edge[edges[j].u] = edges[j].w;\n                parent[edges[j].u] = j;\n            }\n        }\n    }\n    \n    // Add stations layer by layer\n    for (int iter = 0; iter < 5; iter++) {\n        // Find nearest not-in-tree station that we want\n        int best = -1;\n        long long best_cost = LLONG_MAX;\n        for (int i : selected_stations) {\n            if (!in_tree[i] && min_edge[i] < best_cost) {\n                best_cost = min_edge[i];\n                best = i;\n            }\n        }\n        if (best == -1) break;\n        \n        // Add the edge\n        int e_idx = parent[best];\n        edge_on[e_idx] = true;\n        in_tree[best] = true;\n        \n        // Update distances\n        for (int j = 0; j < M; j++) {\n            if (edges[j].u == best && !in_tree[edges[j].v]) {\n                if (edges[j].w < min_edge[edges[j].v]) {\n                    min_edge[edges[j].v] = edges[j].w;\n                    parent[edges[j].v] = j;\n                }\n            }\n            if (edges[j].v == best && !in_tree[edges[j].u]) {\n                if (edges[j].w < min_edge[edges[j].u]) {\n                    min_edge[edges[j].u] = edges[j].w;\n                    parent[edges[j].u] = j;\n                }\n            }\n        }\n    }\n    \n    // Add remaining edges to make graph connected (if needed)\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    for (int i = 0; i < N; i++) {\n        if (in_tree[i]) {\n            for (int j = 0; j < M; j++) {\n                if (edges[j].u == i && !in_tree[edges[j].v]) {\n                    pq.push({edges[j].w, j});\n                }\n                if (edges[j].v == i && !in_tree[edges[j].u]) {\n                    pq.push({edges[j].w, j});\n                }\n            }\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [cost, e_idx] = pq.top();\n        pq.pop();\n        int u = edges[e_idx].u, v = edges[e_idx].v;\n        if (in_tree[u] && in_tree[v]) continue;\n        int new_node = in_tree[u] ? v : u;\n        if (in_tree[new_node]) continue;\n        \n        edge_on[e_idx] = true;\n        in_tree[new_node] = true;\n        \n        for (int j = 0; j < M; j++) {\n            if (edges[j].u == new_node && !in_tree[edges[j].v]) {\n                pq.push({edges[j].w, j});\n            }\n            if (edges[j].v == new_node && !in_tree[edges[j].u]) {\n                pq.push({edges[j].w, j});\n            }\n        }\n    }\n    \n    // Now compute power levels for each station\n    // Only stations reachable from station 1 matter\n    // Compute reachable set\n    vector<bool> reachable(N, false);\n    queue<int> q;\n    q.push(0);\n    reachable[0] = true;\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for (int j = 0; j < M; j++) {\n            if (!edge_on[j]) continue;\n            int v = (edges[j].u == u) ? edges[j].v : (edges[j].v == u ? edges[j].u : -1);\n            if (v != -1 && !reachable[v]) {\n                reachable[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    // For each resident, find nearest reachable station and compute needed power\n    for (int k = 0; k < K; k++) {\n        long long best_d = LLONG_MAX;\n        int best_st = -1;\n        for (int i = 0; i < N; i++) {\n            if (!reachable[i]) continue;\n            long long d = squared_dist(vertices[i], residents[k]);\n            if (d < best_d) {\n                best_d = d;\n                best_st = i;\n            }\n        }\n        if (best_st != -1) {\n            long long needed = ceill(sqrt(best_d));\n            P[best_st] = max(P[best_st], (int)needed);\n        }\n    }\n    \n    // Clamp power to MAX_POWER\n    for (int i = 0; i < N; i++) {\n        P[i] = min(P[i], MAX_POWER);\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << P[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (edge_on[j] ? 1 : 0) << (j+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2; // 465\n\n// Direction vectors for 6-directional movement\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Check if coordinates are valid\nbool valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\n\n// Get target position for a number\npair<int,int> target_pos(int val) {\n    int n = 1;\n    while (n * (n + 1) / 2 <= val) n++;\n    n--;\n    int x = n;\n    int y = val - n * (n + 1) / 2;\n    return {x, y};\n}\n\nint main() {\n    vector<vector<int>> grid(N, vector<int>(N));\n    vector<pair<int,int>> pos(TOTAL);\n    \n    // Read input\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    \n    vector<tuple<int,int,int,int>> operations;\n    \n    // Process balls from smallest to largest\n    for (int val = 0; val < TOTAL; val++) {\n        auto [cx, cy] = pos[val];\n        auto [tx, ty] = target_pos(val);\n        \n        // BFS to find shortest path from current to target\n        vector<vector<int>> dist(N, vector<int>(N, -1));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1, -1}));\n        queue<pair<int,int>> q;\n        \n        dist[cx][cy] = 0;\n        q.push({cx, cy});\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            if (x == tx && y == ty) break;\n            \n            for (int d = 0; d < 6; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (valid(nx, ny) && dist[nx][ny] == -1) {\n                    dist[nx][ny] = dist[x][y] + 1;\n                    prev[nx][ny] = {x, y};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        // Reconstruct path and perform swaps\n        int cur_x = tx, cur_y = ty;\n        vector<pair<int,int>> path;\n        while (cur_x != cx || cur_y != cy) {\n            path.push_back({cur_x, cur_y});\n            auto [p_x, p_y] = prev[cur_x][cur_y];\n            cur_x = p_x; cur_y = p_y;\n        }\n        path.push_back({cx, cy});\n        reverse(path.begin(), path.end());\n        \n        // Execute swaps along the path\n        for (int i = 0; i + 1 < (int)path.size(); i++) {\n            auto [x1, y1] = path[i];\n            auto [x2, y2] = path[i+1];\n            \n            // Swap values\n            swap(grid[x1][y1], grid[x2][y2]);\n            pos[grid[x1][y1]] = {x1, y1};\n            pos[grid[x2][y2]] = {x2, y2};\n            \n            operations.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nvector<vector<int>> grid(N, vector<int>(N, -1));\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    vector<vector<int>> input(n, vector<int>(n));\n    vector<pair<int,int>> seeds(m+1);\n    vector<set<int>> adj(m+1);\n    vector<vector<bool>> hasColor(n, vector<bool>(n, false));\n    \n    // Read input and collect each color's first occurrence for seeding\n    for(int i = 0; i < n; i++) {\n        for(int j = 0; j < n; j++) {\n            cin >> input[i][j];\n            int c = input[i][j];\n            if(seeds[c].first == 0 && seeds[c].second == 0 && c != 0) {\n                seeds[c] = {i, j};\n            }\n            hasColor[i][j] = true;\n        }\n    }\n    \n    // Build adjacency graph\n    vector<vector<bool>> adjMatrix(m+1, vector<bool>(m+1, false));\n    for(int i = 0; i < n; i++) {\n        for(int j = 0; j < n; j++) {\n            if(i+1 < n && input[i][j] != input[i+1][j]) {\n                int a = input[i][j], b = input[i+1][j];\n                adjMatrix[a][b] = adjMatrix[b][a] = true;\n            }\n            if(j+1 < n && input[i][j] != input[i][j+1]) {\n                int a = input[i][j], b = input[i][j+1];\n                adjMatrix[a][b] = adjMatrix[b][a] = true;\n            }\n        }\n    }\n    \n    // Initialize output grid with -1 (unassigned)\n    vector<vector<int>> output(n, vector<int>(n, 0));\n    \n    // Strategy: Place each color in a small cluster, then expand to meet adjacency requirements\n    // We'll use a greedy approach: place colors in order, trying to maximize shared borders\n    \n    // First, find a good ordering (by degree in adjacency graph)\n    vector<pair<int,int>> colorDegree;\n    for(int c = 1; c <= m; c++) {\n        int deg = 0;\n        for(int d = 1; d <= m; d++) {\n            if(adjMatrix[c][d]) deg++;\n        }\n        colorDegree.push_back({deg, c});\n    }\n    sort(colorDegree.rbegin(), colorDegree.rend());\n    \n    // Place seeds for each color\n    set<int> placed;\n    for(auto [deg, c] : colorDegree) {\n        // Find a good position near already placed adjacent colors\n        int bestI = -1, bestJ = -1;\n        int bestScore = -1;\n        \n        for(int i = 0; i < n; i++) {\n            for(int j = 0; j < n; j++) {\n                if(output[i][j] != 0) continue;\n                \n                int score = 0;\n                // Check how many adjacent colors are already placed nearby\n                for(int di = -2; di <= 2; di++) {\n                    for(int dj = -2; dj <= 2; dj++) {\n                        int ni = i+di, nj = j+dj;\n                        if(ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n                        if(output[ni][nj] > 0 && adjMatrix[c][output[ni][nj]]) {\n                            score += (3 - abs(di) - abs(dj));\n                        }\n                    }\n                }\n                \n                if(score > bestScore) {\n                    bestScore = score;\n                    bestI = i;\n                    bestJ = j;\n                }\n            }\n        }\n        \n        if(bestI != -1) {\n            output[bestI][bestJ] = c;\n            placed.insert(c);\n        }\n    }\n    \n    // Place remaining colors that weren't placed\n    for(int c = 1; c <= m; c++) {\n        if(placed.count(c)) continue;\n        for(int i = 0; i < n; i++) {\n            bool placed = false;\n            for(int j = 0; j < n; j++) {\n                if(output[i][j] == 0) {\n                    output[i][j] = c;\n                    placed = true;\n                    break;\n                }\n            }\n            if(placed) break;\n        }\n    }\n    \n    // Now expand regions to ensure connectivity and adjacency requirements\n    // We'll do multiple passes to improve\n    for(int pass = 0; pass < 5; pass++) {\n        // For each color, expand to meet adjacency requirements\n        for(int c = 1; c <= m; c++) {\n            // Find all positions of this color\n            vector<pair<int,int>> positions;\n            for(int i = 0; i < n; i++) {\n                for(int j = 0; j < n; j++) {\n                    if(output[i][j] == c) {\n                        positions.push_back({i, j});\n                    }\n                }\n            }\n            \n            // Check which adjacencies we need to create\n            set<int> missingAdj;\n            for(int d = 1; d <= m; d++) {\n                if(adjMatrix[c][d] && c != d) {\n                    // Check if they're already adjacent\n                    bool alreadyAdj = false;\n                    for(auto [i, j] : positions) {\n                        for(int di = -1; di <= 1; di++) {\n                            for(int dj = -1; dj <= 1; dj++) {\n                                if(abs(di)+abs(dj) != 1) continue;\n                                int ni = i+di, nj = j+dj;\n                                if(ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n                                if(output[ni][nj] == d) {\n                                    alreadyAdj = true;\n                                    break;\n                                }\n                            }\n                            if(alreadyAdj) break;\n                        }\n                        if(alreadyAdj) break;\n                    }\n                    if(!alreadyAdj) {\n                        missingAdj.insert(d);\n                    }\n                }\n            }\n            \n            // Try to create missing adjacencies by expanding\n            if(!missingAdj.empty()) {\n                // Find positions where we can expand to meet missing adjacencies\n                set<pair<int,int>> expandable;\n                for(auto [i, j] : positions) {\n                    for(int di = -1; di <= 1; di++) {\n                        for(int dj = -1; dj <= 1; dj++) {\n                            if(abs(di)+abs(dj) != 1) continue;\n                            int ni = i+di, nj = j+dj;\n                            if(ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n                            if(output[ni][nj] == 0) {\n                                expandable.insert({ni, nj});\n                            }\n                        }\n                    }\n                }\n                \n                // Expand to create required adjacencies\n                for(auto [i, j] : expandable) {\n                    if(missingAdj.empty()) break;\n                    \n                    // Check if expanding here helps with missing adjacencies\n                    int ni, nj;\n                    for(int di = -1; di <= 1; di++) {\n                        for(int dj = -1; dj <= 1; dj++) {\n                            if(abs(di)+abs(dj) != 1) continue;\n                            ni = i+di; nj = j+dj;\n                            if(ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n                            if(output[ni][nj] > 0 && output[ni][nj] != c && missingAdj.count(output[ni][nj])) {\n                                output[i][j] = c;\n                                missingAdj.erase(output[ni][nj]);\n                                break;\n                            }\n                        }\n                        if(missingAdj.empty() || output[i][j] == c) break;\n                    }\n                }\n            }\n        }\n        \n        // Clean up: remove isolated cells that aren't needed\n        // (This is a simplified cleanup - a full solution would need more sophisticated optimization)\n    }\n    \n    // Output the result\n    for(int i = 0; i < n; i++) {\n        for(int j = 0; j < n; j++) {\n            if(j > 0) cout << \" \";\n            cout << output[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Utility for random\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint N, D, Q;\n\n// Structure to store comparison results\nstruct ComparisonResult {\n    int left_sum, right_sum;\n    char result;\n};\n\n// Compare two sets and return result\nchar compare_sets(const vector<int>& left, const vector<int>& right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    string res;\n    cin >> res;\n    return res[0];\n}\n\n// Compare single items indirectly\nchar compare_items(int a, int b) {\n    return compare_sets({a}, {b});\n}\n\n// Binary search to find position in sorted array\nint find_position(const vector<int>& sorted_items, int item, int l, int r) {\n    if (l >= r) return l;\n    int mid = (l + r) / 2;\n    \n    // Compare item with the middle element\n    char res = compare_items(item, sorted_items[mid]);\n    \n    if (res == '<') {\n        return find_position(sorted_items, item, l, mid);\n    } else if (res == '>') {\n        return find_position(sorted_items, item, mid + 1, r);\n    } else {\n        return mid;\n    }\n}\n\n// Compare sums of two groups\nchar compare_groups(const vector<vector<int>>& groups, int g1, int g2) {\n    vector<int> left = groups[g1];\n    vector<int> right = groups[g2];\n    \n    if (left.empty() || right.empty()) {\n        // Handle empty groups by adding a dummy comparison\n        if (left.empty() && right.empty()) return '=';\n        if (left.empty()) return '<';\n        return '>';\n    }\n    \n    return compare_sets(left, right);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Phase 1: Sort items by weight using comparisons\n    vector<int> order;\n    order.push_back(0);\n    \n    for (int i = 1; i < N && Q > 0; i++) {\n        // Binary search to find position\n        int pos = find_position(order, i, 0, order.size());\n        order.insert(order.begin() + pos, i);\n        Q--;\n        \n        // If few queries remain, stop sorting\n        if (Q <= N) break;\n    }\n    \n    // Phase 2: Create initial groups using greedy assignment\n    // Assign items to groups trying to balance weights\n    vector<vector<int>> groups(D);\n    vector<long long> group_weights(D, 0);\n    \n    // First pass: assign each item to the lightest group\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        \n        // Find group with minimum weight\n        int min_group = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] < group_weights[min_group]) {\n                min_group = j;\n            }\n        }\n        \n        groups[min_group].push_back(item);\n        group_weights[min_group]++; // approximate weight\n    }\n    \n    // Phase 3: Refine groups using remaining queries\n    // Try to balance groups by moving items\n    int remaining_queries = Q;\n    \n    for (int iter = 0; iter < min(remaining_queries / 2, 10 * D); iter++) {\n        // Find heaviest and lightest groups\n        int heaviest = 0, lightest = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] > group_weights[heaviest]) heaviest = j;\n            if (group_weights[j] < group_weights[lightest]) lightest = j;\n        }\n        \n        if (heaviest == lightest) break;\n        \n        // Try to move an item from heaviest to lightest\n        if (!groups[heaviest].empty()) {\n            // Pick a random item from heaviest group\n            int idx = rng() % groups[heaviest].size();\n            int item = groups[heaviest][idx];\n            \n            // Temporarily move item\n            groups[heaviest].erase(groups[heaviest].begin() + idx);\n            groups[lightest].push_back(item);\n            \n            // Compare the modified groups\n            char result = compare_groups(groups, heaviest, lightest);\n            remaining_queries--;\n            \n            if (result == '<' || result == '=') {\n                // Improvement: keep the move\n                group_weights[heaviest]--;\n                group_weights[lightest]++;\n            } else {\n                // Revert the move\n                groups[lightest].pop_back();\n                groups[heaviest].insert(groups[heaviest].begin() + idx, item);\n            }\n        }\n        \n        if (remaining_queries <= 0) break;\n    }\n    \n    // Use any remaining queries for final verification\n    while (remaining_queries > 0) {\n        // Dummy comparison to waste queries\n        compare_sets({0}, {1});\n        remaining_queries--;\n    }\n    \n    // Phase 4: Output final partition\n    vector<int> assignment(N);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int n = 200, m = 10;\n    const int h = n / m; // 20\n    \n    // Read input\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; j++) {\n            cin >> stacks[i][j];\n        }\n        reverse(stacks[i].begin(), stacks[i].end()); // top is at back\n    }\n    \n    vector<array<int, 2>> operations;\n    int next_to_remove = 1;\n    \n    // Helper to remove from top\n    auto try_remove = [&]() -> bool {\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_to_remove) {\n                stacks[i].pop_back();\n                operations.push_back({next_to_remove, 0});\n                next_to_remove++;\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    // Helper to find stack containing a given box\n    auto find_stack = [&](int v) -> 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] == v) return i;\n            }\n        }\n        return -1;\n    };\n    \n    // Remove easily accessible boxes first\n    while (true) {\n        bool removed = try_remove();\n        if (!removed) break;\n    }\n    \n    // Process remaining boxes\n    while (next_to_remove <= n) {\n        int target_stack = find_stack(next_to_remove);\n        if (target_stack == -1) {\n            break;\n        }\n        \n        auto& st = stacks[target_stack];\n        // Find position of target box (from top, which is back)\n        int pos = -1;\n        for (int i = 0; i < (int)st.size(); i++) {\n            if (st[i] == next_to_remove) {\n                pos = i;\n                break;\n            }\n        }\n        \n        if (pos == (int)st.size() - 1) {\n            // It's already on top\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n            continue;\n        }\n        \n        // Need to move boxes above it\n        // Find best destination: stack with smallest top, or empty stack\n        int best_dest = -1;\n        int best_top = n + 1;\n        for (int i = 0; i < m; i++) {\n            if (i == target_stack) continue;\n            if (stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n            if (stacks[i].back() < best_top) {\n                best_top = stacks[i].back();\n                best_dest = i;\n            }\n        }\n        \n        // Move boxes from position pos+1 to end to best_dest\n        int k = (int)st.size() - pos - 1;\n        // Move in one operation by moving the top box v = st[pos+1]\n        if (k > 0) {\n            int v = st[pos + 1];\n            operations.push_back({v, best_dest});\n            // Update stacks\n            vector<int> moved(st.begin() + pos + 1, st.end());\n            st.resize(pos + 1);\n            for (int x : moved) {\n                stacks[best_dest].push_back(x);\n            }\n        }\n        \n        // Now remove the target box\n        if (!st.empty() && st.back() == next_to_remove) {\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n        }\n        \n        // Try to remove any consecutive boxes that are now on top\n        while (true) {\n            bool removed = try_remove();\n            if (!removed) break;\n        }\n        \n        if (operations.size() > 5000) break;\n    }\n    \n    // Output\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_CELL = MAX_N * MAX_N;\nconst int INF = 1e9;\n\nint N;\nvector<string> h, v; // walls\nvector<vector<int>> d; // dirt rates\n\n// neighbor directions: 0: R, 1: D, 2: L, 3: U\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dirChar[4] = {'R', 'D', 'L', 'U'};\n\nint cellId(int i, int j) { return i * N + j; }\n\nvector<int> neighbors[MAX_CELL];\nint firstMove[MAX_CELL][MAX_CELL]; // direction to take from src to reach dst (0-3)\n\nvoid buildGraph() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = cellId(i, j);\n            // right\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = cellId(i, j+1);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            // down\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = cellId(i+1, j);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            // left and up are covered by symmetry\n        }\n    }\n}\n\nvoid precomputeFirstMove() {\n    int totalCells = N * N;\n    for (int src = 0; src < totalCells; src++) {\n        vector<int> dist(totalCells, INF);\n        vector<int> first(totalCells, -1);\n        queue<int> q;\n        dist[src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < (int)neighbors[u].size(); dir++) {\n                int v = neighbors[u][dir];\n                if (dist[v] == INF) {\n                    dist[v] = dist[u] + 1;\n                    // record the first move from src: for v, it's the direction from src to the neighbor on the path\n                    // we can store it later when we reconstruct\n                    first[v] = (u == src) ? dir : first[u];\n                    q.push(v);\n                }\n            }\n        }\n        // map first[neighbor] to actual direction from src\n        // but we stored dir relative to neighbor list of u. We need global direction.\n        // Better: during BFS, when we expand from src, we know the direction index (0-3) to each neighbor.\n        // So we store for each v the global direction index from src.\n        // Adjust: for each neighbor v of src, we know its direction.\n        // For others, first[v] = first[u] (the direction from src to u's predecessor).\n        // We'll compute differently: after BFS, run a second pass to fill global direction.\n        // We'll just use BFS each time to get direction? Simpler: precompute firstMove as path direction using BFS from src each time? Not efficient.\n        // Alternative: store for each src,dst the first move direction by doing a BFS and tracing back.\n        // We'll do: for each src, BFS, then for each dst, backtrack to src to get first move.\n        // Backtrack uses parent array. Let's reimplement.\n    }\n}\n\n// We'll implement BFS on the fly in the main loop? Too heavy. Let's precompute full direction table.\n\nvoid precomputeFirstMove2() {\n    int total = N * N;\n    for (int src = 0; src < total; src++) {\n        vector<int> dist(total, INF);\n        vector<int> parent(total, -1);\n        vector<int> moveFromParent(total, -1); // direction from parent to child\n        queue<int> q;\n        dist[src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int nb : neighbors[u]) {\n                if (dist[nb] == INF) {\n                    dist[nb] = dist[u] + 1;\n                    parent[nb] = u;\n                    // determine direction from u to nb\n                    int iu = u / N, ju = u % N;\n                    int inb = nb / N, jnb = nb % N;\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (iu + di[dir] == inb && ju + dj[dir] == jnb) {\n                            moveFromParent[nb] = dir;\n                            break;\n                        }\n                    }\n                    q.push(nb);\n                }\n            }\n        }\n        // for each dst, walk back to src to find first move\n        for (int dst = 0; dst < total; dst++) {\n            if (dst == src) { firstMove[src][dst] = -1; continue; }\n            int cur = dst;\n            while (parent[cur] != src) cur = parent[cur];\n            firstMove[src][dst] = moveFromParent[cur];\n        }\n    }\n}\n\nstring dfs_route;\n\nvoid dfs(int i, int j, vector<vector<bool>>& vis) {\n    vis[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !vis[ni][nj]) {\n            // check wall\n            if (dir == 0 && v[i][j] == '1') continue;\n            if (dir == 1 && h[i][j] == '1') continue;\n            if (dir == 2 && v[i][j-1] == '1') continue;\n            if (dir == 3 && h[i-1][j] == '1') continue;\n            dfs_route.push_back(dirChar[dir]);\n            dfs(ni, nj, vis);\n            dfs_route.push_back(dirChar[(dir+2)%4]);\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    v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n\n    buildGraph();\n    precomputeFirstMove2();\n\n    // 1. DFS covering all cells\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    dfs_route.clear();\n    dfs(0, 0, vis);\n    string route = dfs_route;\n\n    // simulate DFS to get dirt array and last visit times\n    vector<vector<int>> dirt(N, vector<int>(N, 0));\n    vector<vector<int>> lastVisit(N, vector<int>(N, -1));\n    int ci = 0, cj = 0;\n    lastVisit[0][0] = 0;\n    // initial dirt update not needed because all zero at t=0.\n    // For each move in dfs_route:\n    for (char ch : route) {\n        // add d to all cells\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n        // move\n        int dir = -1;\n        if (ch == 'R') dir = 0;\n        else if (ch == 'D') dir = 1;\n        else if (ch == 'L') dir = 2;\n        else if (ch == 'U') dir = 3;\n        ci += di[dir]; cj += dj[dir];\n        dirt[ci][cj] = 0;\n        lastVisit[ci][cj] = (int)route.size(); // approximate, but we'll track step count later\n    }\n\n    // After DFS, we have visited all cells.\n    // Now greedy extra moves\n    int dfsLen = (int)route.size();\n    int maxMoves = 100000;\n    int remaining = maxMoves - dfsLen;\n    if (remaining < 0) { /* too long, but unlikely */ }\n\n    // we will add extra moves\n    string extra;\n    int curId = cellId(ci, cj);\n    // we need to track step count for dirt accumulation\n    int step = dfsLen; // next step index (0-indexed after DFS)\n    vector<vector<int>> curDirt = dirt; // copy\n    // we also need lastVisit for dirt calculation? we maintain curDirt directly.\n    auto findMaxDirtCell = [&]() -> pair<int,int> {\n        int maxVal = -1;\n        int mi = -1, mj = -1;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (curDirt[i][j] > maxVal) {\n                    maxVal = curDirt[i][j];\n                    mi = i; mj = j;\n                }\n            }\n        }\n        return {mi, mj};\n    };\n\n    // Precompute distance to origin for deadline\n    vector<vector<int>> distToOrigin(N, vector<int>(N, INF));\n    {\n        queue<pair<int,int>> q;\n        distToOrigin[0][0] = 0;\n        q.push({0,0});\n        while (!q.empty()) {\n            auto [i,j] = q.front(); q.pop();\n            int u = cellId(i,j);\n            for (int nb : neighbors[u]) {\n                int ni = nb/N, nj = nb%N;\n                if (distToOrigin[ni][nj] > distToOrigin[i][j] + 1) {\n                    distToOrigin[ni][nj] = distToOrigin[i][j] + 1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n    }\n\n    int stepsLeft = remaining - 1; // reserve last step to return\n    for (int t = 0; t < stepsLeft; t++) {\n        // find cell with max dirt\n        auto [ti, tj] = findMaxDirtCell();\n        int targetId = cellId(ti, tj);\n        int dir = firstMove[curId][targetId];\n        int ni = ci + di[dir];\n        int nj = cj + dj[dir];\n        // check deadline: after move, distance to origin must be <= (remaining - t - 1 - 1) because we need one more step after loop\n        int remAfterMove = stepsLeft - t - 1; // steps left after this move (excluding final return)\n        if (distToOrigin[ni][nj] > remAfterMove) {\n            // choose alternative: move toward origin? Instead, find any reachable cell that satisfies deadline and high dirt.\n            // Simple fallback: move to neighbor with smallest distance to origin that satisfies deadline.\n            int bestDir = -1;\n            int bestDist = INF;\n            for (int dir2 = 0; dir2 < 4; dir2++) {\n                int ni2 = ci + di[dir2];\n                int nj2 = cj + dj[dir2];\n                if (ni2 < 0 || ni2 >= N || nj2 < 0 || nj2 >= N) continue;\n                // check wall\n                if (dir2 == 0 && v[ci][cj] == '1') continue;\n                if (dir2 == 1 && h[ci][cj] == '1') continue;\n                if (dir2 == 2 && v[ci][cj-1] == '1') continue;\n                if (dir2 == 3 && h[ci-1][cj] == '1') continue;\n                if (distToOrigin[ni2][nj2] <= remAfterMove) {\n                    if (distToOrigin[ni2][nj2] < bestDist) {\n                        bestDist = distToOrigin[ni2][nj2];\n                        bestDir = dir2;\n                    }\n                }\n            }\n            if (bestDir == -1) break; // no feasible move? shouldn't happen\n            dir = bestDir;\n            ni = ci + di[dir];\n            nj = cj + dj[dir];\n        }\n        extra.push_back(dirChar[dir]);\n        // update dirt\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) curDirt[i][j] += d[i][j];\n        ci = ni; cj = nj;\n        curDirt[ci][cj] = 0;\n        curId = cellId(ci, cj);\n    }\n\n    // finally return to (0,0)\n    // BFS from current to origin\n    int target = 0;\n    while (curId != target) {\n        int dir = firstMove[curId][target];\n        extra.push_back(dirChar[dir]);\n        int ni = ci + di[dir];\n        int nj = cj + dj[dir];\n        ci = ni; cj = nj;\n        curId = cellId(ci, cj);\n        // (no need to update dirt for return moves as output length may exceed, but we have to ensure length <=100000)\n    }\n\n    string finalRoute = route + extra;\n    if ((int)finalRoute.size() > 100000) finalRoute.resize(100000);\n\n    cout << finalRoute << endl;\n\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Constants\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\n// Grid information\nvector<string> grid(N);\nint si, sj;\n\n// Word information\nvector<string> words(M);\nvector<vector<pair<int,int>>> char_positions[26];\n\n// For each word, store the best position to start/end\nstruct WordInfo {\n    string word;\n    vector<int> best_path_i, best_path_j;\n    int best_cost;\n};\n\nvector<WordInfo> word_info(M);\n\n// Precompute positions of each character on the grid\nvoid precompute_positions() {\n    for (int c = 0; c < 26; c++) {\n        char_positions[c].clear();\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n}\n\n// Compute optimal path for a single word starting from (si, sj)\npair<vector<int>, vector<int>> optimize_word_path(const string& word, int start_i, int start_j) {\n    int len = word.size();\n    vector<vector<vector<int>>> dp(len, vector<vector<int>>(N, vector<int>(N, 1e9)));\n    vector<vector<vector<pair<int,int>>>> prev(len, vector<vector<pair<int,int>>>(N, vector<pair<int,int>>(N, {-1, -1})));\n    \n    // Initialize first character\n    for (auto [i, j] : char_positions[word[0] - 'A']) {\n        dp[0][i][j] = abs(i - start_i) + abs(j - start_j) + 1;\n        prev[0][i][j] = {start_i, start_j};\n    }\n    \n    // DP for remaining characters\n    for (int pos = 1; pos < len; pos++) {\n        for (auto [i, j] : char_positions[word[pos] - 'A']) {\n            for (auto [pi, pj] : char_positions[word[pos-1] - 'A']) {\n                int cost = dp[pos-1][pi][pj] + abs(i - pi) + abs(j - pj) + 1;\n                if (cost < dp[pos][i][j]) {\n                    dp[pos][i][j] = cost;\n                    prev[pos][i][j] = {pi, pj};\n                }\n            }\n        }\n    }\n    \n    // Find best ending position\n    int best_i = 0, best_j = 0, best_cost = 1e9;\n    for (auto [i, j] : char_positions[word[len-1] - 'A']) {\n        if (dp[len-1][i][j] < best_cost) {\n            best_cost = dp[len-1][i][j];\n            best_i = i;\n            best_j = j;\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path_i(len), path_j(len);\n    int ci = best_i, cj = best_j;\n    for (int pos = len-1; pos >= 0; pos--) {\n        path_i[pos] = ci;\n        path_j[pos] = cj;\n        if (pos > 0) {\n            auto [pi, pj] = prev[pos][ci][cj];\n            ci = pi;\n            cj = pj;\n        }\n    }\n    \n    return {path_i, path_j};\n}\n\n// Compute transition cost between two words\nint transition_cost(const pair<int,int>& end1, const pair<int,int>& start2) {\n    return abs(end1.first - start2.first) + abs(end1.second - start2.second) + 1;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M;\n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    precompute_positions();\n    \n    // Precompute optimal paths for each word\n    for (int i = 0; i < M; i++) {\n        auto [path_i, path_j] = optimize_word_path(words[i], si, sj);\n        int cost = 0, ci = si, cj = sj;\n        for (int p = 0; p < 5; p++) {\n            cost += abs(path_i[p] - ci) + abs(path_j[p] - cj) + 1;\n            ci = path_i[p];\n            cj = path_j[p];\n        }\n        word_info[i] = {words[i], path_i, path_j, cost};\n    }\n    \n    // Greedy construction of superstring with path optimization\n    vector<bool> used(M, false);\n    vector<int> order;\n    int cur_i = si, cur_j = sj;\n    int total_cost = 0;\n    int ops = 0;\n    \n    // Start with the cheapest first word\n    int best_first = 0, best_first_cost = 1e9;\n    for (int i = 0; i < M; i++) {\n        int cost = transition_cost({si, sj}, {word_info[i].best_path_i[0], word_info[i].best_path_j[0]});\n        if (cost < best_first_cost) {\n            best_first_cost = cost;\n            best_first = i;\n        }\n    }\n    \n    order.push_back(best_first);\n    used[best_first] = true;\n    cur_i = word_info[best_first].best_path_i[4];\n    cur_j = word_info[best_first].best_path_j[4];\n    \n    // Greedy selection of remaining words\n    while ((int)order.size() < M) {\n        int best_next = -1, best_next_cost = 1e9;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            \n            // Check if we can overlap with the last word\n            string& last_word = words[order.back()];\n            string& next_word = words[i];\n            \n            int overlap = 0;\n            for (int o = 1; o <= 4; o++) {\n                if (last_word.substr(5-o) == next_word.substr(0, o)) {\n                    overlap = o;\n                }\n            }\n            \n            int cost;\n            if (overlap > 0) {\n                // Only need to type the non-overlapping part\n                cost = 0;\n                int ci = cur_i, cj = cur_j;\n                for (int p = overlap; p < 5; p++) {\n                    cost += abs(word_info[i].best_path_i[p] - ci) + abs(word_info[i].best_path_j[p] - cj) + 1;\n                    ci = word_info[i].best_path_i[p];\n                    cj = word_info[i].best_path_j[p];\n                }\n            } else {\n                // Full cost\n                cost = transition_cost({cur_i, cur_j}, {word_info[i].best_path_i[0], word_info[i].best_path_j[0]});\n                for (int p = 0; p < 5; p++) {\n                    if (p > 0) {\n                        cost += abs(word_info[i].best_path_i[p] - word_info[i].best_path_i[p-1]) + \n                               abs(word_info[i].best_path_j[p] - word_info[i].best_path_j[p-1]) + 1;\n                    } else {\n                        cost += 1; // Already counted transition cost\n                    }\n                }\n            }\n            \n            if (cost < best_next_cost) {\n                best_next_cost = cost;\n                best_next = i;\n            }\n        }\n        \n        order.push_back(best_next);\n        used[best_next] = true;\n        cur_i = word_info[best_next].best_path_i[4];\n        cur_j = word_info[best_next].best_path_j[4];\n    }\n    \n    // Output the sequence of operations\n    cur_i = si, cur_j = sj;\n    for (int idx : order) {\n        // Move to first character of this word\n        vector<int>& path_i = word_info[idx].best_path_i;\n        vector<int>& path_j = word_info[idx].best_path_j;\n        \n        if (!(path_i[0] == cur_i && path_j[0] == cur_j)) {\n            cout << path_i[0] << \" \" << path_j[0] << \"\\n\";\n            cur_i = path_i[0];\n            cur_j = path_j[0];\n            ops++;\n        }\n        \n        // Type the word\n        for (int p = 0; p < 5; p++) {\n            if (p > 0 || !(path_i[p] == cur_i && path_j[p] == cur_j)) {\n                cout << path_i[p] << \" \" << path_j[p] << \"\\n\";\n                cur_i = path_i[p];\n                cur_j = path_j[p];\n                ops++;\n            }\n        }\n    }\n    \n    cerr << \"Total operations: \" << ops << endl;\n    cerr << \"Total cost: \" << total_cost << endl;\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\n#include <cmath>\n#include <random>\nusing namespace std;\n\nconst double INF = 1e18;\n\nstruct OilField {\n    int id;\n    vector<pair<int,int>> cells; // relative positions\n    int h, w; // height, width after translation\n    vector<pair<int,int>> relative; // original relative positions\n};\n\nint N, M;\ndouble eps;\nvector<OilField> fields;\nvector<vector<int>> oil_map; // ground truth (for simulation)\n\n// For divination queries\ndouble last_query_result;\n\n// Known oil positions\nset<pair<int,int>> known_oil;\nset<pair<int,int>> known_dry;\n\n// For reading responses\ndouble read_response() {\n    string line;\n    getline(cin, line);\n    if (line.empty()) getline(cin, line);\n    return stod(line);\n}\n\n// Query a single cell\nint query_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    fflush(stdout);\n    int val = (int)read_response();\n    return val;\n}\n\n// Query a set of cells\ndouble query_set(const vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto [i,j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    fflush(stdout);\n    return read_response();\n}\n\n// Attempt a guess\nbool make_guess(const set<pair<int,int>>& guess) {\n    cout << \"a \" << guess.size();\n    for (auto [i,j] : guess) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    fflush(stdout);\n    int result = (int)read_response();\n    return result == 1;\n}\n\n// Generate all possible positions for an oil field\nvector<pair<int,int>> get_positions(const OilField& field) {\n    vector<pair<int,int>> positions;\n    int max_i = 0, max_j = 0;\n    for (auto [di,dj] : field.relative) {\n        max_i = max(max_i, di);\n        max_j = max(max_j, dj);\n    }\n    for (int i = 0; i + max_i < N; i++) {\n        for (int j = 0; j + max_j < N; j++) {\n            positions.push_back({i,j});\n        }\n    }\n    return positions;\n}\n\n// Check if a position is valid given current knowledge\nbool is_valid_position(const OilField& field, int pi, int pj, \n                       const set<pair<int,int>>& must_have_oil,\n                       const set<pair<int,int>>& no_oil) {\n    for (auto [di,dj] : field.relative) {\n        int ni = pi + di, nj = pj + dj;\n        if (no_oil.count({ni,nj})) return false;\n    }\n    // Check if all must-have oil cells are covered\n    for (auto [i,j] : must_have_oil) {\n        bool covered = false;\n        for (auto [di,dj] : field.relative) {\n            if (pi + di == i && pj + dj == j) {\n                covered = true;\n                break;\n            }\n        }\n        if (!covered) return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    string line;\n    getline(cin, line);\n    stringstream ss(line);\n    ss >> N >> M >> eps;\n    \n    fields.resize(M);\n    for (int k = 0; k < M; k++) {\n        getline(cin, line);\n        stringstream ss2(line);\n        int d;\n        ss2 >> d;\n        fields[k].id = k;\n        fields[k].relative.resize(d);\n        int min_i = N, min_j = N;\n        for (int t = 0; t < d; t++) {\n            ss2 >> fields[k].relative[t].first >> fields[k].relative[t].second;\n            min_i = min(min_i, fields[k].relative[t].first);\n            min_j = min(min_j, fields[k].relative[t].second);\n        }\n        // Normalize\n        for (auto& [i,j] : fields[k].relative) {\n            i -= min_i;\n            j -= min_j;\n        }\n        // Compute bounding box\n        int max_i = 0, max_j = 0;\n        for (auto [i,j] : fields[k].relative) {\n            max_i = max(max_i, i);\n            max_j = max(max_j, j);\n        }\n        fields[k].h = max_i + 1;\n        fields[k].w = max_j + 1;\n    }\n    \n    // Phase 1: Initial exploration with divination\n    // We'll query rows and columns to get an initial estimate\n    vector<vector<double>> prob(N, vector<double>(N, 0.5));\n    vector<vector<int>> query_count(N, vector<int>(N, 0));\n    \n    // Query all rows\n    vector<double> row_sum(N, 0);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) {\n            row.push_back({i,j});\n        }\n        row_sum[i] = query_set(row);\n    }\n    \n    // Query all columns\n    vector<double> col_sum(N, 0);\n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) {\n            col.push_back({i,j});\n        }\n        col_sum[j] = query_set(col);\n    }\n    \n    // Estimate oil density from row/col sums\n    double total_oil = 0;\n    for (int i = 0; i < N; i++) total_oil += row_sum[i];\n    double avg_oil = total_oil / (N * N);\n    \n    // Use row/col sums to estimate cell probabilities\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            // Simple tomographic reconstruction\n            double estimate = (row_sum[i] + col_sum[j]) / 2.0;\n            prob[i][j] = estimate / max(N,1);\n            prob[i][j] = max(0.0, min(1.0, prob[i][j]));\n        }\n    }\n    \n    // Phase 2: Refine with targeted queries\n    // Find cells with high probability and drill them\n    const int MAX_DRILLS = (2 * N * N) / 3; // leave room for final guess\n    int drills_done = 0;\n    \n    // Sort cells by probability\n    vector<tuple<double,int,int>> cells_by_prob;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cells_by_prob.push_back({prob[i][j], i, j});\n        }\n    }\n    sort(cells_by_prob.rbegin(), cells_by_prob.rend());\n    \n    // Drill cells with high probability\n    int ops_used = 2 * N; // for row/col queries\n    for (auto [p, i, j] : cells_by_prob) {\n        if (drills_done >= MAX_DRILLS) break;\n        if (ops_used + 1 > 2 * N * N) break;\n        \n        int val = query_cell(i, j);\n        ops_used++;\n        drills_done++;\n        \n        if (val > 0) {\n            known_oil.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n        }\n    }\n    \n    // Phase 3: Constraint propagation using known shapes\n    // For each oil field, find possible positions\n    vector<pair<int,int>> field_positions[M];\n    for (int k = 0; k < M; k++) {\n        for (int pi = 0; pi + fields[k].h <= N; pi++) {\n            for (int pj = 0; pj + fields[k].w <= N; pj++) {\n                if (is_valid_position(fields[k], pi, pj, known_oil, known_dry)) {\n                    // Additional check: does this position cover any known dry cells?\n                    bool valid = true;\n                    for (auto [di,dj] : fields[k].relative) {\n                        int ni = pi + di, nj = pj + dj;\n                        if (known_dry.count({ni,nj})) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                    if (valid) {\n                        field_positions[k].push_back({pi,pj});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Generate final guess\n    // Use iterative refinement to find a consistent configuration\n    set<pair<int,int>> final_guess = known_oil;\n    \n    // Try to find any remaining oil cells by checking cells adjacent to known oil\n    // that could be part of a polyomino\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (known_oil.count({i,j}) || known_dry.count({i,j})) continue;\n            \n            // Check if this cell could be oil based on field positions\n            bool could_be_oil = false;\n            for (int k = 0; k < M; k++) {\n                for (auto [pi,pj] : field_positions[k]) {\n                    for (auto [di,dj] : fields[k].relative) {\n                        if (pi + di == i && pj + dj == j) {\n                            could_be_oil = true;\n                            break;\n                        }\n                    }\n                    if (could_be_oil) break;\n                }\n                if (could_be_oil) break;\n            }\n            \n            if (could_be_oil) {\n                final_guess.insert({i,j});\n            }\n        }\n    }\n    \n    // Make the guess\n    if (ops_used + 1 <= 2 * N * N) {\n        make_guess(final_guess);\n    }\n    \n    return 0;\n}","ahc031":"","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MOD = 998244353;\nconst int N = 9;\nconst int STAMP_SIZE = 3;\n\nstruct Operation {\n    int m, p, q;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_actual, M, K;\n    cin >> N_actual >> M >> K;\n    \n    // Initialize board\n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    // Read stamps\n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(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 >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<Operation> operations;\n    \n    // Greedy improvement: try all possible placements and choose best\n    for (int op = 0; op < K; op++) {\n        double best_improvement = -1e9;\n        Operation best_op = {0, 0, 0};\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                    double improvement = 0;\n                    \n                    // Evaluate improvement for this placement\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long current_val = board[p + i][q + j];\n                            long long current_rem = current_val % MOD;\n                            \n                            // Target: get as close to MOD-1 as possible\n                            long long ideal_add = (MOD - 1 - current_rem + MOD) % MOD;\n                            \n                            // How much does adding this stamp help?\n                            long long stamp_val = stamps[m][i][j] % MOD;\n                            if (stamp_val == 0) continue;\n                            \n                            // We can add stamp multiple times effectively\n                            // But here we consider one operation at a time\n                            long long new_rem = (current_rem + stamp_val) % MOD;\n                            long long improvement_cell = new_rem - current_rem;\n                            \n                            // Consider cyclic nature: going from near MOD to 0 is bad\n                            // Going from near 0 to near MOD-1 is good\n                            if (new_rem < current_rem) {\n                                // Wrapped around - this is usually bad unless we break through\n                                improvement_cell = new_rem + MOD - current_rem;\n                            }\n                            \n                            improvement += improvement_cell;\n                        }\n                    }\n                    \n                    // Prioritize cells that are far from optimal\n                    // Add bonus for helping cells that are very far from MOD-1\n                    double bonus = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long current_rem = board[p + i][q + j] % MOD;\n                            long long gap = (MOD - 1 - current_rem + MOD) % MOD;\n                            bonus += gap * 0.01;  // Small bonus for helping bad cells\n                        }\n                    }\n                    \n                    improvement += bonus;\n                    \n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_op = {m, p, q};\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation\n        int m = best_op.m, p = best_op.p, q = best_op.q;\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[p + i][q + j] += stamps[m][i][j];\n            }\n        }\n        operations.push_back(best_op);\n    }\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << op.m << \" \" << op.p << \" \" << op.q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N = 5;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Each string for the 5 cranes\n    vector<string> ops(N);\n    \n    // Precompute where each container needs to go\n    vector<vector<int>> targetRow(N*N), targetCol(N*N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int container = i*N + j;\n            targetRow[container] = i;\n            targetCol[container] = 4; // dispatch gate column\n        }\n    }\n    \n    // Track positions of cranes\n    vector<int> craneRow(N, 0), craneCol(N, 0);\n    for (int i = 0; i < N; i++) {\n        craneRow[i] = i;\n        craneCol[i] = 0;\n    }\n    \n    // Track which containers have been received\n    vector<int> receivedRow(N, 0);\n    // Track which containers have been dispatched\n    vector<bool> dispatched(N*N, false);\n    // Track containers on grid (row, col) -> container number, -1 if empty\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    // Track which container each crane is holding, -1 if empty\n    vector<int> holding(N, -1);\n    \n    // Next container to dispatch per row\n    vector<int> nextDispatch(N, 0);\n    \n    // Main simulation\n    const int MAX_TURNS = 10000;\n    int turns = 0;\n    \n    auto moveCrane = [&](int crane, int nr, int nc) {\n        int r = craneRow[crane], c = craneCol[crane];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n        if (grid[nr][nc] != -1 && holding[crane] != -1 && crane > 0) return false;\n        if (grid[nr][nc] != -1 && holding[crane] != -1 && crane == 0) {\n            // Large crane can move to occupied squares\n        }\n        // Check for crane at destination\n        for (int i = 0; i < N; i++) {\n            if (i != crane && craneRow[i] == nr && craneCol[i] == nc) return false;\n        }\n        // Check for swapping\n        for (int i = 0; i < N; i++) {\n            if (i != crane && craneRow[i] == nr && craneCol[i] == nc) return false;\n            if (i != crane && craneRow[i] == r && craneCol[i] == c) return false;\n        }\n        return true;\n    };\n    \n    vector<int> nextReceiving(N, 0);\n    \n    // Simple strategy: \n    // Small cranes stay near their dispatch gates, large crane fetches containers\n    for (int turn = 0; turn < MAX_TURNS && turns < MAX_TURNS; turn++) {\n        // Place new containers at receiving gates if possible\n        for (int i = 0; i < N; i++) {\n            if (nextReceiving[i] < N && grid[i][0] == -1) {\n                bool craneHere = false;\n                for (int j = 0; j < N; j++) {\n                    if (craneRow[j] == i && craneCol[j] == 0) {\n                        craneHere = true;\n                        break;\n                    }\n                }\n                if (!craneHere) {\n                    grid[i][0] = A[i][nextReceiving[i]];\n                    nextReceiving[i]++;\n                }\n            }\n        }\n        \n        // Dispatch containers at gates\n        for (int i = 0; i < N; i++) {\n            if (grid[i][4] != -1) {\n                int container = grid[i][4];\n                int expectedRow = container / N;\n                if (expectedRow == i && container % N == nextDispatch[i]) {\n                    dispatched[container] = true;\n                    grid[i][4] = -1;\n                    nextDispatch[i]++;\n                }\n            }\n        }\n        \n        // Control each crane\n        for (int crane = 0; crane < N; crane++) {\n            int r = craneRow[crane], c = craneCol[crane];\n            char action = '.';\n            \n            if (crane == 0) {\n                // Large crane: fetch containers from left, deliver to correct rows\n                if (holding[crane] == -1) {\n                    // Look for container to pick up\n                    if (grid[r][c] != -1 && nextReceiving[r] > 0) {\n                        int container = grid[r][c];\n                        int targetR = container / N;\n                        if (c < 2) {\n                            action = 'R';\n                        } else if (c < 4) {\n                            if (r < targetR) action = 'D';\n                            else if (r > targetR) action = 'U';\n                            else if (c < 4) action = 'R';\n                        }\n                        if (action == '.') {\n                            // Try to pick up container\n                            if (grid[r][c] != -1) {\n                                action = 'P';\n                                holding[crane] = grid[r][c];\n                                grid[r][c] = -1;\n                            }\n                        }\n                    } else {\n                        // Move to right to find containers\n                        if (c < 4 && grid[r][c+1] == -1) action = 'R';\n                        else if (c > 0 && grid[r][c-1] == -1) action = 'L';\n                        else if (r < 4 && grid[r+1][c] == -1) action = 'D';\n                        else if (r > 0 && grid[r-1][c] == -1) action = 'U';\n                    }\n                } else {\n                    // Holding container, deliver to correct row\n                    int container = holding[crane];\n                    int targetR = container / N;\n                    if (r == targetR && c == 4) {\n                        // Drop at correct dispatch gate\n                        if (grid[r][c] == -1) {\n                            if (nextDispatch[targetR] == container % N) {\n                                action = 'Q';\n                                grid[r][c] = container;\n                                holding[crane] = -1;\n                            }\n                        }\n                    } else {\n                        // Move towards target\n                        if (c < 4 && moveCrane(crane, r, c+1)) action = 'R';\n                        else if (c > 0 && moveCrane(crane, r, c-1)) action = 'L';\n                        else if (r < targetR && moveCrane(crane, r+1, c)) action = 'D';\n                        else if (r > targetR && moveCrane(crane, r-1, c)) action = 'U';\n                        else if (c < 4) action = 'R';\n                    }\n                }\n            } else {\n                // Small crane: sort within its row\n                if (holding[crane] == -1) {\n                    // Pick up container that belongs to other row\n                    bool foundContainer = false;\n                    for (int col = 0; col < 4 && !foundContainer; col++) {\n                        if (grid[r][col] != -1 && grid[r][col] / N != r) {\n                            // Move towards it\n                            if (c < col && moveCrane(crane, r, c+1)) action = 'R';\n                            else if (c > col && moveCrane(crane, r, c-1)) action = 'L';\n                            else if (r < 4 && moveCrane(crane, r+1, c)) action = 'D';\n                            else if (r > 0 && moveCrane(crane, r-1, c)) action = 'U';\n                            else if (c == col) {\n                                action = 'P';\n                                holding[crane] = grid[r][c];\n                                grid[r][c] = -1;\n                            }\n                            foundContainer = true;\n                        }\n                    }\n                    if (!foundContainer) {\n                        // Move around near dispatch gate\n                        if (c < 3 && moveCrane(crane, r, c+1)) action = 'R';\n                        else if (c > 0 && moveCrane(crane, r, c-1)) action = 'L';\n                    }\n                } else {\n                    // Holding container, deliver to dispatch gate of correct row\n                    int container = holding[crane];\n                    int targetR = container / N;\n                    if (targetR == r) {\n                        // Belongs to our row\n                        if (c < 4) {\n                            if (moveCrane(crane, r, c+1)) action = 'R';\n                        }\n                        if (c == 4 && grid[r][4] == -1) {\n                            if (nextDispatch[r] == container % N) {\n                                action = 'Q';\n                                grid[r][4] = container;\n                                holding[crane] = -1;\n                            }\n                        }\n                    } else {\n                        // Need to give to large crane or move to correct row\n                        if (r < targetR && moveCrane(crane, r+1, c)) action = 'D';\n                        else if (r > targetR && moveCrane(crane, r-1, c)) action = 'U';\n                        else if (c < 4 && moveCrane(crane, r, c+1)) action = 'R';\n                        else if (c > 0 && moveCrane(crane, r, c-1)) action = 'L';\n                    }\n                }\n            }\n            \n            // Execute action\n            if (action == 'R' && moveCrane(crane, r, c+1)) {\n                craneRow[crane] = r;\n                craneCol[crane] = c+1;\n            } else if (action == 'L' && moveCrane(crane, r, c-1)) {\n                craneRow[crane] = r;\n                craneCol[crane] = c-1;\n            } else if (action == 'U' && moveCrane(crane, r-1, c)) {\n                craneRow[crane] = r-1;\n                craneCol[crane] = c;\n            } else if (action == 'D' && moveCrane(crane, r+1, c)) {\n                craneRow[crane] = r+1;\n                craneCol[crane] = c;\n            } else if (action == 'P') {\n                if (grid[r][c] != -1 && holding[crane] == -1) {\n                    holding[crane] = grid[r][c];\n                    grid[r][c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (grid[r][c] == -1 && holding[crane] != -1) {\n                    grid[r][c] = holding[crane];\n                    holding[crane] = -1;\n                    // Check if immediately dispatchable\n                    if (r == c && grid[r][4] != -1) {\n                        int container = grid[r][4];\n                        int expectedRow = container / N;\n                        if (expectedRow == r && container % N == nextDispatch[r]) {\n                            dispatched[container] = true;\n                            grid[r][4] = -1;\n                            nextDispatch[r]++;\n                        }\n                    }\n                }\n            }\n            \n            ops[crane] += action;\n        }\n        turns++;\n    }\n    \n    // Normalize lengths\n    int maxLen = 0;\n    for (int i = 0; i < N; i++) {\n        maxLen = max(maxLen, (int)ops[i].length());\n    }\n    for (int i = 0; i < N; i++) {\n        while ((int)ops[i].length() < maxLen) {\n            ops[i] += '.';\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << ops[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\nconst int MAX_TURNS = 100000;\n\n// Directions: up, down, left, right\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    // Truck position and load\n    int x = 0, y = 0;\n    int load = 0;\n    vector<string> ops;\n    \n    // BFS to find shortest path\n    auto find_path = [&](int sx, int sy, int tx, int ty) -> vector<pair<int,int>> {\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n        queue<pair<int,int>> q;\n        \n        dist[sx][sy] = 0;\n        q.push({sx, sy});\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            if (cx == tx && cy == ty) break;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cx + dx[d], ny = cy + dy[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] > dist[cx][cy] + 1) {\n                    dist[nx][ny] = dist[cx][cy] + 1;\n                    prev[nx][ny] = {cx, cy};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        // Reconstruct path\n        vector<pair<int,int>> path;\n        int cx = tx, cy = ty;\n        while (cx != sx || cy != sy) {\n            path.push_back({cx, cy});\n            auto [px, py] = prev[cx][cy];\n            cx = px; cy = py;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    // Get direction char for movement\n    auto get_dir = [&](int from_x, int from_y, int to_x, int to_y) -> char {\n        for (int d = 0; d < 4; d++) {\n            if (from_x + dx[d] == to_x && from_y + dy[d] == to_y) {\n                return dir_char[d];\n            }\n        }\n        return '?';\n    };\n    \n    // Process sources and sinks\n    // First, let's collect all sources (positive) and sinks (negative)\n    vector<tuple<int,int,int>> sources; // x, y, amount\n    vector<tuple<int,int,int>> sinks;   // x, y, amount\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (h[i][j] > 0) {\n                sources.push_back({i, j, h[i][j]});\n            } else if (h[i][j] < 0) {\n                sinks.push_back({i, j, -h[i][j]});\n            }\n        }\n    }\n    \n    // Sort sources by distance from (0,0) or current position\n    // Process sources from farthest to nearest to minimize backtracking\n    sort(sources.begin(), sources.end(), [&](const auto& a, const auto& b) {\n        int x1 = get<0>(a), y1 = get<1>(a);\n        int x2 = get<0>(b), y2 = get<1>(b);\n        return abs(x1) + abs(y1) > abs(x2) + abs(y2); // Process farthest first\n    });\n    \n    // For each source, find nearest sink\n    for (auto& src : sources) {\n        auto [sx, sy, amount] = src;\n        \n        if (amount <= 0) continue;\n        \n        // Move to source\n        if (x != sx || y != sy) {\n            auto path = find_path(x, y, sx, sy);\n            for (auto [px, py] : path) {\n                char dir = get_dir(x, y, px, py);\n                ops.push_back(string(1, dir));\n                x = px; y = py;\n            }\n        }\n        \n        // Find nearest sink\n        int best_dist = INF;\n        int best_sink_idx = -1;\n        for (int k = 0; k < (int)sinks.size(); k++) {\n            auto [tx, ty, need] = sinks[k];\n            if (need <= 0) continue;\n            int dist = abs(x - tx) + abs(y - ty);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_sink_idx = k;\n            }\n        }\n        \n        if (best_sink_idx == -1) break; // No more sinks\n        \n        auto& sink = sinks[best_sink_idx];\n        auto [tx, ty, need] = sink;\n        \n        // Determine how much to carry (limit by capacity/turns)\n        // We'll carry the minimum of source amount, sink need, or some reasonable batch\n        int carry = min(amount, need);\n        // Also limit to 1000 per trip to avoid huge numbers\n        carry = min(carry, 1000);\n        \n        // Load\n        if (carry > 0) {\n            ops.push_back(\"+\" + to_string(carry));\n            load += carry;\n            amount -= carry;\n            get<2>(src) = amount;\n        }\n        \n        // Move to sink\n        if (load > 0) {\n            auto path = find_path(x, y, tx, ty);\n            for (auto [px, py] : path) {\n                char dir = get_dir(x, y, px, py);\n                ops.push_back(string(1, dir));\n                x = px; y = py;\n            }\n            \n            // Unload\n            ops.push_back(\"-\" + to_string(load));\n            need -= load;\n            get<2>(sink) = need;\n            load = 0;\n        }\n        \n        // If source still has more, put it back\n        if (amount > 0) {\n            sources.push_back({sx, sy, amount});\n        }\n    }\n    \n    // Output\n    for (const string& op : ops) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Seed {\n    vector<int> values;\n    int total;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<Seed> seeds(seed_count);\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        seeds[i].values.resize(M);\n        seeds[i].index = i;\n        seeds[i].total = 0;\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i].values[j];\n            seeds[i].total += seeds[i].values[j];\n        }\n    }\n    \n    // Precompute grid positions and their neighbor counts\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            positions.push_back({i, j});\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Sort seeds by total value descending\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return seeds[a].total > seeds[b].total;\n        });\n        \n        // Create placement grid\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Priority positions (center first for more neighbors)\n        vector<pair<int, int>> priority_positions;\n        // Center positions have 4 neighbors\n        for (int i = 1; i < N-1; i++) {\n            for (int j = 1; j < N-1; j++) {\n                priority_positions.push_back({i, j});\n            }\n        }\n        // Edge positions (non-corner) have 3 neighbors\n        for (int i = 1; i < N-1; i++) {\n            priority_positions.push_back({i, 0});\n            priority_positions.push_back({i, N-1});\n            priority_positions.push_back({0, i});\n            priority_positions.push_back({N-1, i});\n        }\n        // Corner positions have 2 neighbors\n        priority_positions.push_back({0, 0});\n        priority_positions.push_back({0, N-1});\n        priority_positions.push_back({N-1, 0});\n        priority_positions.push_back({N-1, N-1});\n        \n        // Place best seeds in priority positions\n        int seed_idx = 0;\n        for (auto pos : priority_positions) {\n            if (seed_idx >= seed_count) break;\n            int seed_num = order[seed_idx];\n            if (!used[seed_num]) {\n                grid[pos.first][pos.second] = seed_num;\n                used[seed_num] = true;\n                seed_idx++;\n            }\n        }\n        \n        // Fill remaining positions\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == -1) {\n                    while (seed_idx < seed_count && used[order[seed_idx]]) {\n                        seed_idx++;\n                    }\n                    if (seed_idx < seed_count) {\n                        grid[i][j] = order[seed_idx];\n                        used[order[seed_idx]] = true;\n                        seed_idx++;\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 << grid[i][j];\n                if (j < N-1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            seeds[i].total = 0;\n            seeds[i].index = i;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].values[j];\n                seeds[i].total += seeds[i].values[j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Structure to represent position\nstruct Pos {\n    int x, y;\n    Pos(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Pos& p) const { return x == p.x && y == p.y; }\n};\n\n// Direction vectors\nconst int dx[] = {0, 1, 0, -1};\nconst int dy[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nclass RoboticArmSolver {\nprivate:\n    int N, M, V;\n    vector<vector<int>> initial_grid, target_grid;\n    vector<Pos> takoyaki_pos, target_pos;\n    \n    // Arm structure\n    int V_actual;\n    vector<int> parent;\n    vector<int> edge_length;\n    vector<int> rotation_state; // 0: right, 1: down, 2: left, 3: up\n    \n    // Current state\n    Pos root_pos;\n    bool holding[15]; // which fingertips are holding\n    \npublic:\n    RoboticArmSolver() {\n        read_input();\n        solve();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> V;\n        initial_grid = vector<vector<int>>(N, vector<int>(N));\n        target_grid = vector<vector<int>>(N, vector<int>(N));\n        \n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                initial_grid[i][j] = line[j] - '0';\n                if (initial_grid[i][j]) {\n                    takoyaki_pos.push_back(Pos(i, j));\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target_grid[i][j] = line[j] - '0';\n                if (target_grid[i][j]) {\n                    target_pos.push_back(Pos(i, j));\n                }\n            }\n        }\n    }\n    \n    // Calculate fingertip positions given root position and rotation states\n    vector<Pos> get_fingertip_positions() {\n        vector<Pos> finger_pos;\n        vector<tuple<int, int, int>> stack; // vertex, x, y, rotation_sum\n        // Rotation sum represents cumulative rotation from root to this vertex\n        \n        for (int v = 0; v < V_actual; v++) {\n            if (v == 0) {\n                stack.push_back({0, root_pos.x, root_pos.y, 0});\n            } else {\n                // Find parent's position\n                auto it = find_if(stack.begin(), stack.end(), \n                    [this, v](const auto& t) { return get<0>(t) == parent[v]; });\n                \n                int px = get<1>(*it);\n                int py = get<2>(*it);\n                int prot = get<3>(*it);\n                \n                int my_rot = (prot + rotation_state[v]) % 4;\n                int dir = (my_rot * 3) % 4; // Initial direction is right, then rotate\n                \n                // For simplicity, use a tree that extends right then down\n                int cx = px, cy = py;\n                if (v % 2 == 1) { // Extend right\n                    cx += dx[my_rot] * edge_length[v];\n                    cy += dy[my_rot] * edge_length[v];\n                } else if (v > 0) { // Extend down\n                    cx += dx[(my_rot + 1) % 4] * edge_length[v];\n                    cy += dy[(my_rot + 1) % 4] * edge_length[v];\n                }\n                \n                stack.push_back({v, cx, cy, my_rot});\n            }\n        }\n        \n        // Leaves are fingertips\n        for (int v = 0; v < V_actual; v++) {\n            bool is_leaf = true;\n            for (int u = 1; u < V_actual; u++) {\n                if (parent[u] == v) {\n                    is_leaf = false;\n                    break;\n                }\n            }\n            if (is_leaf) {\n                auto it = find_if(stack.begin(), stack.end(),\n                    [v](const auto& t) { return get<0>(t) == v; });\n                finger_pos.push_back(Pos(get<1>(*it), get<2>(*it)));\n            }\n        }\n        \n        return finger_pos;\n    }\n    \n    // Design the robotic arm\n    void design_arm() {\n        V_actual = V;\n        parent.resize(V_actual);\n        edge_length.resize(V_actual);\n        rotation_state.resize(V_actual, 0);\n        \n        // Create a tree where:\n        // - Node 0 is root\n        // - Nodes 1..V-1 form a star or small tree\n        // - Each edge has length N-1 for maximum reach\n        \n        parent[0] = -1;\n        edge_length[0] = 0;\n        \n        for (int v = 1; v < V_actual; v++) {\n            // Connect to root or previous node\n            parent[v] = (v <= 4) ? 0 : (v - 4);\n            \n            // Use maximum length for better reach\n            if (v <= 4) {\n                edge_length[v] = N - 1;\n            } else {\n                edge_length[v] = 1;\n            }\n        }\n        \n        // Output arm design\n        cout << V_actual << endl;\n        for (int v = 1; v < V_actual; v++) {\n            cout << parent[v] << \" \" << edge_length[v] << endl;\n        }\n    }\n    \n    // Simple greedy matching of takoyaki to targets\n    vector<pair<int, int>> match_takoyaki() {\n        vector<pair<int, int>> assignment(M);\n        vector<bool> target_used(M, false);\n        \n        // For each takoyaki, find nearest unused target\n        for (int i = 0; i < M; i++) {\n            int best_j = -1;\n            int best_dist = 1e9;\n            \n            for (int j = 0; j < M; j++) {\n                if (!target_used[j]) {\n                    int dist = abs(takoyaki_pos[i].x - target_pos[j].x) \n                             + abs(takoyaki_pos[i].y - target_pos[j].y);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_j = j;\n                    }\n                }\n            }\n            \n            assignment[i] = {i, best_j};\n            target_used[best_j] = true;\n        }\n        \n        return assignment;\n    }\n    \n    // Generate movement commands\n    void generate_commands() {\n        auto assignment = match_takoyaki();\n        vector<bool> delivered(M, false);\n        vector<int> current_pos_idx(M, -1); // -1 means holding\n        \n        // Initialize fingertips at position (0,0) with default rotation\n        root_pos = Pos(0, 0);\n        \n        // For each takoyaki, move it to its target\n        for (int turn = 0; turn < 100000 && !all_of(delivered.begin(), delivered.end(), [](bool b){return b;}); turn++) {\n            string command(2 * V_actual, '.');\n            \n            // Find current fingertip positions\n            auto finger_pos = get_fingertip_positions();\n            \n            // Determine movement direction\n            int target_takoyaki = -1;\n            int min_dist = 1e9;\n            \n            // Find nearest undelivered takoyaki\n            for (int i = 0; i < M; i++) {\n                if (!delivered[i]) {\n                    int dist = abs(root_pos.x - takoyaki_pos[i].x) \n                             + abs(root_pos.y - takoyaki_pos[i].y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        target_takoyaki = i;\n                    }\n                }\n            }\n            \n            if (target_takoyaki >= 0) {\n                // Move towards the takoyaki/target\n                Pos target = (holding[0]) ? target_pos[assignment[target_takoyaki].second] \n                                         : takoyaki_pos[target_takoyaki];\n                \n                if (root_pos.x < target.x) command[0] = 'D';\n                else if (root_pos.x > target.x) command[0] = 'U';\n                else if (root_pos.y < target.y) command[0] = 'R';\n                else if (root_pos.y > target.y) command[0] = 'L';\n                \n                // Update root position\n                if (command[0] != '.') {\n                    switch(command[0]) {\n                        case 'U': root_pos.x--; break;\n                        case 'D': root_pos.x++; break;\n                        case 'L': root_pos.y--; break;\n                        case 'R': root_pos.y++; break;\n                    }\n                }\n            }\n            \n            // Try to grab/release\n            for (int f = 0; f < V_actual; f++) {\n                bool is_leaf = true;\n                for (int u = 1; u < V_actual; u++) {\n                    if (parent[u] == f) {\n                        is_leaf = false;\n                        break;\n                    }\n                }\n                \n                if (is_leaf && f < (int)finger_pos.size()) {\n                    Pos fp = finger_pos[f];\n                    if (fp.x >= 0 && fp.x < N && fp.y >= 0 && fp.y < N) {\n                        // Check if we should grab\n                        for (int i = 0; i < M; i++) {\n                            if (!delivered[i] && fp == takoyaki_pos[i] && !holding[f]) {\n                                command[V_actual + f] = 'P';\n                                holding[f] = true;\n                                break;\n                            }\n                            // Check if we should release\n                            if (holding[f] && fp == target_pos[assignment[i].second] && !delivered[i]) {\n                                command[V_actual + f] = 'P';\n                                holding[f] = false;\n                                delivered[i] = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n        \n        // Fill remaining turns if needed\n        for (int turn = 100000; turn > 0 && turn > 0; turn--) {\n            string command(2 * V_actual, '.');\n            cout << command << endl;\n        }\n    }\n    \n    void solve() {\n        design_arm();\n        \n        // Initial position\n        cout << 0 << \" \" << 0 << endl;\n        \n        generate_commands();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    RoboticArmSolver solver;\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 5000;\n    vector<pair<int,int>> mackerel(N), sardine(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> mackerel[i].first >> mackerel[i].second;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sardine[i].first >> sardine[i].second;\n    }\n    \n    // Collect all unique coordinates for discretization\n    set<int> xs_set, ys_set;\n    for (auto& p : mackerel) {\n        xs_set.insert(p.first);\n        ys_set.insert(p.second);\n    }\n    for (auto& p : sardine) {\n        xs_set.insert(p.first);\n        ys_set.insert(p.second);\n    }\n    \n    vector<int> xs(xs_set.begin(), xs_set.end());\n    vector<int> ys(ys_set.begin(), ys_set.end());\n    \n    int H = xs.size(), W = ys.size();\n    \n    // Build grid with fish values\n    vector<vector<int>> grid(H, vector<int>(W, 0));\n    for (auto& p : mackerel) {\n        int ix = lower_bound(xs.begin(), xs.end(), p.first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), p.second) - ys.begin();\n        grid[ix][iy] = 1;\n    }\n    for (auto& p : sardine) {\n        int ix = lower_bound(xs.begin(), xs.end(), p.first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), p.second) - ys.begin();\n        grid[ix][iy] = -1;\n    }\n    \n    // 2D prefix sum\n    vector<vector<int>> pref(H+1, vector<int>(W+1, 0));\n    for (int i = 1; i <= H; i++) {\n        for (int j = 1; j <= W; j++) {\n            pref[i][j] = pref[i-1][j] + pref[i][j-1] - pref[i-1][j-1] + grid[i-1][j-1];\n        }\n    }\n    \n    auto rect_sum = [&](int r1, int c1, int r2, int c2) {\n        return pref[r2+1][c2+1] - pref[r1][c2+1] - pref[r2+1][c1] + pref[r1][c1];\n    };\n    \n    // Find best rectangle using multiple candidates\n    // Try different regions and pick the best\n    vector<tuple<int,int,int,int>> candidates;\n    \n    // Try each cell as a starting point with some window\n    int step = max(1, H / 20);  // Sample grid coarsely\n    for (int i = 0; i < H; i += step) {\n        for (int j = 0; j < W; j += step) {\n            // Try to expand rectangle from this point\n            int best_sum = -1e9, best_i2 = i, best_j2 = j;\n            for (int i2 = i; i2 < min(H, i + 50); i2++) {\n                for (int j2 = j; j2 < min(W, j + 50); j2++) {\n                    int sum = rect_sum(i, j, i2, j2);\n                    if (sum > best_sum) {\n                        best_sum = sum;\n                        best_i2 = i2;\n                        best_j2 = j2;\n                    }\n                }\n            }\n            if (best_sum > 0) {\n                candidates.push_back({i, j, best_i2, best_j2});\n            }\n        }\n    }\n    \n    // Pick the best candidate\n    auto best = *max_element(candidates.begin(), candidates.end(), \n        [&](const auto& a, const auto& b) {\n            auto [r1,c1,r2,c2] = a;\n            auto [r3,c3,r4,c4] = b;\n            return rect_sum(r1,c1,r2,c2) < rect_sum(r3,c3,r4,c4);\n        });\n    \n    auto [r1, c1, r2, c2] = best;\n    \n    // Convert to actual coordinates with margin\n    int PAD = 1;\n    int x1 = max(0, xs[r1] - PAD);\n    int y1 = max(0, ys[c1] - PAD);\n    int x2 = min(100000, xs[r2] + PAD);\n    int y2 = min(100000, ys[c2] + PAD);\n    \n    // Ensure polygon has at least some area\n    if (x1 == x2) x2 = min(100000, x1 + 1);\n    if (y1 == y2) y2 = min(100000, y1 + 1);\n    \n    // Output rectangle\n    cout << \"4\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nstruct Rectangle {\n    int w, h;\n    int w_m, h_m; // measured values\n};\n\nint N, T, sigma;\nvector<Rectangle> rects;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n};\n\nstruct PackingResult {\n    vector<Placement> placements;\n    int width;\n    int height;\n    int score;\n    int unplaced_sum;\n};\n\n// Simulate a sequence of placements and return the actual dimensions\nPackingResult simulate_placement(const vector<Placement>& placements) {\n    // Track placed rectangles\n    vector<bool> placed(N, false);\n    vector<int> x(N), y(N), w(N), h(N);\n    \n    for (const auto& pl : placements) {\n        int idx = pl.p;\n        placed[idx] = true;\n        \n        int rw = rects[idx].w_m, rh = rects[idx].h_m;\n        if (pl.r) swap(rw, rh);\n        \n        w[idx] = rw;\n        h[idx] = rh;\n        \n        if (pl.d == 'U') {\n            // Align left edge with reference\n            int left_x = 0;\n            if (pl.b >= 0) {\n                left_x = x[pl.b] + w[pl.b];\n            }\n            \n            // Find lowest y where it fits without overlap\n            int best_y = 0;\n            for (int j = 0; j < idx; j++) {\n                if (!placed[j]) continue;\n                // Check if this rectangle overlaps horizontally\n                int rx = x[j], rw2 = w[j];\n                if (left_x < rx + rw2 && left_x + rw > rx) {\n                    best_y = max(best_y, y[j] + h[j]);\n                }\n            }\n            \n            x[idx] = left_x;\n            y[idx] = best_y;\n        } else { // 'L'\n            // Align top edge with reference\n            int top_y = 0;\n            if (pl.b >= 0) {\n                top_y = y[pl.b] + h[pl.b];\n            }\n            \n            // Find leftmost x where it fits without overlap\n            int best_x = 0;\n            for (int j = 0; j < idx; j++) {\n                if (!placed[j]) continue;\n                // Check if this rectangle overlaps vertically\n                int ry = y[j], rh2 = h[j];\n                if (top_y < ry + rh2 && top_y + rh > ry) {\n                    best_x = max(best_x, x[j] + w[j]);\n                }\n            }\n            \n            x[idx] = best_x;\n            y[idx] = top_y;\n        }\n    }\n    \n    // Calculate bounding box\n    int max_x = 0, max_y = 0;\n    int unplaced_sum = 0;\n    \n    for (int i = 0; i < N; i++) {\n        if (placed[i]) {\n            max_x = max(max_x, x[i] + w[i]);\n            max_y = max(max_y, y[i] + h[i]);\n        } else {\n            unplaced_sum += rects[i].w_m + rects[i].h_m;\n        }\n    }\n    \n    return {placements, max_x, max_y, max_x + max_y + unplaced_sum, unplaced_sum};\n}\n\n// Generate a packing using shelf algorithm\nvector<Placement> generate_shelf_packing(const vector<pair<int,int>>& order, \n                                         const vector<bool>& rotate) {\n    vector<Placement> result;\n    \n    // Track the \"skyline\" for placement\n    // For simplicity, use a simple shelf approach\n    \n    int current_x = 0, current_y = 0;\n    int shelf_height = 0;\n    \n    for (int i : order) {\n        if (i >= N) continue;\n        \n        int idx = i;\n        int rw = rects[idx].w_m, rh = rects[idx].h_m;\n        if (rotate[idx]) swap(rw, rh);\n        \n        // Try to place on current shelf\n        if (current_x + rw <= 1000000) { // reasonable width limit\n            Placement pl;\n            pl.p = idx;\n            pl.r = rotate[idx];\n            pl.d = 'U';\n            pl.b = (result.empty() ? -1 : result.back().p);\n            result.push_back(pl);\n            current_x += rw;\n            shelf_height = max(shelf_height, rh);\n        } else {\n            // Start new shelf\n            Placement pl;\n            pl.p = idx;\n            pl.r = rotate[idx];\n            pl.d = 'L';\n            pl.b = -1;\n            result.push_back(pl);\n            current_x = rw;\n            current_y += shelf_height;\n            shelf_height = rh;\n        }\n    }\n    \n    return result;\n}\n\nvoid query_and_get_result(const vector<Placement>& placements, \n                          int& W, int& H) {\n    cout << placements.size() << endl;\n    for (const auto& pl : placements) {\n        cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << endl;\n    }\n    cout.flush();\n    cin >> W >> H;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> T >> sigma;\n    rects.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w_m >> rects[i].h_m;\n    }\n    \n    int best_score = 2e9;\n    vector<Placement> best_placements;\n    \n    // Strategy 1: Sort by measured height, try both orientations\n    vector<pair<int,int>> height_order;\n    for (int i = 0; i < N; i++) {\n        height_order.push_back({rects[i].h_m, i});\n    }\n    sort(height_order.begin(), height_order.end());\n    \n    // Strategy 2: Sort by measured width\n    vector<pair<int,int>> width_order;\n    for (int i = 0; i < N; i++) {\n        width_order.push_back({rects[i].w_m, i});\n    }\n    sort(width_order.begin(), width_order.end());\n    \n    for (int turn = 0; turn < T; turn++) {\n        // Try multiple strategies each turn\n        int W, H;\n        \n        // Strategy: try different orderings and rotations\n        for (int attempt = 0; attempt < 10; attempt++) {\n            vector<bool> rotate(N, false);\n            vector<pair<int,int>> order;\n            \n            // Vary ordering based on attempt\n            if (attempt < 3) {\n                // Use height-based ordering\n                order = height_order;\n                if (attempt == 1) {\n                    // Swap some orientations\n                    for (int i = 0; i < N; i += 2) {\n                        if (rects[i].w_m > rects[i].h_m) {\n                            rotate[i] = true;\n                        }\n                    }\n                }\n            } else if (attempt < 6) {\n                // Use width-based ordering\n                order = width_order;\n                if (attempt == 4) {\n                    for (int i = 0; i < N; i += 2) {\n                        if (rects[i].h_m > rects[i].w_m) {\n                            rotate[i] = true;\n                        }\n                    }\n                }\n            } else {\n                // Random ordering\n                order.clear();\n                for (int i = 0; i < N; i++) order.push_back({0, i});\n                shuffle(order.begin(), order.end(), rng);\n                for (int i = 0; i < N; i++) {\n                    rotate[order[i].second] = (rng() % 2);\n                }\n            }\n            \n            auto placements = generate_shelf_packing(order, rotate);\n            auto result = simulate_placement(placements);\n            \n            if (result.score < best_score) {\n                best_score = result.score;\n                best_placements = placements;\n                \n                // Actually output this one\n                query_and_get_result(placements, W, H);\n                cout.flush();\n                goto next_turn;\n            }\n        }\n        \n        // If no improvement, try best known\n        {\n            query_and_get_result(best_placements, W, H);\n            cout.flush();\n        }\n        \n        next_turn:\n        // Use W, H for next iteration (though we don't use it much due to noise)\n        continue;\n    }\n    \n    return 0;\n}","ahc041":"","ahc042":"#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 = 20;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Find all Oni positions\n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // Precompute Fukunokami positions for quick checking\n    vector<vector<bool>> is_fuku(N, vector<bool>(N, false));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'o') {\n                is_fuku[i][j] = true;\n            }\n        }\n    }\n    \n    vector<string> ans;\n    \n    for (auto [oni_i, oni_j] : oni_positions) {\n        // Check clear directions and find the one with minimum operations\n        int best_ops = INT_MAX;\n        char best_dir = '?';\n        \n        // Check Up\n        bool clear_up = true;\n        for (int k = oni_i - 1; k >= 0; k--) {\n            if (is_fuku[k][oni_j]) {\n                clear_up = false;\n                break;\n            }\n        }\n        if (clear_up) {\n            int ops = 2 * (oni_i + 1);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'U';\n            }\n        }\n        \n        // Check Down\n        bool clear_down = true;\n        for (int k = oni_i + 1; k < N; k++) {\n            if (is_fuku[k][oni_j]) {\n                clear_down = false;\n                break;\n            }\n        }\n        if (clear_down) {\n            int ops = 2 * (N - oni_i);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'D';\n            }\n        }\n        \n        // Check Left\n        bool clear_left = true;\n        for (int k = oni_j - 1; k >= 0; k--) {\n            if (is_fuku[oni_i][k]) {\n                clear_left = false;\n                break;\n            }\n        }\n        if (clear_left) {\n            int ops = 2 * (oni_j + 1);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'L';\n            }\n        }\n        \n        // Check Right\n        bool clear_right = true;\n        for (int k = oni_j + 1; k < N; k++) {\n            if (is_fuku[oni_i][k]) {\n                clear_right = false;\n                break;\n            }\n        }\n        if (clear_right) {\n            int ops = 2 * (N - oni_j);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'R';\n            }\n        }\n        \n        // Perform the operations\n        if (best_dir == 'U') {\n            for (int t = 0; t < oni_i + 1; t++) {\n                ans.push_back(\"U \" + to_string(oni_j));\n            }\n            for (int t = 0; t < oni_i + 1; t++) {\n                ans.push_back(\"D \" + to_string(oni_j));\n            }\n        } else if (best_dir == 'D') {\n            for (int t = 0; t < N - oni_i; t++) {\n                ans.push_back(\"D \" + to_string(oni_j));\n            }\n            for (int t = 0; t < N - oni_i; t++) {\n                ans.push_back(\"U \" + to_string(oni_j));\n            }\n        } else if (best_dir == 'L') {\n            for (int t = 0; t < oni_j + 1; t++) {\n                ans.push_back(\"L \" + to_string(oni_i));\n            }\n            for (int t = 0; t < oni_j + 1; t++) {\n                ans.push_back(\"R \" + to_string(oni_i));\n            }\n        } else { // Right\n            for (int t = 0; t < N - oni_j; t++) {\n                ans.push_back(\"R \" + to_string(oni_i));\n            }\n            for (int t = 0; t < N - oni_j; t++) {\n                ans.push_back(\"L \" + to_string(oni_i));\n            }\n        }\n    }\n    \n    // Output the solution\n    for (const string& s : ans) {\n        cout << s << \"\\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 main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Input\n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    // Initialize a_i, b_i\n    vector<int> a(N), b(N);\n    \n    // Simple initial heuristic: distribute evenly\n    // For each employee, try to balance successors\n    for (int i = 0; i < N; i++) {\n        // Try to connect to employees with remaining capacity\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    \n    // Function to compute actual frequencies\n    auto simulate = [&]() -> vector<int> {\n        vector<int> freq(N, 0);\n        vector<int> visit_cnt(N, 0);\n        \n        int cur = 0;\n        freq[0]++;\n        visit_cnt[0]++;\n        \n        for (int week = 1; week < L; week++) {\n            int t = visit_cnt[cur];\n            if (t % 2 == 1) {\n                cur = a[cur];\n            } else {\n                cur = b[cur];\n            }\n            freq[cur]++;\n            visit_cnt[cur]++;\n        }\n        return freq;\n    };\n    \n    // Compute current frequencies\n    auto freq = simulate();\n    \n    // Compute error\n    auto compute_error = [&](const vector<int>& f) -> long long {\n        long long err = 0;\n        for (int i = 0; i < N; i++) {\n            err += abs(f[i] - T[i]);\n        }\n        return err;\n    };\n    \n    long long best_error = compute_error(freq);\n    vector<int> best_a = a, best_b = b;\n    \n    // Optimization: simulated annealing\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    double temp = 1000.0;\n    const double cooling = 0.999;\n    const int iterations = 100000;\n    \n    for (int iter = 0; iter < iterations && best_error > 0; iter++) {\n        // Randomly choose an employee and modify\n        int emp = rng() % N;\n        int old_a = a[emp], old_b = b[emp];\n        \n        // Random modification\n        int new_emp = rng() % N;\n        if (rng() % 2 == 0) {\n            a[emp] = new_emp;\n        } else {\n            b[emp] = new_emp;\n        }\n        \n        // Simulate new frequencies\n        auto new_freq = simulate();\n        long long new_error = compute_error(new_freq);\n        \n        if (new_error < best_error || \n            (new_error < best_error + 5 && (double)rng() / UINT32_MAX < exp((best_error - new_error) / temp))) {\n            // Accept\n            best_error = new_error;\n            best_a = a;\n            best_b = b;\n            freq = new_freq;\n        } else {\n            // Revert\n            a[emp] = old_a;\n            b[emp] = old_b;\n        }\n        \n        temp *= cooling;\n    }\n    \n    // Output final solution\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    int cx, cy; // center coordinates\n};\n\nvector<City> cities;\nvector<vector<int>> groups;\nvector<vector<pair<int,int>>> group_edges;\n\n// Query function\nvector<pair<int,int>> query(const vector<int>& subset) {\n    cout << \"? \" << subset.size();\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    \n    vector<pair<int,int>> result;\n    for (int i = 0; i < (int)subset.size() - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        result.emplace_back(a, b);\n    }\n    return result;\n}\n\n// Output final answer\nvoid output_answer() {\n    cout << \"!\" << endl;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[i][j];\n        }\n        cout << endl;\n        \n        for (auto& e : group_edges[i]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cities.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].id = i;\n        cities[i].cx = (cities[i].lx + cities[i].rx) / 2;\n        cities[i].cy = (cities[i].ly + cities[i].ry) / 2;\n    }\n    \n    // Sort cities by center coordinates and assign to groups\n    vector<int> city_order(N);\n    iota(city_order.begin(), city_order.end(), 0);\n    sort(city_order.begin(), city_order.end(), [&](int a, int b) {\n        if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n        return cities[a].cy < cities[b].cy;\n    });\n    \n    groups.resize(M);\n    group_edges.resize(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; j++) {\n            groups[i][j] = city_order[idx++];\n        }\n    }\n    \n    // Query phase - process each group\n    int queries_used = 0;\n    for (int k = 0; k < M && queries_used < Q; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g == 1) continue;\n        if (g == 2) {\n            // Direct edge for 2-city group\n            group_edges[k].emplace_back(group[0], group[1]);\n            continue;\n        }\n        \n        // For larger groups, use queries efficiently\n        // Strategy: query overlapping sets of 3 cities\n        vector<bool> has_edge(N, false);\n        vector<int> last_connected(N, -1);\n        vector<pair<int,int>> edges_found;\n        \n        // Process cities in order within group\n        for (int i = 0; i + 2 < g && queries_used < Q; i++) {\n            vector<int> subset = {group[i], group[i+1], group[i+2]};\n            auto result = query(subset);\n            queries_used++;\n            \n            for (auto& e : result) {\n                // Check if we already have this edge (in reverse order)\n                bool already = false;\n                for (auto& existing : edges_found) {\n                    if ((existing.first == e.first && existing.second == e.second) ||\n                        (existing.first == e.second && existing.second == e.first)) {\n                        already = true;\n                        break;\n                    }\n                }\n                if (!already) {\n                    edges_found.push_back(e);\n                }\n            }\n        }\n        \n        // If we still have remaining queries, try to connect remaining parts\n        // Build MST from gathered edges for this group\n        vector<pair<int,int>> mst_edges;\n        \n        // If we got enough edges from queries, use them\n        // Otherwise, fill remaining connections with direct edges\n        vector<vector<int>> adj(N);\n        for (auto& e : edges_found) {\n            adj[e.first].push_back(e.second);\n            adj[e.second].push_back(e.first);\n        }\n        \n        // Check connectivity within group using BFS\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(group[0]);\n        visited[group[0]] = true;\n        int connected_count = 1;\n        \n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int u : adj[v]) {\n                if (!visited[u]) {\n                    visited[u] = true;\n                    connected_count++;\n                    q.push(u);\n                }\n            }\n        }\n        \n        // If not fully connected, add more edges to connect\n        if (connected_count < g) {\n            // Add edges from MST queries or direct connections\n            for (int i = 0; i < g && queries_used < Q; i++) {\n                if (!visited[group[i]]) {\n                    // Try to connect this disconnected city\n                    int best_j = -1;\n                    for (int j = 0; j < g; j++) {\n                        if (visited[group[j]]) {\n                            // Query this pair if possible\n                            if (queries_used < Q) {\n                                vector<int> subset = {group[i], group[j]};\n                                // Need at least 2 cities for query, but L >= 3\n                                // So we add a third city if possible\n                                for (int kk = 0; kk < g; kk++) {\n                                    if (kk != i && kk != j) {\n                                        subset.push_back(group[kk]);\n                                        break;\n                                    }\n                                }\n                                if (subset.size() >= 2) {\n                                    auto result = query(subset);\n                                    queries_used++;\n                                    for (auto& e : result) {\n                                        edges_found.push_back(e);\n                                    }\n                                    // Re-check connectivity\n                                    adj.clear();\n                                    adj.resize(N);\n                                    for (auto& e : edges_found) {\n                                        adj[e.first].push_back(e.second);\n                                        adj[e.second].push_back(e.first);\n                                    }\n                                    \n                                    fill(visited.begin(), visited.end(), false);\n                                    q.push(group[0]);\n                                    visited[group[0]] = true;\n                                    connected_count = 1;\n                                    while (!q.empty()) {\n                                        int v = q.front(); q.pop();\n                                        for (int u : adj[v]) {\n                                            if (!visited[u]) {\n                                                visited[u] = true;\n                                                connected_count++;\n                                                q.push(u);\n                                            }\n                                        }\n                                    }\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Now collect MST edges from the group\n        // Use edges found from queries to build a spanning tree\n        // For simplicity, if we have enough edges, just use them\n        // Otherwise, fill with direct connections\n        \n        // Use the edges from queries as much as possible\n        set<int> connected;\n        connected.insert(group[0]);\n        \n        for (auto& e : edges_found) {\n            int u = e.first, v = e.second;\n            // Check if both in group\n            bool in_u = false, in_v = false;\n            for (int c : group) {\n                if (c == u) in_u = true;\n                if (c == v) in_v = true;\n            }\n            if (!in_u || !in_v) continue;\n            \n            if ((connected.count(u) == 0 && connected.count(v) > 0) ||\n                (connected.count(v) == 0 && connected.count(u) > 0)) {\n                mst_edges.push_back(e);\n                connected.insert(u);\n                connected.insert(v);\n            }\n        }\n        \n        // Fill remaining connections\n        for (int c : group) {\n            if (connected.count(c) == 0) {\n                // Connect to first connected city\n                mst_edges.emplace_back(c, *connected.begin());\n                connected.insert(c);\n            }\n        }\n        \n        group_edges[k] = mst_edges;\n    }\n    \n    // Output final answer\n    output_answer();\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\nconst int INF = 1e9;\n\nstruct Cell {\n    int r, c;\n    Cell(int r = 0, int c = 0) : r(r), c(c) {}\n    bool operator==(const Cell& o) const { return r == o.r && c == o.c; }\n    bool operator!=(const Cell& o) const { return !(*this == o); }\n};\n\nstring dirs = \"UDLR\";\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nclass Solver {\npublic:\n    int N, M;\n    vector<Cell> targets;\n    vector<string> grid;\n    vector<string> actions;\n    Cell pos;\n    \n    Solver(int n, int m, vector<Cell> t) : N(n), M(m), targets(t) {\n        grid = vector<string>(N, string(N, '.'));\n        pos = targets[0];\n    }\n    \n    bool valid(int r, int c) {\n        return r >= 0 && r < N && c >= 0 && c < N;\n    }\n    \n    bool hasBlock(int r, int c) {\n        return grid[r][c] == '#';\n    }\n    \n    void addAction(char a, char d) {\n        actions.push_back(string(1, a) + \" \" + string(1, d));\n    }\n    \n    // Simulate slide and return final position\n    Cell slide(int r, int c, int dir) {\n        int nr = r + dr[dir], nc = c + dc[dir];\n        while (valid(nr, nc) && !hasBlock(nr, nc)) {\n            r = nr; c = nc;\n            nr += dr[dir]; nc += dc[dir];\n        }\n        return Cell(r, c);\n    }\n    \n    // Find direction to place block to make slide work\n    // Place blocks around current position to slide towards target\n    bool makeSlidePath(Cell target) {\n        // Try to find a direct slide path\n        for (int d = 0; d < 4; d++) {\n            Cell end = slide(pos.r, pos.c, d);\n            if (end == target) {\n                addAction('S', dirs[d]);\n                pos = target;\n                return true;\n            }\n        }\n        \n        // Place blocks strategically to create slide paths\n        // Greedy: try to place blocks that will help\n        int bestDist = INF;\n        int bestDir = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            Cell end = slide(pos.r, pos.c, d);\n            int dist = abs(end.r - target.r) + abs(end.c - target.c);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestDir = d;\n            }\n        }\n        \n        if (bestDir >= 0) {\n            // Try placing a block to redirect the slide\n            int nr = pos.r + dr[bestDir];\n            int nc = pos.c + dc[bestDir];\n            \n            if (valid(nr, nc) && !hasBlock(nr, nc)) {\n                // Place block adjacent to redirect\n                addAction('A', dirs[bestDir]);\n                grid[nr][nc] = '#';\n                \n                // Now try to slide again\n                Cell end = slide(pos.r, pos.c, bestDir);\n                if (end == target) {\n                    addAction('S', dirs[bestDir]);\n                    pos = target;\n                    return true;\n                }\n                // Remove block if didn't help\n                addAction('A', dirs[bestDir]);\n                grid[nr][nc] = '.';\n            }\n        }\n        return false;\n    }\n    \n    // BFS to find path, preferring slides over moves\n    vector<pair<char, char>> findPath(Cell start, Cell end) {\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int, int>>> prev(N, vector<pair<int, int>>(N));\n        vector<vector<char>> prevDir(N, vector<char>(N));\n        queue<pair<int,int>> q;\n        \n        dist[start.r][start.c] = 0;\n        q.push({start.r, start.c});\n        \n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            \n            if (r == end.r && c == end.c) break;\n            \n            // Try moves\n            for (int d = 0; d < 4; d++) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (valid(nr, nc) && !hasBlock(nr, nc) && dist[nr][nc] > dist[r][c] + 1) {\n                    dist[nr][nc] = dist[r][c] + 1;\n                    prev[nr][nc] = {r, c};\n                    prevDir[nr][nc] = dirs[d];\n                    q.push({nr, nc});\n                }\n            }\n            \n            // Try slides\n            for (int d = 0; d < 4; d++) {\n                Cell slideEnd = slide(r, c, d);\n                if (slideEnd.r != r || slideEnd.c != c) {\n                    if (dist[slideEnd.r][slideEnd.c] > dist[r][c] + 1) {\n                        dist[slideEnd.r][slideEnd.c] = dist[r][c] + 1;\n                        prev[slideEnd.r][slideEnd.c] = {r, c};\n                        prevDir[slideEnd.r][slideEnd.c] = dirs[d] + 4; // mark as slide\n                        q.push({slideEnd.r, slideEnd.c});\n                    }\n                }\n            }\n        }\n        \n        vector<pair<char, char>> path;\n        int r = end.r, c = end.c;\n        while (r != start.r || c != start.c) {\n            char d = prevDir[r][c];\n            if (d >= 4) {\n                path.push_back({'S', (char)(d - 4)});\n                // Need to find where slide started\n                int pd = d - 4;\n                int pr = r - dr[pd], pc = c - dc[pd];\n                while (valid(pr, pc) && !hasBlock(pr, pc)) {\n                    pr -= dr[pd];\n                    pc -= dc[pd];\n                }\n                pr += dr[pd];\n                pc += dc[pd];\n                tie(r, c) = prev[r][c];\n                // Actually prev[r][c] should be start of slide\n                tie(r, c) = pair<int,int>{prev[r][c].first, prev[r][c].second};\n            } else {\n                path.push_back({'M', d});\n                tie(r, c) = prev[r][c];\n            }\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    }\n    \n    long long solve() {\n        long long score = 0;\n        \n        for (int idx = 1; idx < M; idx++) {\n            Cell target = targets[idx];\n            \n            // Try to use slide with block placement\n            if (makeSlidePath(target)) {\n                continue;\n            }\n            \n            // Find optimal path using BFS\n            auto path = findPath(pos, target);\n            \n            for (auto [a, d] : path) {\n                if (a == 'M') {\n                    int nr = pos.r + dr[d];\n                    int nc = pos.c + dc[d];\n                    addAction('M', d);\n                    pos = Cell(nr, nc);\n                } else {\n                    // Slide\n                    Cell end = slide(pos.r, pos.c, d);\n                    if (end == target) {\n                        pos = target;\n                        addAction('S', d);\n                    } else if (dist(pos.r, pos.c, d, target)) {\n                        // Try to place blocks to redirect slide\n                        int nr = pos.r + dr[d];\n                        int nc = pos.c + dc[d];\n                        if (!hasBlock(nr, nc)) {\n                            addAction('A', d);\n                            grid[nr][nc] = '#';\n                            Cell newEnd = slide(pos.r, pos.c, d);\n                            if (newEnd == target) {\n                                addAction('S', d);\n                                pos = target;\n                            } else {\n                                // Remove block\n                                addAction('A', d);\n                                grid[nr][nc] = '.';\n                                addAction('M', d);\n                                pos = Cell(nr, nc);\n                            }\n                        } else {\n                            addAction('M', d);\n                            pos = Cell(nr, nc);\n                        }\n                    } else {\n                        addAction('S', d);\n                        pos = end;\n                    }\n                }\n            }\n        }\n        \n        // Output actions\n        for (const auto& a : actions) {\n            cout << a << endl;\n        }\n        \n        return actions.size();\n    }\n    \n    int dist(int r1, int c1, int d, Cell target) {\n        Cell end = slide(r1, c1, d);\n        return abs(end.r - target.r) + abs(end.c - target.c);\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<Cell> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].r >> targets[i].c;\n    }\n    \n    Solver solver(N, M, targets);\n    solver.solve();\n    \n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Xorshift random number generator\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    \n    using result_type = uint64_t;\n    \n    uint64_t operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    \n    static constexpr uint64_t min() { return 0; }\n    static constexpr uint64_t max() { return ULLONG_MAX; }\n    \n    int rand_int(int l, int r) {\n        return l + operator()() % (r - l + 1);\n    }\n    \n    double rand_double() {\n        return (double)operator()() / ULLONG_MAX;\n    }\n} rng;\n\nstruct Rect {\n    int a, b, c, d;  // (a,b) top-left, (c,d) bottom-right\n    int x, y, r;     // target point and desired area\n    long long s;     // current area\n    \n    Rect() : a(0), b(0), c(0), d(0), x(0), y(0), r(0), s(0) {}\n    Rect(int a_, int b_, int c_, int d_, int x_, int y_, int r_)\n        : a(a_), b(b_), c(c_), d(d_), x(x_), y(y_), r(r_) {\n        s = (long long)(c - a) * (d - b);\n    }\n    \n    bool contains(int px, int py) const {\n        return a <= px && px < c && b <= py && py < d;\n    }\n    \n    double score() const {\n        if (!contains(x, y)) return 0.0;\n        if (s == 0) return 0.0;\n        double ratio = (r < s) ? (double)r / s : (double)s / r;\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    double potential_score(int na, int nb, int nc, int nd) const {\n        if (!(na <= x && x < nc && nb <= y && y < nd)) return 0.0;\n        long long ns = (long long)(nc - na) * (nd - nb);\n        if (ns == 0) return 0.0;\n        double ratio = (r < ns) ? (double)r / ns : (double)ns / r;\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<int> x(n), y(n), r(n);\n    long long total_r = 0;\n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n        total_r += r[i];\n    }\n    \n    // Phase 1: Greedy construction using Voronoi-inspired partitioning\n    vector<Rect> rects(n);\n    \n    // Sort indices by desired area (descending) for priority\n    vector<int> idx(n);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        return r[i] > r[j];\n    });\n    \n    // For each point, grow a rectangle greedily\n    // We'll divide the space into initial regions using a grid\n    \n    // Initialize with minimal rectangles\n    for (int i = 0; i < n; i++) {\n        rects[i] = Rect(x[i], y[i], x[i] + 1, y[i] + 1, x[i], y[i], r[i]);\n    }\n    \n    // Phase 2: Simulated Annealing\n    const double start_temp = 1.0;\n    const double end_temp = 0.001;\n    const int iterations = 50000;\n    \n    auto get_total_score = [&]() {\n        double sum = 0;\n        for (const auto& rect : rects) sum += rect.score();\n        return sum;\n    };\n    \n    auto check_overlap = [&](int exclude_idx, int na, int nb, int nc, int nd) {\n        for (int j = 0; j < n; j++) {\n            if (j == exclude_idx) continue;\n            if (max(na, rects[j].a) < min(nc, rects[j].c) && \n                max(nb, rects[j].b) < min(nd, rects[j].d)) {\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    double current_score = get_total_score();\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        double temp = start_temp + (end_temp - start_temp) * iter / iterations;\n        \n        // Pick a random rectangle and try to modify it\n        int i = rng.rand_int(0, n - 1);\n        auto& rect = rects[i];\n        \n        // Generate neighbor: expand or shrink in one direction\n        int dir = rng.rand_int(0, 3);\n        int delta = rng.rand_int(1, min(100, max(1, (int)sqrt(rect.r))));\n        \n        int na = rect.a, nb = rect.b, nc = rect.c, nd = rect.d;\n        \n        if (dir == 0) { // expand left\n            na = max(0, rect.a - delta);\n        } else if (dir == 1) { // expand right\n            nc = min(10000, rect.c + delta);\n        } else if (dir == 2) { // expand up\n            nb = max(0, rect.b - delta);\n        } else { // expand down\n            nd = min(10000, rect.d + delta);\n        }\n        \n        // Must contain target point\n        if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n        \n        // Check overlap\n        if (check_overlap(i, na, nb, nc, nd)) continue;\n        \n        double new_score = rect.potential_score(na, nb, nc, nd);\n        double score_diff = new_score - rect.score();\n        \n        // Accept with probability based on temperature\n        if (score_diff > 0 || rng.rand_double() < exp(score_diff * 1000 / temp)) {\n            rect.a = na;\n            rect.b = nb;\n            rect.c = nc;\n            rect.d = nd;\n            rect.s = (long long)(nc - na) * (nd - nb);\n            current_score += score_diff;\n        }\n        \n        // Also try shrinking if we're too big\n        if (rect.s > rect.r * 1.5 && rng.rand_double() < 0.3) {\n            dir = rng.rand_int(0, 3);\n            delta = rng.rand_int(1, min(50, (int)(sqrt(rect.s) / 2)));\n            \n            na = rect.a; nb = rect.b; nc = rect.c; nd = rect.d;\n            \n            if (dir == 0) { // shrink from right\n                nc = max(na + 1, rect.c - delta);\n            } else if (dir == 1) { // shrink from left\n                na = min(nc - 1, rect.a + delta);\n            } else if (dir == 2) { // shrink from bottom\n                nd = max(nb + 1, rect.d - delta);\n            } else { // shrink from top\n                nb = min(nd - 1, rect.b + delta);\n            }\n            \n            if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n            if (check_overlap(i, na, nb, nc, nd)) continue;\n            \n            double shrink_score = rect.potential_score(na, nb, nc, nd);\n            double shrink_diff = shrink_score - rect.score();\n            \n            if (shrink_diff > 0 || rng.rand_double() < exp(shrink_diff * 500 / temp)) {\n                rect.a = na;\n                rect.b = nb;\n                rect.c = nc;\n                rect.d = nd;\n                rect.s = (long long)(nc - na) * (nd - nb);\n                current_score += shrink_diff;\n            }\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \"\n             << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> visited_tile;\n    long long score;\n    string path;\n};\n\nclass Solver {\nprivate:\n    static const int N = 50;\n    int si, sj;\n    vector<vector<int>> t, p;\n    vector<vector<pair<int,int>>> tile_cells;\n    int M;\n    \npublic:\n    Solver() {\n        cin >> si >> sj;\n        t.assign(N, vector<int>(N));\n        p.assign(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> p[i][j];\n        \n        // Find max tile ID\n        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        // Build tile_cells mapping\n        tile_cells.resize(M);\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                tile_cells[t[i][j]].push_back({i, j});\n    }\n    \n    string solve() {\n        string best_path;\n        long long best_score = -1;\n        \n        // Try multiple starting strategies\n        vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n        \n        // Strategy 1: Greedy DFS with look-ahead\n        for (int start_dir = 0; start_dir < 4; start_dir++) {\n            auto result = greedy_dfs(si, sj, start_dir);\n            if (result.second > best_score) {\n                best_score = result.second;\n                best_path = result.first;\n            }\n        }\n        \n        // Strategy 2: Try from all 4 directions with different ordering\n        for (int attempt = 0; attempt < 10; attempt++) {\n            vector<vector<bool>> visited(M, false);\n            visited[t[si][sj]] = true;\n            \n            string path;\n            long long score = p[si][sj];\n            int ci = si, cj = sj;\n            \n            while (true) {\n                // Get valid moves sorted by heuristic\n                vector<tuple<int,int,int,int>> moves; // heuristic, dir_idx, ni, nj\n                for (int d = 0; d < 4; d++) {\n                    int ni = ci + dirs[d].first;\n                    int nj = cj + dirs[d].second;\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    if (visited[t[ni][nj]]) continue;\n                    \n                    int h = p[ni][nj];\n                    // Bonus for tiles with more unvisited adjacent tiles\n                    int bonus = count_adjacent_tiles(ni, nj, visited);\n                    moves.push_back({-h - bonus * 2, d, ni, nj});\n                }\n                \n                if (moves.empty()) break;\n                \n                sort(moves.begin(), moves.end());\n                auto [h, d, ni, nj] = moves[0];\n                \n                visited[t[ni][nj]] = true;\n                score += p[ni][nj];\n                path += \"DURL\"[d];\n                ci = ni; cj = nj;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_path = path;\n            }\n        }\n        \n        return best_path;\n    }\n    \nprivate:\n    int count_adjacent_tiles(int i, int j, const vector<vector<bool>>& visited) {\n        vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n        int count = 0;\n        for (auto [di, dj] : dirs) {\n            int ni = i + di, nj = j + dj;\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (!visited[t[ni][nj]]) count++;\n        }\n        return count;\n    }\n    \n    pair<string, long long> greedy_dfs(int start_i, int start_j, int first_dir) {\n        vector<pair<int,int>> dirs = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n        vector<vector<bool>> visited(M, false);\n        visited[t[start_i][start_j]] = true;\n        \n        string path;\n        long long score = p[start_i][start_j];\n        int ci = start_i, cj = start_j;\n        \n        // First move in specified direction if valid\n        int ni = ci + dirs[first_dir].first;\n        int nj = cj + dirs[first_dir].second;\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[t[ni][nj]]) {\n            visited[t[ni][nj]] = true;\n            score += p[ni][nj];\n            path += \"DURL\"[first_dir];\n            ci = ni; cj = nj;\n        }\n        \n        // Continue greedy with look-ahead\n        while (true) {\n            // Evaluate all valid moves with look-ahead\n            vector<tuple<int,int,int,int>> moves;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = ci + dirs[d].first;\n                int nj = cj + dirs[d].second;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (visited[t[ni][nj]]) continue;\n                \n                // Heuristic: immediate value + future potential\n                int h = p[ni][nj];\n                \n                // Add bonus for moves that keep options open\n                for (int dd = 0; dd < 4; dd++) {\n                    int nni = ni + dirs[dd].first;\n                    int nnj = nj + dirs[dd].second;\n                    if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n                    if (!visited[t[nni][nnj]]) {\n                        h += p[nni][nnj] / 2; // potential future value\n                    }\n                }\n                \n                moves.push_back({-h, d, ni, nj});\n            }\n            \n            if (moves.empty()) break;\n            \n            sort(moves.begin(), moves.end());\n            auto [h, d, ni, nj] = moves[0];\n            \n            visited[t[ni][nj]] = true;\n            score += p[ni][nj];\n            path += \"DURL\"[d];\n            ci = ni; cj = nj;\n        }\n        \n        return {path, score};\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    string result = solver.solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nstruct Edge {\n    int from_row, from_col, to_row, to_col;\n    double mean;\n    int count;\n};\n\nstruct Graph {\n    vector<Edge> edges;\n    vector<vector<int>> adj;\n    \n    Graph() {\n        adj.resize(N * N);\n        \n        // Horizontal edges\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                Edge e = {i, j, i, j+1, 5000.0, 0};\n                edges.push_back(e);\n                adj[u].push_back((int)edges.size() - 1);\n                adj[v].push_back((int)edges.size() - 1);\n            }\n        }\n        \n        // Vertical edges\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                int u = i * N + j;\n                int v = (i+1) * N + j;\n                edges.push_back({i, j, i+1, j, 5000.0, 0});\n                adj[u].push_back((int)edges.size() - 1);\n                adj[v].push_back((int)edges.size() - 1);\n            }\n        }\n    }\n    \n    string get_path_str(int si, int sj, int ti, int tj, vector<int>& used_edges) {\n        // Dijkstra\n        vector<double> dist(N*N, 1e18);\n        vector<int> prev(N*N, -1);\n        vector<int> prev_edge(N*N, -1);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<>> pq;\n        \n        int s = si * N + sj;\n        int t = ti * N + tj;\n        dist[s] = 0;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == t) break;\n            \n            int ui = u / N, uj = u % N;\n            for (int eid : adj[u]) {\n                auto& e = edges[eid];\n                int v = (e.from_row == ui && e.from_col == uj) \n                       ? e.to_row * N + e.to_col \n                       : e.from_row * N + e.from_col;\n                double nd = d + e.mean;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_edge[v] = eid;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        // Reconstruct path\n        string path;\n        used_edges.clear();\n        \n        int cur = t;\n        while (cur != s) {\n            int eid = prev_edge[cur];\n            used_edges.push_back(eid);\n            cur = prev[cur];\n        }\n        reverse(used_edges.begin(), used_edges.end());\n        \n        // Convert to direction string\n        int ci = si, cj = sj;\n        for (int eid : used_edges) {\n            auto& e = edges[eid];\n            int ni, nj;\n            if (e.from_row == ci && e.from_col == cj) {\n                ni = e.to_row; nj = e.to_col;\n            } else {\n                ni = e.from_row; nj = e.from_col;\n            }\n            \n            if (ni < ci) path += 'U';\n            else if (ni > ci) path += 'D';\n            else if (nj < cj) path += 'L';\n            else path += 'R';\n            \n            ci = ni; cj = nj;\n        }\n        \n        return path;\n    }\n    \n    void update_edges(const vector<int>& used_edges, double observed_length) {\n        double predicted = 0;\n        for (int eid : used_edges) predicted += edges[eid].mean;\n        \n        double error = observed_length - predicted;\n        double per_edge = error / used_edges.size();\n        \n        for (int eid : used_edges) {\n            edges[eid].count++;\n            double alpha = 0.3 / (1 + edges[eid].count * 0.01);\n            edges[eid].mean += alpha * per_edge;\n            edges[eid].mean = max(100.0, min(20000.0, edges[eid].mean));\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Graph g;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        vector<int> used_edges;\n        string path = g.get_path_str(si, sj, ti, tj, used_edges);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        double observed;\n        cin >> observed;\n        \n        g.update_edges(used_edges, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast random number generation\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next() {\n        x ^= x << 7;\n        return x ^= x >> 9;\n    }\n    int rand_int(int l, int r) {\n        return l + (int)(next() % (r - l + 1));\n    }\n    double rand_double() {\n        return (double)next() / UINT64_MAX;\n    }\n};\n\nstruct Solver {\n    int N, M;\n    vector<string> strings;\n    vector<vector<int>> freq; // frequency of each character at each position\n    vector<string> ans;\n    XorShift rng;\n    \n    // For each string, store possible positions\n    vector<vector<tuple<int,int,int>>> possible_positions; // (row, col, dir)\n    \n    Solver(int n, int m, vector<string>& s) : N(n), M(m), strings(s) {\n        freq.assign(N, vector<int>(8, 0));\n        ans.assign(N, string(N, '.'));\n        \n        // Initialize frequency analysis\n        for (auto& str : strings) {\n            for (char c : str) {\n                freq[0][c - 'A']++;\n            }\n        }\n    }\n    \n    // Check if string can be placed at (r, c) going in direction dir\n    bool can_place(const string& str, int r, int c, int dir) {\n        int len = str.size();\n        if (dir == 0) { // horizontal\n            for (int p = 0; p < len; p++) {\n                int nc = (c + p) % N;\n                if (ans[r][nc] != '.' && ans[r][nc] != str[p]) return false;\n            }\n        } else { // vertical\n            for (int p = 0; p < len; p++) {\n                int nr = (r + p) % N;\n                if (ans[nr][c] != '.' && ans[nr][c] != str[p]) return false;\n            }\n        }\n        return true;\n    }\n    \n    // Place string at (r, c) going in direction dir\n    void place_string(const string& str, int r, int c, int dir) {\n        int len = str.size();\n        if (dir == 0) {\n            for (int p = 0; p < len; p++) {\n                int nc = (c + p) % N;\n                if (ans[r][nc] == '.') ans[r][nc] = str[p];\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                int nr = (r + p) % N;\n                if (ans[nr][c] == '.') ans[nr][c] = str[p];\n            }\n        }\n    }\n    \n    // Check if string is a subsequence of current answer\n    bool is_subsequence(const string& str) {\n        int len = str.size();\n        // Check horizontal\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.' || ans[r][c] != str[0]) continue;\n                bool ok = true;\n                for (int p = 1; p < len; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] == '.' || ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) return true;\n            }\n        }\n        // Check vertical\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.' || ans[r][c] != str[0]) continue;\n                bool ok = true;\n                for (int p = 1; p < len; p++) {\n                    int nr = (r + p) % N;\n                    if (ans[nr][c] == '.' || ans[nr][c] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) return true;\n            }\n        }\n        return false;\n    }\n    \n    // Find all possible positions for a string\n    void find_positions(const string& str) {\n        vector<tuple<int,int,int>> positions;\n        int len = str.size();\n        \n        // Horizontal\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] != '.' && ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) positions.push_back({r, c, 0});\n            }\n        }\n        \n        // Vertical\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                bool ok = true;\n                for (int p = 0; p < len; p++) {\n                    int nr = (r + p) % N;\n                    if (ans[nr][c] != '.' && ans[nr][c] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) positions.push_back({r, c, 1});\n            }\n        }\n        \n        possible_positions.push_back(positions);\n    }\n    \n    // Main solving function\n    void solve() {\n        // Phase 1: Build initial solution greedily\n        // Sort strings by length (longer first, as they're more constraining)\n        vector<pair<int,int>> order;\n        for (int i = 0; i < M; i++) {\n            order.push_back({-(int)strings[i].size(), i});\n        }\n        sort(order.begin(), order.end());\n        \n        // Place strings greedily\n        for (auto [len_neg, idx] : order) {\n            string& str = strings[idx];\n            if (is_subsequence(str)) continue;\n            \n            // Try to find a valid position\n            bool placed = false;\n            for (int r = 0; r < N && !placed; r++) {\n                for (int c = 0; c < N && !placed; c++) {\n                    // Try horizontal\n                    if (can_place(str, r, c, 0)) {\n                        place_string(str, r, c, 0);\n                        placed = true;\n                        break;\n                    }\n                    // Try vertical\n                    if (can_place(str, r, c, 1)) {\n                        place_string(str, r, c, 1);\n                        placed = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!placed) {\n                // Force placement by overriding conflicting cells\n                // Find position with minimal conflicts\n                int best_conflicts = 1000;\n                int best_r = -1, best_c = -1, best_dir = -1;\n                \n                for (int r = 0; r < N; r++) {\n                    for (int c = 0; c < N; c++) {\n                        // Horizontal\n                        int conflicts = 0;\n                        bool valid = true;\n                        for (int p = 0; p < (int)str.size(); p++) {\n                            int nc = (c + p) % N;\n                            if (ans[r][nc] != '.' && ans[r][nc] != str[p]) {\n                                conflicts++;\n                            }\n                        }\n                        if (conflicts < best_conflicts) {\n                            best_conflicts = conflicts;\n                            best_r = r;\n                            best_c = c;\n                            best_dir = 0;\n                        }\n                        \n                        // Vertical\n                        conflicts = 0;\n                        valid = true;\n                        for (int p = 0; p < (int)str.size(); p++) {\n                            int nr = (r + p) % N;\n                            if (ans[nr][c] != '.' && ans[nr][c] != str[p]) {\n                                conflicts++;\n                            }\n                        }\n                        if (conflicts < best_conflicts) {\n                            best_conflicts = conflicts;\n                            best_r = r;\n                            best_c = c;\n                            best_dir = 1;\n                        }\n                    }\n                }\n                \n                if (best_r != -1) {\n                    place_string(str, best_r, best_c, best_dir);\n                }\n            }\n        }\n        \n        // Phase 2: Local optimization\n        // Fill remaining empty cells with most common character in their row/column\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.') {\n                    // Choose character based on frequency in nearby strings\n                    vector<int> char_freq(8, 0);\n                    \n                    // Count characters in horizontal strings passing through this cell\n                    for (int i = 0; i < M; i++) {\n                        string& str = strings[i];\n                        int len = str.size();\n                        // Check horizontal\n                        for (int sr = 0; sr < N; sr++) {\n                            for (int sc = 0; sc < N; sc++) {\n                                bool passes = false;\n                                for (int p = 0; p < len; p++) {\n                                    int nr = sr;\n                                    int nc = (sc + p) % N;\n                                    if (nr == r && nc == c) {\n                                        passes = true;\n                                        break;\n                                    }\n                                }\n                                if (passes) {\n                                    for (int p = 0; p < len; p++) {\n                                        int nc = (sc + p) % N;\n                                        if (nr == r && nc == c) {\n                                            char_freq[str[p] - 'A']++;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Choose most frequent character\n                    int best_char = 0;\n                    int best_freq = -1;\n                    for (int k = 0; k < 8; k++) {\n                        if (char_freq[k] > best_freq) {\n                            best_freq = char_freq[k];\n                            best_char = k;\n                        }\n                    }\n                    \n                    if (best_freq > 0) {\n                        ans[r][c] = 'A' + best_char;\n                    } else {\n                        ans[r][c] = 'A' + (rng.rand_int(0, 7));\n                    }\n                }\n            }\n        }\n        \n        // Phase 3: Random local search to improve\n        int iterations = 10000;\n        int current_score = count_matches();\n        \n        while (iterations > 0) {\n            // Randomly pick a cell and try different character\n            int r = rng.rand_int(0, N-1);\n            int c = rng.rand_int(0, N-1);\n            char old_char = ans[r][c];\n            \n            // Try all 8 possibilities\n            for (char new_char = 'A'; new_char <= 'H'; new_char++) {\n                if (new_char == old_char) continue;\n                ans[r][c] = new_char;\n                int new_score = count_matches();\n                if (new_score > current_score) {\n                    current_score = new_score;\n                    iterations = 10000;\n                    break;\n                } else {\n                    // Revert with some probability\n                    if (rng.rand_double() < 0.1) {\n                        // Accept worse solution sometimes\n                        current_score = new_score;\n                        break;\n                    }\n                    ans[r][c] = old_char;\n                }\n            }\n            iterations--;\n        }\n    }\n    \n    int count_matches() {\n        int count = 0;\n        for (auto& str : strings) {\n            if (is_subsequence(str)) count++;\n        }\n        return count;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Solver solver(N, M, strings);\n    solver.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << solver.ans[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\n\nint N, si, sj;\nvector<string> c;\nvector<vector<int>> cost;\nvector<vector<int>> dist; // BFS distances from start\n\nint di[4] = {-1, 1, 0, 0};\nint dj[4] = {0, 0, -1, 1};\nchar dirChar[4] = {'U', 'D', 'L', 'R'};\n\n// BFS distances from (si,sj) to all cells\nvoid bfsDist() {\n    dist.assign(N, vector<int>(N, 1e9));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si,sj});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        for (int d=0; d<4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && dist[ni][nj] > dist[i][j]+1) {\n                dist[ni][nj] = dist[i][j]+1;\n                q.push({ni,nj});\n            }\n        }\n    }\n}\n\n// Precompute visibility sets: vis[i][j] = set of visible cells\nvector<vector<pair<int,int>>> visible;\n\nvoid precomputeVisible() {\n    visible.assign(N, vector<pair<int,int>>());\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        // left\n        for (int nj=j-1; nj>=0 && c[i][nj]!='#'; nj--) visible[i][j].push_back({i,nj});\n        // right\n        for (int nj=j+1; nj<N && c[i][nj]!='#'; nj++) visible[i][j].push_back({i,nj});\n        // up\n        for (int ni=i-1; ni>=0 && c[ni][j]!='#'; ni--) visible[i][j].push_back({ni,j});\n        // down\n        for (int ni=i+1; ni<N && c[ni][j]!='#'; ni++) visible[i][j].push_back({ni,j});\n    }\n}\n\n// BFS shortest path from (i1,j1) to (i2,j2)\nstring pathBetween(int i1, int j1, int i2, int j2) {\n    vector<vector<int>> d(N, vector<int>(N, 1e9));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    d[i1][j1] = 0;\n    q.push({i1,j1});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i==i2 && j==j2) break;\n        for (int dir=0; dir<4; dir++) {\n            int ni = i+di[dir], nj = j+dj[dir];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && d[ni][nj] > d[i][j]+1) {\n                d[ni][nj] = d[i][j]+1;\n                prev[ni][nj] = {i,j};\n                q.push({ni,nj});\n            }\n        }\n    }\n    string path;\n    int ci = i2, cj = j2;\n    while (!(ci==i1 && cj==j1)) {\n        auto [pi,pj] = prev[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 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 >> N >> si >> sj;\n    c.resize(N);\n    for (int i=0; i<N; i++) cin >> c[i];\n    \n    precomputeVisible();\n    \n    // total road cells\n    vector<pair<int,int>> roads;\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') roads.push_back({i,j});\n    int r = roads.size();\n    \n    // Mark visible from start\n    vector<vector<bool>> seen(N, vector<bool>(N, false));\n    seen[si][sj] = true;\n    for (auto [vi,vj] : visible[si][sj]) seen[vi][vj] = true;\n    \n    int cur_i = si, cur_j = sj;\n    string ans;\n    int uncovered = 0;\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) uncovered++;\n    \n    while (uncovered > 0) {\n        // find nearest uncovered cell\n        bfsDist();\n        int bestDist = 1e9, bestI = -1, bestJ = -1;\n        for (auto [i,j] : roads) {\n            if (!seen[i][j] && dist[i][j] < bestDist) {\n                bestDist = dist[i][j];\n                bestI = i; bestJ = j;\n            }\n        }\n        // move to that cell\n        string subPath = pathBetween(cur_i, cur_j, bestI, bestJ);\n        ans += subPath;\n        \n        // update current position and seen\n        cur_i = bestI; cur_j = bestJ;\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) {\n            if (!seen[vi][vj]) {\n                seen[vi][vj] = true;\n                uncovered--;\n            }\n        }\n    }\n    \n    // return to start\n    string back = pathBetween(cur_i, cur_j, si, sj);\n    ans += back;\n    \n    cout << ans << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast I/O\nstruct FastIO {\n    FastIO() {\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cout.tie(nullptr);\n    }\n} fastio;\n\n// Utility for random\nstruct XorShift {\n    uint64_t x;\n    XorShift() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t rand() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint32_t rand(uint32_t range) {\n        return rand() % range;\n    }\n    double uniform() {\n        return (double)rand() / UINT32_MAX;\n    }\n    double normal() {\n        double u1 = uniform(), u2 = uniform();\n        return sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);\n    }\n} rng;\n\n// 2D vector type\nusing Vec = vector<int>;\n\n// Main solver\nstruct Solver {\n    int N, M, K, R;\n    vector<Vec> task_diff; // task difficulties\n    vector<vector<int>> deps; // dependencies\n    vector<Vec> workers_skills_est; // estimated worker skills\n    vector<vector<double>> skill_mean; // mean of skill estimates\n    vector<vector<double>> skill_var; // variance of skill estimates\n    \n    // State\n    vector<int> task_status; // 0=not started, 1=running, 2=done\n    vector<int> worker_busy_until; // day when worker becomes free\n    vector<int> worker_task; // task assigned to worker (-1 if none)\n    int current_day;\n    \n    // History for learning\n    struct Observation {\n        int worker;\n        int task;\n        int duration;\n        Vec task_diff;\n    };\n    vector<Observation> history;\n    \n    Solver() {\n        read_input();\n        init();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> K >> R;\n        task_diff.resize(N, Vec(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                cin >> task_diff[i][j];\n            }\n        }\n        deps.resize(N);\n        for (int i = 0; i < R; i++) {\n            int u, v;\n            cin >> u >> v;\n            u--; v--;\n            deps[v].push_back(u);\n        }\n    }\n    \n    void init() {\n        // Initialize skill estimates with reasonable values\n        workers_skills_est.assign(M, Vec(K, 0));\n        skill_mean.assign(M, vector<double>(K, 30.0));\n        skill_var.assign(M, vector<double>(K, 100.0));\n        \n        task_status.assign(N, 0);\n        worker_busy_until.assign(M, 0);\n        worker_task.assign(M, -1);\n        current_day = 1;\n    }\n    \n    bool can_start(int task) {\n        if (task_status[task] != 0) return false;\n        for (int dep : deps[task]) {\n            if (task_status[dep] != 2) return false;\n        }\n        return true;\n    }\n    \n    double expected_duration(int worker, int task) {\n        double w = 0;\n        for (int k = 0; k < K; k++) {\n            w += max(0, task_diff[task][k] - (int)round(workers_skills_est[worker][k]));\n        }\n        return max(1.0, w + 1); // conservative estimate\n    }\n    \n    int find_best_worker(int task) {\n        int best_worker = -1;\n        double best_time = 1e9;\n        vector<int> available;\n        for (int w = 0; w < M; w++) {\n            if (worker_busy_until[w] <= current_day) {\n                available.push_back(w);\n            }\n        }\n        if (available.empty()) return -1;\n        \n        for (int w : available) {\n            double dur = expected_duration(w, task);\n            // Add explore bonus for uncertain skills\n            double uncertainty = 0;\n            for (int k = 0; k < K; k++) {\n                uncertainty += skill_var[w][k];\n            }\n            uncertainty = sqrt(uncertainty / K);\n            dur -= 0.5 * uncertainty; // prefer exploring uncertain workers\n            \n            if (dur < best_time) {\n                best_time = dur;\n                best_worker = w;\n            }\n        }\n        return best_worker;\n    }\n    \n    void update_skills(Observation& obs) {\n        // Simple gradient descent to update skill estimates\n        double learning_rate = 0.1;\n        int actual_dur = obs.duration;\n        Vec& d = obs.task_diff;\n        int w = obs.worker;\n        \n        // Compute predicted w\n        double pred_w = 0;\n        for (int k = 0; k < K; k++) {\n            pred_w += max(0, d[k] - workers_skills_est[w][k]);\n        }\n        \n        // Update if actual duration gives information\n        if (actual_dur > 1) {\n            // The actual w (without noise) is around actual_dur - random(-3 to 3)\n            // We'll use a simple update rule\n            for (int k = 0; k < K; k++) {\n                if (d[k] > workers_skills_est[w][k]) {\n                    // This skill might be lower than estimated\n                    workers_skills_est[w][k] = max(0, workers_skills_est[w][k] + \n                        (int)(learning_rate * (d[k] - workers_skills_est[w][k]) * (actual_dur - 1) / (pred_w + 1)));\n                }\n            }\n        } else {\n            // Task was easy, worker likely has sufficient skills\n            for (int k = 0; k < K; k++) {\n                workers_skills_est[w][k] = max(workers_skills_est[w][k], d[k]);\n            }\n        }\n    }\n    \n    void solve() {\n        while (true) {\n            // Update worker states from previous day's completions\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            stringstream ss(line);\n            int first;\n            ss >> first;\n            \n            if (first == -1) {\n                // End of simulation\n                return;\n            }\n            \n            // Process completed tasks\n            int n_completed = first;\n            for (int i = 0; i < n_completed; i++) {\n                int worker;\n                ss >> worker;\n                worker--;\n                int task = worker_task[worker];\n                if (task >= 0) {\n                    task_status[task] = 2; // completed\n                    int duration = current_day - (worker_busy_until[worker] - 1);\n                    \n                    Observation obs;\n                    obs.worker = worker;\n                    obs.task = task;\n                    obs.duration = duration;\n                    obs.task_diff = task_diff[task];\n                    history.push_back(obs);\n                    \n                    // Update skill estimates\n                    update_skills(obs);\n                    \n                    worker_task[worker] = -1;\n                    worker_busy_until[worker] = current_day; // free now\n                }\n            }\n            \n            // Find tasks that can be started\n            vector<int> available_tasks;\n            for (int t = 0; t < N; t++) {\n                if (can_start(t)) {\n                    available_tasks.push_back(t);\n                }\n            }\n            \n            // Assign workers to tasks\n            vector<pair<int, int>> assignments;\n            \n            // Sort tasks by priority (e.g., by number of descendants)\n            sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n                return deps[a].size() > deps[b].size();\n            });\n            \n            for (int task : available_tasks) {\n                if (assignments.size() >= M) break;\n                \n                int worker = find_best_worker(task);\n                if (worker >= 0) {\n                    assignments.push_back({worker, task});\n                    worker_task[worker] = task;\n                    task_status[task] = 1; // started\n                    \n                    // Estimate completion time for next day update\n                    double est_dur = expected_duration(worker, task);\n                    worker_busy_until[worker] = current_day + (int)ceil(est_dur);\n                }\n            }\n            \n            // Output assignments\n            cout << assignments.size();\n            for (auto& p : assignments) {\n                cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n            }\n            cout << endl;\n            cout.flush();\n            \n            current_day++;\n            \n            if (current_day > 2000) {\n                // Read remaining input and exit\n                while (true) {\n                    getline(cin, line);\n                    if (line == \"-1\") break;\n                }\n                return;\n            }\n        }\n    }\n};\n\nint main() {\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nconst int DEPOT_X = 400, DEPOT_Y = 400;\nconst int N_ORDERS = 1000;\nconst int PICK = 50;\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nstruct Order {\n    int a, b, c, d;\n    int len; // distance from restaurant to destination\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> orders(N_ORDERS);\n    for (int i = 0; i < N_ORDERS; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].len = manhattan(orders[i].a, orders[i].b, orders[i].c, orders[i].d);\n    }\n\n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // --- Selection: pick 50 with small roundtrip cost (depot->rest->dest->depot)\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < N_ORDERS; ++i) {\n        int rt = manhattan(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b)\n               + orders[i].len\n               + manhattan(orders[i].c, orders[i].d, DEPOT_X, DEPOT_Y);\n        candidates.emplace_back(rt, i);\n    }\n    sort(candidates.begin(), candidates.end());\n\n    // Take top 100 best (ensure diversity)\n    vector<int> selectedIdx;\n    for (int i = 0; i < 100; ++i) selectedIdx.push_back(candidates[i].second);\n    shuffle(selectedIdx.begin(), selectedIdx.end(), rng);\n    selectedIdx.resize(PICK);\n\n    // Build route as sequence of point IDs:\n    // For each order i, we insert two nodes: restaurant (2*i), destination (2*i+1)\n    // Depot at start/end: represented as -1 separately.\n    struct Node {\n        int x, y;\n        int orderId;   // for precedence check\n        bool isRestaurant;\n    };\n    vector<Node> nodes; // for the chosen orders\n    for (int idx : selectedIdx) {\n        nodes.push_back({orders[idx].a, orders[idx].b, idx, true});\n        nodes.push_back({orders[idx].c, orders[idx].d, idx, false});\n    }\n\n    // Initial naive tour: depot -> all nodes in order -> depot\n    vector<int> route; // indices into nodes, 0..(2*PICK-1)\n    route.reserve(2*PICK);\n    for (int i = 0; i < (int)nodes.size(); ++i) route.push_back(i);\n\n    // Heuristic: nearest neighbor starting from depot\n    {\n        vector<bool> used(2*PICK, false);\n        vector<int> newRoute;\n        int cx = DEPOT_X, cy = DEPOT_Y;\n        for (int step = 0; step < 2*PICK; ++step) {\n            int best = -1;\n            int bestDist = 1e9;\n            for (int j = 0; j < 2*PICK; ++j) {\n                if (used[j]) continue;\n                int d = manhattan(cx, cy, nodes[j].x, nodes[j].y);\n                if (d < bestDist) {\n                    bestDist = d;\n                    best = j;\n                }\n            }\n            newRoute.push_back(best);\n            used[best] = true;\n            cx = nodes[best].x;\n            cy = nodes[best].y;\n        }\n        route = move(newRoute);\n    }\n\n    // 2-opt local search with precedence constraints\n    auto routeDist = [&](const vector<int>& r) -> int {\n        int total = manhattan(DEPOT_X, DEPOT_Y, nodes[r[0]].x, nodes[r[0]].y);\n        for (int i = 0; i+1 < (int)r.size(); ++i) {\n            total += manhattan(nodes[r[i]].x, nodes[r[i]].y, nodes[r[i+1]].x, nodes[r[i+1]].y);\n        }\n        total += manhattan(nodes[r.back()].x, nodes[r.back()].y, DEPOT_X, DEPOT_Y);\n        return total;\n    };\n\n    auto validPrecedence = [&](const vector<int>& r) -> bool {\n        // For each order: restaurant pos must be before destination pos\n        array<int, 2*N_ORDERS> posRest, posDest;\n        fill(posRest.begin(), posRest.end(), -1);\n        fill(posDest.begin(), posDest.end(), -1);\n        for (int i = 0; i < (int)r.size(); ++i) {\n            int ni = r[i];\n            int oid = nodes[ni].orderId;\n            if (nodes[ni].isRestaurant) posRest[oid] = i;\n            else posDest[oid] = i;\n        }\n        for (int idx : selectedIdx) {\n            if (posRest[idx] == -1 || posDest[idx] == -1) return false;\n            if (posRest[idx] >= posDest[idx]) return false;\n        }\n        return true;\n    };\n\n    // Random restart loop + 2-opt\n    int bestT = 1e9;\n    vector<int> bestRoute;\n\n    for (int restart = 0; restart < 5; ++restart) {\n        // shuffle starting route\n        shuffle(route.begin(), route.end(), rng);\n        // Ensure precedence constraint initially (restaurant before destination)\n        // by brute force: for each order, ensure restaurant first\n        {\n            vector<int> tmp;\n            vector<bool> restPlaced(N_ORDERS, false);\n            for (int idx : route) {\n                int oid = nodes[idx].orderId;\n                if (nodes[idx].isRestaurant) {\n                    tmp.push_back(idx);\n                    restPlaced[oid] = true;\n                } else {\n                    // try to find restaurant before\n                    if (!restPlaced[oid]) {\n                        // need to find corresponding restaurant earlier; insert both\n                        // simple: put restaurant earlier\n                        for (int j = 0; j < (int)tmp.size(); ++j) {\n                            if (nodes[tmp[j]].orderId == oid && nodes[tmp[j]].isRestaurant) {\n                                // already placed\n                                break;\n                            }\n                        }\n                        // if not placed, add restaurant (should not happen if set is intact)\n                    }\n                    tmp.push_back(idx);\n                }\n            }\n            route = tmp;\n        }\n\n        int curT = routeDist(route);\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < (int)route.size(); ++i) {\n                for (int j = i+1; j < (int)route.size(); ++j) {\n                    // reverse segment i..j\n                    vector<int> newRoute = route;\n                    reverse(newRoute.begin()+i, newRoute.begin()+j+1);\n                    if (!validPrecedence(newRoute)) continue;\n                    int newT = routeDist(newRoute);\n                    if (newT < curT) {\n                        route = newRoute;\n                        curT = newT;\n                        improved = true;\n                        goto next2opt;\n                    }\n                }\n            }\n            next2opt:;\n        }\n\n        if (curT < bestT) {\n            bestT = curT;\n            bestRoute = route;\n        }\n    }\n\n    // Output format\n    cout << PICK;\n    for (int idx : selectedIdx) cout << \" \" << idx+1;\n    cout << \"\\n\";\n\n    int n = bestRoute.size() + 2; // +2 for start and end depot\n    cout << n << \" \" << DEPOT_X << \" \" << DEPOT_Y;\n    for (int idx : bestRoute) cout << \" \" << nodes[idx].x << \" \" << nodes[idx].y;\n    cout << \" \" << DEPOT_X << \" \" << DEPOT_Y << \"\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Edge {\n    int u, v;\n    double expected_cost;  // Using d_i as expected (middle of range)\n    double d;             // exact Euclidean distance (rounded)\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    int N = 400;\n    int M = 1995;\n    \n    vector<pair<int,int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    vector<tuple<int,int,int>> edges; // u, v, idx\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v, i});\n    }\n    \n    // Precompute Euclidean distances\n    vector<double> dist(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    // Initialize DSU and track adopted edges\n    dsu dsu(N);\n    vector<bool> adopted(M, false);\n    \n    // Process edges one by one\n    for (int i = 0; i < M; i++) {\n        int u, v, idx;\n        tie(u, v, idx) = edges[i];\n        \n        // Read actual cost\n        long long actual_cost;\n        cin >> actual_cost;\n        \n        // Check if already connected (skip if so)\n        if (dsu.same(u, v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Decision logic:\n        // If actual cost is close to minimum (<= 1.5 * d_i), take it\n        // Otherwise, check if we can get cheaper option later\n        double d = dist[i];\n        double ratio = actual_cost / d;\n        \n        // Use expected minimum cost for future edges\n        // Edges from MST construction tend to have lower costs\n        if (ratio <= 1.5) {\n            // Good deal, take it\n            adopted[i] = true;\n            dsu.merge(u, v);\n            cout << 1 << endl;\n        } else {\n            // Check if there are still many cheap edges available\n            // For edges later in sequence, be more aggressive\n            // For edges early on, be more conservative\n            double threshold = 1.5 + 0.3 * (i / (double)M);\n            \n            // Also consider: if we haven't added many edges, be more conservative\n            int adopted_count = 0;\n            for (int j = 0; j < i; j++) {\n                if (adopted[j]) adopted_count++;\n            }\n            threshold -= 0.1 * (adopted_count / (double)(N/2));\n            \n            if (ratio <= threshold) {\n                adopted[i] = true;\n                dsu.merge(u, v);\n                cout << 1 << endl;\n            } else {\n                cout << 0 << endl;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int SIZE = 30;\nconst int TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Position& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Position pos;\n    int type;\n    string movement;\n};\n\nstruct Human {\n    Position pos;\n    int id;\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Pet> pets;\n    vector<Human> humans;\n    vector<vector<bool>> wall;  // true if impassable\n    vector<vector<bool>> isPet;\n    vector<string> actions;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dir[4] = {'U', 'D', 'L', 'R'};\n    const char wallDir[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool canPlaceWall(int x, int y) {\n        if (!isValid(x, y) || wall[x][y]) return false;\n        // Can't place wall on pet or human positions\n        if (isPet[x][y]) return false;\n        for (auto& h : humans) {\n            if (h.pos.x == x && h.pos.y == y) return false;\n        }\n        // Can't place wall adjacent to pet\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && isPet[nx][ny]) {\n                return false;\n            }\n        }\n        return true;\n    }\n    \n    int manhattan(Position a, Position b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Find a good enclosure area\n    void planEnclosure(vector<Position>& targetWalls) {\n        // Calculate center of human positions\n        int centerX = 0, centerY = 0;\n        for (auto& h : humans) {\n            centerX += h.pos.x;\n            centerY += h.pos.y;\n        }\n        centerX /= M;\n        centerY /= M;\n        \n        // Build rectangle around center\n        int radius = 8;  // Start with reasonable size\n        int x1 = max(1, centerX - radius);\n        int y1 = max(1, centerY - radius);\n        int x2 = min(SIZE-2, centerX + radius);\n        int y2 = min(SIZE-2, centerY + radius);\n        \n        // Add walls around the perimeter\n        for (int x = x1; x <= x2; x++) {\n            targetWalls.push_back({x, y1});\n            targetWalls.push_back({x, y2});\n        }\n        for (int y = y1+1; y < y2; y++) {\n            targetWalls.push_back({x1, y});\n            targetWalls.push_back({x2, y});\n        }\n    }\n    \n    Position getNextWallPosition(int humanIdx) {\n        // Strategy: Build walls around humans\n        auto& human = humans[humanIdx];\n        Position best = {-1, -1};\n        int minDist = 1e9;\n        \n        // Try to build walls in a circle around humans\n        for (int dist = 1; dist <= 10; dist++) {\n            for (int dx = -dist; dx <= dist; dx++) {\n                for (int dy = -dist; dy <= dist; dy++) {\n                    if (abs(dx) != dist && abs(dy) != dist) continue;\n                    int nx = human.pos.x + dx;\n                    int ny = human.pos.y + dy;\n                    if (canPlaceWall(nx, ny)) {\n                        int d = abs(dx) + abs(dy);\n                        if (d < minDist) {\n                            minDist = d;\n                            best = {nx, ny};\n                        }\n                    }\n                }\n            }\n            if (best.x != -1) break;\n        }\n        \n        return best;\n    }\n    \npublic:\n    Solver() {\n        wall = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n        isPet = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n    }\n    \n    void readInput() {\n        cin >> N;\n        pets.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> pets[i].pos.x >> pets[i].pos.y >> pets[i].type;\n            pets[i].pos.x--;\n            pets[i].pos.y--;\n            isPet[pets[i].pos.x][pets[i].pos.y] = true;\n        }\n        \n        cin >> M;\n        humans.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humans[i].pos.x >> humans[i].pos.y;\n            humans[i].pos.x--;\n            humans[i].pos.y--;\n            humans[i].id = i;\n        }\n    }\n    \n    void solve() {\n        // Phase 1 (turn 0-100): Build enclosure\n        // Phase 2 (turn 101-200): Expand/enhance enclosure\n        // Phase 3 (turn 201-300): Maintain walls\n        \n        vector<Position> wallTargets;\n        planEnclosure(wallTargets);\n        \n        for (int turn = 0; turn < TURNS; turn++) {\n            string output;\n            bool allDone = true;\n            \n            for (int i = 0; i < M; i++) {\n                auto& human = humans[i];\n                char action = '.';\n                \n                if (turn < 200) {\n                    // Building phase\n                    if (i == 0 && turn < (int)wallTargets.size() && turn % 3 == 0) {\n                        // Special human moves to strategic position\n                        auto target = wallTargets[turn];\n                        // Move towards target\n                        if (human.pos != target) {\n                            if (human.pos.x > target.x && canPlaceWall(human.pos.x-1, human.pos.y) == false) {\n                                // Check if we can move up\n                                int nx = human.pos.x - 1;\n                                int ny = human.pos.y;\n                                if (!wall[nx][ny]) {\n                                    action = 'U';\n                                    human.pos.x--;\n                                }\n                            } else if (human.pos.x < target.x) {\n                                action = 'D';\n                                human.pos.x++;\n                            } else if (human.pos.y > target.y) {\n                                action = 'L';\n                                human.pos.y--;\n                            } else if (human.pos.y < target.y) {\n                                action = 'R';\n                                human.pos.y++;\n                            }\n                        } else {\n                            // Build wall here\n                            action = 'd';  // Build wall downward\n                            wall[human.pos.x+1][human.pos.y] = true;\n                        }\n                    } else {\n                        // Other humans build nearby walls\n                        Position wallPos = getNextWallPosition(i);\n                        if (wallPos.x != -1) {\n                            // Move towards wall position first\n                            if (manhattan(human.pos, wallPos) > 1) {\n                                // Move closer\n                                if (abs(human.pos.x - wallPos.x) > abs(human.pos.y - wallPos.y)) {\n                                    if (human.pos.x > wallPos.x && !wall[human.pos.x-1][human.pos.y]) {\n                                        action = 'U';\n                                        human.pos.x--;\n                                    } else if (human.pos.x < wallPos.x && !wall[human.pos.x+1][human.pos.y]) {\n                                        action = 'D';\n                                        human.pos.x++;\n                                    }\n                                } else {\n                                    if (human.pos.y > wallPos.y && !wall[human.pos.x][human.pos.y-1]) {\n                                        action = 'L';\n                                        human.pos.y--;\n                                    } else if (human.pos.y < wallPos.y && !wall[human.pos.x][human.pos.y+1]) {\n                                        action = 'R';\n                                        human.pos.y++;\n                                    }\n                                }\n                            } else {\n                                // Build wall\n                                int dx = wallPos.x - human.pos.x;\n                                int dy = wallPos.y - human.pos.y;\n                                if (dx == -1) action = 'u';\n                                else if (dx == 1) action = 'd';\n                                else if (dy == -1) action = 'l';\n                                else if (dy == 1) action = 'r';\n                                wall[wallPos.x][wallPos.y] = true;\n                            }\n                        }\n                    }\n                } else {\n                    // Maintenance phase - try to complete the enclosure\n                    Position wallPos = getNextWallPosition(i);\n                    if (wallPos.x != -1) {\n                        // Similar movement logic\n                        if (manhattan(human.pos, wallPos) > 1) {\n                            if (human.pos.x > wallPos.x && !wall[human.pos.x-1][human.pos.y]) {\n                                action = 'U';\n                                human.pos.x--;\n                            } else if (human.pos.x < wallPos.x && !wall[human.pos.x+1][human.pos.y]) {\n                                action = 'D';\n                                human.pos.x++;\n                            } else if (human.pos.y > wallPos.y && !wall[human.pos.x][human.pos.y-1]) {\n                                action = 'L';\n                                human.pos.y--;\n                            } else if (human.pos.y < wallPos.y && !wall[human.pos.x][human.pos.y+1]) {\n                                action = 'R';\n                                human.pos.y++;\n                            }\n                        } else {\n                            int dx = wallPos.x - human.pos.x;\n                            int dy = wallPos.y - human.pos.y;\n                            if (dx == -1) action = 'u';\n                            else if (dx == 1) action = 'd';\n                            else if (dy == -1) action = 'l';\n                            else if (dy == 1) action = 'r';\n                            wall[wallPos.x][wallPos.y] = true;\n                        }\n                    }\n                }\n                \n                if (action == '.') allDone = false;\n                output += action;\n            }\n            \n            cout << output << endl;\n            cout.flush();\n            \n            // Read pet movements\n            string petMovement;\n            for (int i = 0; i < N; i++) {\n                cin >> petMovement;\n                if (i > 0) cin.ignore();\n                if (i < N-1) cin >> petMovement;\n                \n                // Update pet positions\n                isPet[pets[i].pos.x][pets[i].pos.y] = false;\n                for (char c : petMovement) {\n                    if (c == 'U') pets[i].pos.x--;\n                    else if (c == 'D') pets[i].pos.x++;\n                    else if (c == 'L') pets[i].pos.y--;\n                    else if (c == 'R') pets[i].pos.y++;\n                }\n                isPet[pets[i].pos.x][pets[i].pos.y] = true;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.readInput();\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> h, v;\n    \n    bool canMove(int i, int j, int d) const {\n        // d: 0=up, 1=down, 2=left, 3=right\n        if (d == 0 && i > 0 && !v[i-1][j]) return true;\n        if (d == 1 && i < 19 && !v[i][j]) return true;\n        if (d == 2 && j > 0 && !h[i][j-1]) return true;\n        if (d == 3 && j < 19 && !h[i][j]) return true;\n        return false;\n    }\n};\n\n// Compute reachable probability from a state with remaining string\ndouble computeExpectedScore(const string& s, int si, int sj, int ti, int tj, \n                           const Grid& grid, double p) {\n    // DP[i][j][k] = probability of being at (i,j) after k moves\n    // We'll use iterative DP\n    int L = s.size();\n    vector<vector<double>> dp(20, vector<double>(20, 0.0));\n    dp[si][sj] = 1.0;\n    \n    double expected = 0.0;\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n    \n    for (int step = 0; step < L && step < 400; ++step) {\n        vector<vector<double>> ndp(20, vector<double>(20, 0.0));\n        double goalProb = 0.0;\n        \n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (dp[i][j] < 1e-12) continue;\n                if (i == ti && j == tj) {\n                    goalProb += dp[i][j];\n                    continue;\n                }\n                \n                // Forget character with probability p\n                ndp[i][j] += dp[i][j] * p;\n                \n                // Try to move with probability (1-p)\n                int d = 0;\n                for (; d < 4; ++d) if (s[step] == dirs[d]) break;\n                if (grid.canMove(i, j, d)) {\n                    ndp[i+di[d]][j+dj[d]] += dp[i][j] * (1.0 - p);\n                } else {\n                    ndp[i][j] += dp[i][j] * (1.0 - p);\n                }\n            }\n        }\n        \n        // Expected score contribution\n        if (step < L) {\n            expected += goalProb * (401.0 - (step + 1));\n        }\n        \n        dp = ndp;\n    }\n    \n    return expected;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    Grid grid;\n    grid.h.resize(20, vector<int>(19));\n    grid.v.resize(19, vector<int>(20));\n    \n    for (int i = 0; i < 20; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 19; ++j) grid.h[i][j] = s[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 20; ++j) grid.v[i][j] = s[j] - '0';\n    }\n    \n    // BFS for shortest path\n    const int INF = 1e9;\n    vector<vector<int>> dist(20, vector<int>(20, INF));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dir_char[] = {'U', 'D', 'L', 'R'};\n    \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            if (!grid.canMove(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<char> path;\n    int ci = ti, cj = tj;\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        if (pi == ci - 1) path.push_back('D');\n        else if (pi == ci + 1) path.push_back('U');\n        else if (pj == cj - 1) path.push_back('R');\n        else path.push_back('L');\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Adaptive repetition based on position criticality\n    int baseLen = path.size();\n    int maxLen = 200;\n    int remaining = maxLen - baseLen;\n    \n    // Compute criticality for each position\n    // A position is critical if forgetting it could cause losing the path\n    vector<double> criticality(baseLen, 1.0);\n    \n    // Simulate forgetting each position and see if we can still reach goal\n    for (int skip = 0; skip < baseLen; ++skip) {\n        string testPath;\n        for (int i = 0; i < baseLen; ++i) {\n            if (i == skip) continue;\n            testPath.push_back(path[i]);\n        }\n        \n        // Check if we can still reach goal with this path\n        int ci = si, cj = sj;\n        bool reached = false;\n        for (char c : testPath) {\n            int d = 0;\n            if (c == 'U') d = 0;\n            else if (c == 'D') d = 1;\n            else if (c == 'L') d = 2;\n            else d = 3;\n            \n            if (grid.canMove(ci, cj, d)) {\n                ci += di[d]; cj += dj[d];\n            }\n            if (ci == ti && cj == tj) {\n                reached = true;\n                break;\n            }\n        }\n        \n        if (!reached) {\n            criticality[skip] = 2.0; // More critical\n        } else {\n            criticality[skip] = 0.5; // Less critical\n        }\n    }\n    \n    // Build optimized string\n    string ans;\n    double totalCritical = accumulate(criticality.begin(), criticality.end(), 0.0);\n    \n    for (int i = 0; i < baseLen && ans.size() < maxLen; ++i) {\n        ans.push_back(path[i]);\n        \n        // Add extra repetitions based on criticality and remaining budget\n        if (remaining > 0) {\n            int extra = max(0, min(remaining, \n                (int)(criticality[i] * remaining / totalCritical + 0.5)));\n            \n            // Bound extra by reasonable amount\n            extra = min(extra, (int)(1.0 / (1.0 - p) + 0.5));\n            \n            for (int r = 0; r < extra && ans.size() < maxLen; ++r) {\n                ans.push_back(path[i]);\n            }\n            remaining -= extra;\n        }\n    }\n    \n    // Ensure we don't exceed 200\n    if (ans.size() > 200) ans.resize(200);\n    \n    // Optional: local search to improve score (if time permits)\n    // For now, output the greedy solution\n    cout << ans << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\n// Direction arrays: 0=left, 1=up, 2=right, 3=down\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\n// Transition table for each tile type and entry direction\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0: curve (right, up)\n    {3, -1, -1, 0},  // 1: curve (left, down)\n    {-1, -1, 3, 2},  // 2: curve (up, left)\n    {-1, 2, 1, -1},  // 3: curve (down, right)\n    {1, 0, 3, 2},    // 4: double curve (all sides)\n    {3, 2, 1, 0},    // 5: double curve (all sides, crossed)\n    {2, -1, 0, -1},  // 6: straight (left-right)\n    {-1, 3, -1, 1},  // 7: straight (up-down)\n};\n\nstruct State {\n    array<array<int, 30>, 30> tiles;\n    \n    // Evaluate all loops and return sorted lengths\n    vector<int> getLoopLengths() const {\n        vector<int> lengths;\n        vector<vector<bool>> visited(30, vector<bool>(30, false));\n        \n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                if (!visited[i][j]) {\n                    // Check all possible entry directions for this tile\n                    for (int d = 0; d < 4; d++) {\n                        int len = traceLoop(i, j, d, visited);\n                        if (len > 0) {\n                            lengths.push_back(len);\n                        }\n                    }\n                }\n            }\n        }\n        \n        sort(lengths.rbegin(), lengths.rend());\n        return lengths;\n    }\n    \n    int traceLoop(int si, int sj, int sd, vector<vector<bool>>& visited) const {\n        int i = si, j = sj, d = sd;\n        int length = 0;\n        \n        while (true) {\n            int d2 = to[tiles[i][j]][d];\n            if (d2 == -1) return 0;\n            \n            i += di[d2];\n            j += dj[d2];\n            if (i < 0 || i >= 30 || j < 0 || j >= 30) return 0;\n            d = (d2 + 2) % 4;\n            length++;\n            \n            if (i == si && j == sj && d == sd) {\n                // Mark all tiles in this loop as visited\n                i = si; j = sj; d = sd;\n                for (int k = 0; k < length; k++) {\n                    visited[i][j] = true;\n                    int d2 = to[tiles[i][j]][d];\n                    i += di[d2];\n                    j += dj[d2];\n                    d = (d2 + 2) % 4;\n                }\n                return length;\n            }\n            \n            if (length > 900) return 0; // safety\n        }\n    }\n    \n    // Fast evaluation - just find top 2 loops without marking visited\n    pair<int,int> getTopTwo() const {\n        int L1 = 0, L2 = 0;\n        vector<vector<bool>> visited(30, vector<bool>(30, false));\n        \n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                if (!visited[i][j]) {\n                    for (int d = 0; d < 4; d++) {\n                        int len = traceLoop(i, j, d, visited);\n                        if (len > 0) {\n                            if (len > L1) {\n                                L2 = L1;\n                                L1 = len;\n                            } else if (len > L2) {\n                                L2 = len;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return {L1, L2};\n    }\n    \n    long long getScore() const {\n        auto [L1, L2] = getTopTwo();\n        return (long long)L1 * L2;\n    }\n    \n    int getTile(int i, int j) const {\n        return tiles[i][j];\n    }\n    \n    void setTile(int i, int j, int t) {\n        tiles[i][j] = t;\n    }\n    \n    void rotateTile(int i, int j, int times) {\n        tiles[i][j] = (tiles[i][j] + times) % 8;\n    }\n};\n\n// Convert rotation state to output string\nstring encodeState(const State& state, const array<array<int,30>,30>& original) {\n    string output;\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int rot = (state.tiles[i][j] - original[i][j] + 8) % 8;\n            output += char('0' + (rot % 4));\n        }\n    }\n    return output;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    array<array<int,30>,30> original;\n    for (int i = 0; i < 30; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 30; j++) {\n            original[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Start with original state\n    State bestState;\n    bestState.tiles = original;\n    long long bestScore = bestState.getScore();\n    \n    // Random number generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, 29);\n    uniform_int_distribution<int> rotDist(1, 3);\n    uniform_real_distribution<double> probDist(0.0, 1.0);\n    \n    // Multiple random restarts\n    for (int restart = 0; restart < 50; restart++) {\n        State current;\n        current.tiles = original;\n        \n        // Random rotations for initial state\n        if (restart > 0) {\n            for (int i = 0; i < 30; i++) {\n                for (int j = 0; j < 30; j++) {\n                    int r = uniform_int_distribution<int>(0, 3)(rng);\n                    for (int k = 0; k < r; k++) {\n                        current.tiles[i][j] = (current.tiles[i][j] + 1) % 8;\n                    }\n                }\n            }\n        }\n        \n        long long currentScore = current.getScore();\n        \n        // Simulated annealing\n        double temperature = 100.0;\n        double coolingRate = 0.9995;\n        \n        for (int iter = 0; iter < 2000; iter++) {\n            // Try small local changes\n            for (int change = 0; change < 20; change++) {\n                int i = dist(rng);\n                int j = dist(rng);\n                int oldTile = current.tiles[i][j];\n                int rot = rotDist(rng);\n                \n                // Apply rotation\n                current.tiles[i][j] = (current.tiles[i][j] + rot) % 8;\n                \n                long long newScore = current.getScore();\n                \n                // Accept or reject\n                if (newScore > currentScore || \n                    probDist(rng) < exp((newScore - currentScore) / temperature)) {\n                    currentScore = newScore;\n                } else {\n                    // Revert\n                    current.tiles[i][j] = oldTile;\n                }\n                \n                if (currentScore > bestScore) {\n                    bestState = current;\n                    bestScore = currentScore;\n                }\n            }\n            \n            temperature *= coolingRate;\n        }\n    }\n    \n    // Output result\n    string output = encodeState(bestState, original);\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Direction mappings\nconst int dy[] = {-1, 1, 0, 0};  // U, D, L, R\nconst int dx[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int rev_dir[] = {1, 0, 3, 2};  // Reverse directions\n\n// Tile bitmasks: L=1, U=2, R=4, D=8\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\n\nint N, T;\nvector<vector<int>> board;\npair<int,int> empty_pos;\n\n// Convert hex char to int\nint hex_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\n// Convert int to hex char\nchar int_to_hex(int v) {\n    if (v < 10) return '0' + v;\n    return 'a' + v - 10;\n}\n\n// Check if position is valid\nbool valid(int y, int x) {\n    return y >= 0 && y < N && x >= 0 && x < N;\n}\n\n// Calculate tree size from current board\nint calc_tree_size(const vector<vector<int>>& b) {\n    int n = N * N - 1;\n    vector<vector<pair<int,int>>> adj(N, vector<pair<int,int>>(N));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    // Build adjacency based on line connections\n    auto get_max_tree = [&](int sy, int sx) -> int {\n        if (b[sy][sx] == 0) return 0;\n        queue<pair<int,int>> q;\n        q.push({sy, sx});\n        visited[sy][sx] = true;\n        int sz = 0;\n        \n        while (!q.empty()) {\n            auto [y, x] = q.front(); q.pop();\n            sz++;\n            int tile = b[y][x];\n            \n            // Up\n            if ((tile & UP) && y > 0 && (b[y-1][x] & DOWN) && !visited[y-1][x]) {\n                visited[y-1][x] = true;\n                q.push({y-1, x});\n            }\n            // Down\n            if ((tile & DOWN) && y < N-1 && (b[y+1][x] & UP) && !visited[y+1][x]) {\n                visited[y+1][x] = true;\n                q.push({y+1, x});\n            }\n            // Left\n            if ((tile & LEFT) && x > 0 && (b[y][x-1] & RIGHT) && !visited[y][x-1]) {\n                visited[y][x-1] = true;\n                q.push({y, x-1});\n            }\n            // Right\n            if ((tile & RIGHT) && x < N-1 && (b[y][x+1] & LEFT) && !visited[y][x+1]) {\n                visited[y][x+1] = true;\n                q.push({y, x+1});\n            }\n        }\n        return sz;\n    };\n    \n    int max_tree = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] != 0 && !visited[i][j]) {\n                int sz = get_max_tree(i, j);\n                max_tree = max(max_tree, sz);\n            }\n        }\n    }\n    return max_tree;\n}\n\n// Find path from empty to target using BFS (always possible on any state)\nstring find_path(int ty, int tx) {\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> dir_used(N, vector<int>(N, -1));\n    \n    queue<pair<int,int>> q;\n    q.push(empty_pos);\n    vis[empty_pos.first][empty_pos.second] = true;\n    \n    while (!q.empty()) {\n        auto [y, x] = q.front(); q.pop();\n        if (y == ty && x == tx) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int ny = y + dy[d], nx = x + dx[d];\n            if (!valid(ny, nx) || vis[ny][nx]) continue;\n            vis[ny][nx] = true;\n            parent[ny][nx] = {y, x};\n            dir_used[ny][nx] = d;\n            q.push({ny, nx});\n        }\n    }\n    \n    // Reconstruct path\n    string path;\n    int cy = ty, cx = tx;\n    while (!(cy == empty_pos.first && cx == empty_pos.second)) {\n        int d = dir_used[cy][cx];\n        path += dir_char[d];\n        auto [py, px] = parent[cy][cx];\n        // The direction from parent to child is the opposite\n        cy = py; cx = px;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Also need to reverse direction because we want to move tiles INTO empty\n    // Actually, we need to move tile at (ty,tx) to empty's position\n    // So we move empty to (ty,tx), which means tiles move in opposite direction\n    string result;\n    for (char c : path) {\n        if (c == 'U') result += 'D';\n        else if (c == 'D') result += 'U';\n        else if (c == 'L') result += 'R';\n        else result += 'L';\n    }\n    \n    return result;\n}\n\n// Apply a move sequence to the board\nvoid apply_moves(const string& moves) {\n    for (char c : moves) {\n        int d;\n        if (c == 'U') d = 0;\n        else if (c == 'D') d = 1;\n        else if (c == 'L') d = 2;\n        else d = 3;\n        \n        int ny = empty_pos.first + dy[d];\n        int nx = empty_pos.second + dx[d];\n        swap(board[empty_pos.first][empty_pos.second], board[ny][nx]);\n        empty_pos = {ny, nx};\n    }\n}\n\n// Main solve function\nstring solve() {\n    // Read input\n    string line;\n    getline(cin, line);\n    stringstream ss(line);\n    ss >> N >> T;\n    \n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string row;\n        getline(cin, row);\n        // Remove spaces if any\n        row.erase(remove(row.begin(), row.end(), ' '), row.end());\n        for (int j = 0; j < N; j++) {\n            board[i][j] = hex_to_int(row[j]);\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n            }\n        }\n    }\n    \n    string result;\n    int max_operations = T;\n    \n    // Strategy: Try to create a spanning tree structure\n    // Since we know a perfect tree is reachable, try to fix problematic connections\n    \n    // First, find current tree size\n    int current_tree = calc_tree_size(board);\n    \n    // If we already have perfect tree, minimal moves\n    if (current_tree == N * N - 1) {\n        return \"\";\n    }\n    \n    // Greedy approach: Try to improve connections\n    // Look for tiles that can be connected but aren't\n    \n    // Simple heuristic: move the empty tile in a pattern to try to create connections\n    // This is a placeholder for more sophisticated algorithms\n    \n    // For now, just do a snake pattern to shuffle tiles\n    for (int round = 0; round < 2 && result.size() < max_operations; round++) {\n        // Snake pattern\n        if (result.size() < max_operations) {\n            // Move right across top row\n            while (empty_pos.second < N-1 && result.size() < max_operations) {\n                result += 'R';\n                apply_moves(\"R\");\n            }\n            while (empty_pos.second > 0 && result.size() < max_operations) {\n                result += 'L';\n                apply_moves(\"L\");\n            }\n            // Move down\n            if (empty_pos.first < N-1 && result.size() < max_operations) {\n                result += 'D';\n                apply_moves(\"D\");\n            }\n        }\n        \n        if (result.size() < max_operations) {\n            // Move left across row\n            while (empty_pos.second > 0 && result.size() < max_operations) {\n                result += 'L';\n                apply_moves(\"L\");\n            }\n            while (empty_pos.second < N-1 && result.size() < max_operations) {\n                result += 'R';\n                apply_moves(\"R\");\n            }\n            if (empty_pos.first < N-1 && result.size() < max_operations) {\n                result += 'D';\n                apply_moves(\"D\");\n            }\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    string answer = solve();\n    cout << answer << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ld = long double;\n\nconst ld PI = acosl(-1.0L);\n\nstruct Point {\n    ll x, y;\n};\n\n// Cross product sign for line through points p1,p2 at point p\nint side(const Point& p1, const Point& p2, const Point& p) {\n    ll dx = p2.x - p1.x;\n    ll dy = p2.y - p1.y;\n    ll cross = dx * (p.y - p1.y) - dy * (p.x - p1.x);\n    if (cross > 0) return 1;\n    if (cross < 0) return -1;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Sort strawberries by polar angle\n    vector<pair<ld, int>> by_angle;\n    for (int i = 0; i < N; ++i) {\n        if (strawberries[i].x == 0 && strawberries[i].y == 0) {\n            by_angle.emplace_back(-PI - 1, i); // center first\n        } else {\n            by_angle.emplace_back(atan2l(strawberries[i].y, strawberries[i].x), i);\n        }\n    }\n    sort(by_angle.begin(), by_angle.end());\n\n    // Build target piece sizes: we want as many pieces of each size d as possible (up to a_d)\n    // We'll process strawberries in order, creating pieces of target sizes\n    vector<int> target_sizes;\n    for (int d = 10; d >= 1; --d) {\n        for (int j = 0; j < a[d]; ++j) {\n            target_sizes.push_back(d);\n        }\n    }\n\n    // We'll use cuts through origin to create sectors\n    // Each sector will contain exactly 'target' strawberries\n    // If we need to discard strawberries, we cut through them\n    vector<pair<Point,Point>> cuts;\n    int cursor = 0;\n    int target_idx = 0;\n    vector<int> piece_counts;\n\n    while (cursor < N && target_idx < (int)target_sizes.size()) {\n        int target = target_sizes[target_idx];\n        // Collect target strawberries for this sector\n        vector<int> sector_indices;\n        int needed = target;\n        \n        // We may need to skip some strawberries (cut through them) if we can't get exact count\n        while (cursor < N && needed > 0) {\n            if (needed == 1) {\n                // We need exactly one more, take it\n                sector_indices.push_back(by_angle[cursor].second);\n                cursor++;\n                needed--;\n            } else if (needed <= (N - cursor)) {\n                // We have enough remaining strawberries, take one\n                sector_indices.push_back(by_angle[cursor].second);\n                cursor++;\n                needed--;\n            } else {\n                // Not enough strawberries left, break\n                break;\n            }\n        }\n\n        if (needed == 0) {\n            // Successfully created a sector with target strawberries\n            piece_counts.push_back(target);\n            // Add a radial cut after this sector (unless it's the last)\n            if (cursor < N) {\n                int last_idx = sector_indices.back();\n                ld angle = by_angle[cursor].first; // angle of next strawberry\n                // Cut through origin at this angle\n                Point p1 = {0, 0};\n                Point p2 = {ll(1e9 * cosl(angle)), ll(1e9 * sinl(angle))};\n                cuts.emplace_back(p1, p2);\n            }\n            target_idx++;\n        } else {\n            // Couldn't get exact count, this strawberry is discarded (cut through it)\n            // Create cut through this strawberry\n            int discard_idx = by_angle[cursor].second;\n            ld angle = by_angle[cursor].first;\n            Point p1 = {0, 0};\n            // Second point in perpendicular direction to cut through the point\n            Point p2 = {strawberries[discard_idx].x + ll(1e9 * cosl(angle + PI/2)),\n                       strawberries[discard_idx].y + ll(1e9 * sinl(angle + PI/2))};\n            cuts.emplace_back(p1, p2);\n            cursor++;\n        }\n    }\n\n    // If we have more cuts available, add some random cuts to improve\n    // But we may not need them - just use what we have\n\n    int k = min((int)cuts.size(), K);\n    cout << k << \"\\n\";\n    for (int i = 0; i < k; ++i) {\n        cout << cuts[i].first.x << \" \" << cuts[i].first.y << \" \"\n             << cuts[i].second.x << \" \" << cuts[i].second.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n};\n\nstruct Rectangle {\n    Point p[4];\n    int weight;\n};\n\nint N, M;\nvector<vector<bool>> hasDot;\nvector<vector<bool>> occupied; // for rectangle perimeters\nint center;\n\n// Precompute weights\nvector<vector<int>> weight;\n\nint get_weight(int x, int y) {\n    return (x-center)*(x-center) + (y-center)*(y-center) + 1;\n}\n\nbool can_place_rectangle(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {\n    // Check if p1 is empty\n    if (hasDot[p1.x][p1.y]) return false;\n    \n    // Check if p2, p3, p4 have dots\n    if (!hasDot[p2.x][p2.y] || !hasDot[p3.x][p3.y] || !hasDot[p4.x][p4.y]) return false;\n    \n    // Check condition 2: no other dots on perimeter\n    // Simplified check for axis-aligned rectangles\n    auto check_line = [&](int x1, int y1, int x2, int y2) {\n        if (x1 == x2) {\n            for (int y = min(y1,y2); y <= max(y1,y2); y++) {\n                if (hasDot[x1][y] && !(Point(x1,y) == p2 || Point(x1,y) == p3 || Point(x1,y) == p4)) return false;\n            }\n        } else if (y1 == y2) {\n            for (int x = min(x1,x2); x <= max(x1,x2); x++) {\n                if (hasDot[x][y1] && !(Point(x,y1) == p2 || Point(x,y1) == p3 || Point(x,y1) == p4)) return false;\n            }\n        }\n        return true;\n    };\n    \n    return check_line(p1.x, p1.y, p2.x, p2.y) && \n           check_line(p2.x, p2.y, p3.x, p3.y) &&\n           check_line(p3.x, p3.y, p4.x, p4.y) &&\n           check_line(p4.x, p4.y, p1.x, p1.y);\n}\n\nvoid find_candidates(vector<Rectangle>& candidates) {\n    candidates.clear();\n    \n    // Search for possible rectangles centered on empty points\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            if (hasDot[x][y]) continue;\n            \n            // Try axis-aligned rectangles\n            for (int dx = 1; dx < N; dx++) {\n                for (int dy = 1; dy < N; dy++) {\n                    // Check all four corners\n                    int x1 = x - dx, y1 = y;\n                    int x2 = x, y2 = y + dy;\n                    int x3 = x + dx, y3 = y;\n                    int x4 = x, y4 = y - dy;\n                    \n                    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) continue;\n                    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) continue;\n                    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N) continue;\n                    \n                    Rectangle r;\n                    r.p[0] = Point(x, y);\n                    r.p[1] = Point(x1, y1);\n                    r.p[2] = Point(x2, y2);\n                    r.p[3] = Point(x3, y3);\n                    r.weight = weight[x][y];\n                    \n                    if (can_place_rectangle(r.p[0], r.p[1], r.p[2], r.p[3])) {\n                        candidates.push_back(r);\n                    }\n                }\n            }\n            \n            // Try 45\u00b0 rotated rectangles\n            for (int d = 1; d < N; d++) {\n                int x1 = x - d, y1 = y - d;\n                int x2 = x, y2 = y - d;\n                int x3 = x + d, y3 = y;\n                int x4 = x, y4 = y + d;\n                \n                if (x1 >= 0 && x1 < N && y1 >= 0 && y1 < N &&\n                    x2 >= 0 && x2 < N && y2 >= 0 && y2 < N &&\n                    x3 >= 0 && x3 < N && y3 >= 0 && y3 < N &&\n                    x4 >= 0 && x4 < N && y4 >= 0 && y4 < N) {\n                    \n                    Rectangle r;\n                    r.p[0] = Point(x, y);\n                    r.p[1] = Point(x1, y1);\n                    r.p[2] = Point(x2, y2);\n                    r.p[3] = Point(x3, y3);\n                    r.weight = weight[x][y];\n                    \n                    if (can_place_rectangle(r.p[0], r.p[1], r.p[2], r.p[3])) {\n                        candidates.push_back(r);\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    hasDot.assign(N, vector<bool>(N, false));\n    occupied.assign(N, vector<bool>(N, false));\n    center = (N-1)/2;\n    \n    weight.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            weight[i][j] = get_weight(i, j);\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        hasDot[x][y] = true;\n    }\n    \n    vector<array<int, 8>> operations;\n    vector<Rectangle> candidates;\n    \n    // Greedy algorithm with multiple attempts\n    auto solve = [&]() -> vector<array<int, 8>> {\n        vector<array<int, 8>> ops;\n        auto temp_hasDot = hasDot;\n        \n        while (true) {\n            find_candidates(candidates);\n            if (candidates.empty()) break;\n            \n            // Sort by weight descending\n            sort(candidates.begin(), candidates.end(), \n                 [](const Rectangle& a, const Rectangle& b) {\n                     return a.weight > b.weight;\n                 });\n            \n            // Take the best candidate\n            Rectangle best = candidates[0];\n            \n            // Place the rectangle\n            Point p1 = best.p[0];\n            temp_hasDot[p1.x][p1.y] = true;\n            \n            ops.push_back({p1.x, p1.y, \n                          best.p[1].x, best.p[1].y,\n                          best.p[2].x, best.p[2].y,\n                          best.p[3].x, best.p[3].y});\n        }\n        \n        return ops;\n    };\n    \n    operations = solve();\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            cout << op[i] << (i < 7 ? \" \" : \"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int T = 100;\n\n// Direction vectors: F, B, L, R\nconst int dx[] = {0, 0, -1, 1};  // row change (0=front, 1=back, 2=left, 3=right)\nconst int dy[] = {1, -1, 0, 0};  // col change\n\nstruct State {\n    int grid[N][N] = {};  // 0=empty, 1-3=flavors\n    int empty_count = N * N;\n    \n    State() {}\n    \n    // Initialize from another state\n    State(const State& other) {\n        memcpy(grid, other.grid, sizeof(grid));\n        empty_count = other.empty_count;\n    }\n    \n    // Check if cell is valid\n    bool valid(int x, int y) const {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    // Tilt in direction d (0=F, 1=B, 2=L, 3=R)\n    State tilt(int d) const {\n        State res(*this);\n        \n        // Determine iteration order based on direction\n        if (d == 0) {  // Forward (toward row 0, y++)\n            for (int x = 0; x < N; x++) {\n                for (int y = 0; y < N; y++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    // Try to move forward (decreasing y)\n                    while (ny > 0 && res.grid[x][ny-1] == 0) ny--;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 1) {  // Backward (toward row N-1, y--)\n            for (int x = 0; x < N; x++) {\n                for (int y = N-1; y >= 0; y--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny < N-1 && res.grid[x][ny+1] == 0) ny++;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 2) {  // Left (toward col 0, x--)\n            for (int y = 0; y < N; y++) {\n                for (int x = 0; x < N; x++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx > 0 && res.grid[nx-1][y] == 0) nx--;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else {  // Right (toward col N-1, x++)\n            for (int y = 0; y < N; y++) {\n                for (int x = N-1; x >= 0; x--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx < N-1 && res.grid[nx+1][y] == 0) nx++;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        \n        return res;\n    }\n    \n    // Place candy at position p (1-indexed in empty cells ordering)\n    void place(int p, int flavor) {\n        int count = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[x][y] = flavor;\n                        empty_count--;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Evaluate the state - higher is better\n    double evaluate() const {\n        // Count adjacent same-flavor pairs\n        double score = 0.0;\n        \n        // Horizontal pairs\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N-1; x++) {\n                if (grid[x][y] != 0 && grid[x+1][y] != 0 && grid[x][y] == grid[x+1][y]) {\n                    score += 1.0;\n                }\n            }\n        }\n        \n        // Vertical pairs\n        for (int y = 0; y < N-1; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0 && grid[x][y+1] != 0 && grid[x][y] == grid[x][y+1]) {\n                    score += 1.0;\n                }\n            }\n        }\n        \n        // Bonus for large empty spaces (future flexibility)\n        // Count maximum consecutive empty cells in each direction\n        double empty_bonus = 0.0;\n        \n        // Check rows\n        for (int y = 0; y < N; y++) {\n            int streak = 0;\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    streak++;\n                } else {\n                    empty_bonus += streak * streak * 0.01;\n                    streak = 0;\n                }\n            }\n            empty_bonus += streak * streak * 0.01;\n        }\n        \n        // Check columns\n        for (int x = 0; x < N; x++) {\n            int streak = 0;\n            for (int y = 0; y < N; y++) {\n                if (grid[x][y] == 0) {\n                    streak++;\n                } else {\n                    empty_bonus += streak * streak * 0.01;\n                    streak = 0;\n                }\n            }\n            empty_bonus += streak * streak * 0.01;\n        }\n        \n        // Penalty for isolated cells (no same-flavor neighbors)\n        double isolation_penalty = 0.0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int same_neighbors = 0;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] == grid[x][y]) {\n                        same_neighbors++;\n                    }\n                }\n                if (same_neighbors == 0) {\n                    isolation_penalty -= 0.5;\n                }\n            }\n        }\n        \n        return score + empty_bonus + isolation_penalty;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read flavors\n    vector<int> flavors(T);\n    for (int i = 0; i < T; i++) {\n        cin >> flavors[i];\n    }\n    \n    State current_state;\n    const char dir_names[] = {'F', 'B', 'L', 'R'};\n    \n    // Process each candy\n    for (int t = 0; t < T; t++) {\n        int p;\n        cin >> p;\n        \n        // Place the candy\n        current_state.place(p, flavors[t]);\n        \n        // If last candy, no need to tilt\n        if (t == T - 1) break;\n        \n        // Evaluate all 4 possible tilts\n        double best_score = -1e18;\n        int best_dir = 0;\n        \n        for (int d = 0; d < 4; d++) {\n            State new_state = current_state.tilt(d);\n            double score = new_state.evaluate();\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n        \n        // Apply the best tilt\n        current_state = current_state.tilt(best_dir);\n        \n        // Output direction\n        cout << dir_names[best_dir] << '\\n';\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <queue>\nusing namespace std;\n\nconst int QUERIES = 100;\nint M;\ndouble eps;\n\n// Generate adjacency matrix from string\nvector<vector<bool>> strToAdj(const string& s, int N) {\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            adj[i][j] = adj[j][i] = (s[idx++] == '1');\n        }\n    }\n    return adj;\n}\n\n// Encode graph to string\nstring adjToStr(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    string s;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            s += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Edge count\nint countEdges(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (adj[i][j]) cnt++;\n        }\n    }\n    return cnt;\n}\n\n// Degree sequence (sorted)\nvector<int> getDegreeSeq(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (adj[i][j]) deg[i]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Count triangles\nint countTriangles(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (!adj[i][j]) continue;\n            for (int k = j+1; k < N; k++) {\n                if (adj[i][k] && adj[j][k]) cnt++;\n            }\n        }\n    }\n    return cnt;\n}\n\n// Global clustering coefficient\ndouble clusteringCoefficient(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int triangles = 0;\n    int triplets = 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                int e = adj[i][k] + adj[j][k];\n                if (e == 2) triangles++;\n                if (e >= 1) triplets++;\n            }\n        }\n    }\n    return triplets > 0 ? (double)triangles / triplets : 0.0;\n}\n\n// Katz centrality (approximate)\nvector<double> katzCentrality(const vector<vector<bool>>& adj, double alpha = 0.1) {\n    int N = adj.size();\n    vector<double> cent(N, 1.0);\n    vector<double> newCent(N);\n    \n    for (int iter = 0; iter < 50; iter++) {\n        fill(newCent.begin(), newCent.end(), 1.0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (adj[i][j]) {\n                    newCent[i] += alpha * cent[j];\n                }\n            }\n        }\n        // Normalize\n        double norm = 0;\n        for (double v : newCent) norm += v * v;\n        norm = sqrt(norm);\n        for (double& v : newCent) v /= norm;\n        cent = newCent;\n    }\n    sort(cent.begin(), cent.end());\n    return cent;\n}\n\n// Average shortest path (using BFS on small N)\ndouble avgPathLength(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    if (N > 50) return 0;  // Skip for large graphs\n    \n    double total = 0;\n    int count = 0;\n    \n    for (int start = 0; start < min(N, 10); start++) {  // Sample 10 sources\n        vector<int> dist(N, -1);\n        queue<int> q;\n        dist[start] = 0;\n        q.push(start);\n        \n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v = 0; v < N; v++) {\n                if (adj[u][v] && dist[v] == -1) {\n                    dist[v] = dist[u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (v != start && dist[v] > 0) {\n                total += dist[v];\n                count++;\n            }\n        }\n    }\n    return count > 0 ? total / count : 0;\n}\n\n// Compute comprehensive feature vector\nvector<double> computeFeatures(const vector<vector<bool>>& adj, int N) {\n    vector<double> features;\n    \n    // 1. Edge count (most reliable)\n    int edges = countEdges(adj);\n    features.push_back(edges);\n    \n    // 2. Degree sequence statistics\n    auto deg = getDegreeSeq(adj);\n    double mean = 0;\n    for (int d : deg) mean += d;\n    mean /= N;\n    \n    double var = 0;\n    for (int d : deg) var += (d - mean) * (d - mean);\n    var /= N;\n    \n    features.push_back(deg[0]);           // min degree\n    features.push_back(deg[N/4]);         // Q1\n    features.push_back(deg[N/2]);         // median\n    features.push_back(deg[3*N/4]);       // Q3\n    features.push_back(deg[N-1]);         // max degree\n    features.push_back(var / (mean + 1)); // CV^2\n    \n    // 3. Count special degree nodes\n    int isolated = 0, leaves = 0, highDeg = 0;\n    for (int d : deg) {\n        if (d == 0) isolated++;\n        if (d == 1) leaves++;\n        if (d > mean * 1.5) highDeg++;\n    }\n    features.push_back(isolated);\n    features.push_back(leaves);\n    features.push_back(highDeg);\n    \n    // 4. Triangle-based features\n    int triangles = countTriangles(adj);\n    double maxTriangles = (double)N * (N-1) * (N-2) / 6;\n    features.push_back(triangles);\n    features.push_back(maxTriangles > 0 ? triangles / maxTriangles : 0);\n    \n    // 5. Clustering coefficient\n    features.push_back(clusteringCoefficient(adj));\n    \n    // 6. Katz centrality statistics\n    if (N <= 50) {\n        auto katz = katzCentrality(adj);\n        sort(katz.begin(), katz.end());\n        features.push_back(katz[0]);\n        features.push_back(katz[N/2]);\n        features.push_back(katz[N-1]);\n        double katzVar = 0, katzMean = accumulate(katz.begin(), katz.end(), 0.0) / N;\n        for (double v : katz) katzVar += (v - katzMean) * (v - katzMean);\n        features.push_back(sqrt(katzVar / N));\n    } else {\n        features.push_back(0);\n        features.push_back(0);\n        features.push_back(0);\n        features.push_back(0);\n    }\n    \n    // 7. Path length approximation\n    features.push_back(avgPathLength(adj));\n    \n    return features;\n}\n\n// Weighted L2 distance\ndouble weightedDist(const vector<double>& a, const vector<double>& b, const vector<double>& weights) {\n    double d = 0;\n    for (int i = 0; i < (int)a.size(); i++) {\n        double diff = a[i] - b[i];\n        // Normalize by typical scale (using mean of both)\n        double scale = max(1.0, (abs(a[i]) + abs(b[i])) / 2.0);\n        d += weights[i] * diff * diff / (scale * scale);\n    }\n    return sqrt(d);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read M and epsilon\n    cin >> M >> eps;\n    \n    // Adaptive N selection based on M and epsilon\n    int N;\n    if (eps <= 0.02) {\n        N = min(100, max(20, 15 + M / 2));\n    } else if (eps <= 0.05) {\n        N = min(80, max(15, 12 + M / 3));\n    } else if (eps <= 0.10) {\n        N = min(60, max(12, 10 + M / 4));\n    } else if (eps <= 0.20) {\n        N = min(40, max(10, 8 + M / 5));\n    } else if (eps <= 0.30) {\n        N = min(30, max(8, 6 + M / 6));\n    } else {\n        N = min(20, max(6, 4 + M / 8));\n    }\n    \n    // Generate structured graphs\n    vector<vector<vector<bool>>> graphs(M, vector<vector<bool>>(N, vector<bool>(N, false)));\n    vector<vector<double>> graphFeatures(M);\n    \n    int totalEdges = N * (N - 1) / 2;\n    mt19937 rng(12345);  // Fixed seed for reproducibility\n    \n    for (int k = 0; k < M; k++) {\n        vector<vector<bool>>& adj = graphs[k];\n        double targetDensity = (double)k / (M - 1);\n        int targetEdges = max(1, (int)(targetDensity * totalEdges));\n        \n        // Create structured graphs with clear distinctions\n        if (eps <= 0.05) {\n            // Low noise: use highly structured graphs\n            if (k % 4 == 0) {\n                // Complete bipartite K_{a, N-a}\n                int a = max(1, min(N-1, 1 + k * (N-2) / M));\n                for (int i = 0; i < a; i++) {\n                    for (int j = a; j < N; j++) {\n                        adj[i][j] = adj[j][i] = true;\n                    }\n                }\n            } else if (k % 4 == 1) {\n                // Path + extra edges\n                for (int i = 0; i < N-1; i++) {\n                    adj[i][i+1] = adj[i+1][i] = true;\n                }\n                int extra = targetEdges - (N-1);\n                while (extra > 0) {\n                    int u = rng() % N, v = rng() % N;\n                    if (u != v && !adj[u][v]) {\n                        adj[u][v] = adj[v][u] = true;\n                        extra--;\n                    }\n                }\n            } else if (k % 4 == 2) {\n                // Regular-like graph with different degrees\n                int deg = targetEdges * 2 / N;\n                deg = max(1, min(N-1, deg));\n                for (int i = 0; i < N; i++) {\n                    for (int d = 1; d <= deg/2; d++) {\n                        int j = (i + d) % N;\n                        adj[i][j] = adj[j][i] = true;\n                    }\n                }\n            } else {\n                // Random Erdos-Renyi with specific density\n                uniform_real_distribution<double> unif(0, 1);\n                for (int i = 0; i < N; i++) {\n                    for (int j = i+1; j < N; j++) {\n                        if (unif(rng) < targetDensity) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            }\n        } else if (eps <= 0.15) {\n            // Medium noise: simpler structures\n            if (k < M / 3) {\n                // Star-like\n                for (int i = 1; i <= k && i < N; i++) {\n                    adj[0][i] = adj[i][0] = true;\n                }\n            } else if (k < 2 * M / 3) {\n                // Two communities with varying internal edges\n                int half = N / 2;\n                double density = (k - M/3) / (M/3.0);\n                for (int i = 0; i < half; i++) {\n                    for (int j = half; j < N; j++) {\n                        if (uniform_real_distribution<double>(0,1)(rng) < 0.3 + 0.5*density) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            } else {\n                // Dense graphs\n                for (int i = 0; i < N; i++) {\n                    for (int j = i+1; j < N; j++) {\n                        if (uniform_real_distribution<double>(0,1)(rng) < 0.7 + 0.3*targetDensity) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            }\n        } else {\n            // High noise: rely mostly on edge density\n            // Use simple Erdos-Renyi with controlled density\n            for (int i = 0; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    if (uniform_real_distribution<double>(0,1)(rng) < targetDensity) {\n                        adj[i][j] = adj[j][i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Ensure minimum edges for small k\n        if (countEdges(adj) < 1 && k > 0) {\n            adj[0][1] = adj[1][0] = true;\n        }\n        \n        graphFeatures[k] = computeFeatures(adj, N);\n    }\n    \n    // Precompute feature weights based on epsilon\n    // Edge count weight increases with noise\n    vector<double> featureWeights(graphFeatures[0].size(), 1.0);\n    featureWeights[0] = 1.0 + eps * 5;  // Edge count weighted more with noise\n    // Degree statistics weight\n    for (int i = 1; i <= 5; i++) featureWeights[i] = 1.0 + (1 - eps);\n    // Triangle features less reliable with noise\n    if (eps > 0.15) {\n        for (int i = 10; i <= 12; i++) featureWeights[i] = 0.5;\n    }\n    \n    // Output\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        cout << adjToStr(graphs[k]) << endl;\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < QUERIES; q++) {\n        string H_str;\n        cin >> H_str;\n        \n        auto H = strToAdj(H_str, N);\n        auto H_features = computeFeatures(H, N);\n        \n        // Weighted distance classification\n        int best = 0;\n        double bestDist = 1e18;\n        \n        // Also track edge-count only as fallback\n        int edgeBest = 0;\n        double edgeBestDist = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double dist = weightedDist(H_features, graphFeatures[k], featureWeights);\n            double edgeDist = abs(H_features[0] - graphFeatures[k][0]);\n            \n            if (dist < bestDist) {\n                bestDist = dist;\n                best = k;\n            }\n            if (edgeDist < edgeBestDist) {\n                edgeBestDist = edgeDist;\n                edgeBest = k;\n            }\n        }\n        \n        // For high noise, trust edge count more\n        double edgeRatio = abs(H_features[0] - graphFeatures[best][0]) / (double)max(1, (int)H_features[0]);\n        if (eps > 0.2 && edgeRatio > 0.3) {\n            best = edgeBest;\n        }\n        \n        cout << best << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\nconst double EPS = 1e-9;\n\nint N, M, D, K;\nvector<tuple<int, int, int>> edges;\nvector<vector<pair<int, int>>> graph;\n\n// Store all-pairs shortest paths\nvector<vector<int>> dist;\n\n// Edge importance: how critical is each edge\nvector<double> edge_importance;\n\nvoid compute_shortest_paths() {\n    dist.assign(N, vector<int>(N, INF));\n    \n    // Use Dijkstra from each source\n    for (int s = 0; s < N; s++) {\n        dist[s][s] = 0;\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[s][v]) continue;\n            \n            for (auto [to, w] : graph[v]) {\n                if (dist[s][to] > d + w) {\n                    dist[s][to] = d + w;\n                    pq.push({dist[s][to], to});\n                }\n            }\n        }\n    }\n}\n\nvoid compute_edge_importance() {\n    edge_importance.assign(M, 0.0);\n    \n    // For each pair of vertices, find which edges are on shortest paths\n    for (int s = 0; s < N; s++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return dist[s][a] < dist[s][b];\n        });\n        \n        // For each destination\n        for (int t = s+1; t < N; t++) {\n            if (dist[s][t] == INF) continue;\n            int shortest = dist[s][t];\n            \n            // Find edges on shortest paths from s to t\n            // For each edge, check if it lies on some shortest path\n            for (int e = 0; e < M; e++) {\n                auto [u, v, w] = edges[e];\n                if (dist[s][u] + w + dist[v][t] == shortest || \n                    dist[s][v] + w + dist[u][t] == shortest) {\n                    edge_importance[e] += 1.0 / (N * (N-1) / 2.0);\n                }\n            }\n        }\n    }\n}\n\ndouble quick_evaluate(const vector<int>& schedule) {\n    // Simplified evaluation: just look at how many important edges are on each day\n    double cost = 0;\n    \n    for (int day = 1; day <= D; day++) {\n        double day_importance = 0;\n        for (int e = 0; e < M; e++) {\n            if (schedule[e] == day) {\n                day_importance += edge_importance[e];\n            }\n        }\n        cost += day_importance * day_importance;  // Penalize concentration\n    }\n    \n    return cost;\n}\n\nvector<int> solve() {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Sort edges by importance\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    vector<int> best_schedule;\n    double best_cost = INF;\n    \n    // Multiple attempts with different random seeds\n    for (int trial = 0; trial < 20; trial++) {  // Reduced from 50 to save time\n        vector<int> schedule(M);\n        vector<int> day_count(D+1, 0);\n        \n        // Greedy assignment: put most important edges on separate days\n        for (int idx = 0; idx < M; idx++) {\n            int e = edge_order[idx];\n            \n            // Find the day with least important edges so far\n            vector<pair<double, int>> day_importance;\n            for (int d = 1; d <= D; d++) {\n                if (day_count[d] < K) {\n                    double imp = 0;\n                    for (int other_idx = 0; other_idx < idx; other_idx++) {\n                        int other = edge_order[other_idx];\n                        if (schedule[other] == d) {\n                            auto [u1, v1, w1] = edges[e];\n                            auto [u2, v2, w2] = edges[other];\n                            // Check if edges share a vertex - avoid putting them together\n                            if (u1 == u2 || u1 == v2 || v1 == u2 || v1 == v2) {\n                                imp += edge_importance[other];\n                            }\n                        }\n                    }\n                    day_importance.push_back({imp, d});\n                }\n            }\n            \n            // Sort by importance and pick the best day with some randomness\n            sort(day_importance.begin(), day_importance.end());\n            \n            int best_day;\n            if (rng() % 100 < 80) {  // 80% greedy, 20% random\n                best_day = day_importance[0].second;\n            } else {\n                best_day = day_importance[rng() % day_importance.size()].second;\n            }\n            \n            schedule[e] = best_day;\n            day_count[best_day]++;\n        }\n        \n        // Local search: try to improve by swapping edges between days\n        for (int iter = 0; iter < 500; iter++) {\n            int e1 = rng() % M;\n            int old_day = schedule[e1];\n            int new_day = rng() % D + 1;\n            \n            if (new_day == old_day) continue;\n            if (day_count[new_day] >= K) continue;\n            \n            // Quick check if swap improves things\n            auto [u1, v1, w1] = edges[e1];\n            \n            // Check if moving to new_day reduces conflicts\n            double old_conflict = 0, new_conflict = 0;\n            \n            for (int e2 = 0; e2 < M; e2++) {\n                if (e2 == e1) continue;\n                auto [u2, v2, w2] = edges[e2];\n                bool share_vertex = (u1 == u2 || u1 == v2 || v1 == u2 || v1 == v2);\n                \n                if (schedule[e2] == old_day && share_vertex) {\n                    old_conflict += edge_importance[e2];\n                }\n                if (schedule[e2] == new_day && share_vertex) {\n                    new_conflict += edge_importance[e2];\n                }\n            }\n            \n            if (new_conflict < old_conflict || rng() % 100 < 10) {\n                schedule[e1] = new_day;\n                day_count[old_day]--;\n                day_count[new_day]++;\n            }\n        }\n        \n        double cost = quick_evaluate(schedule);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_schedule = schedule;\n        }\n    }\n    \n    return best_schedule;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\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        graph[u].push_back({v, w});\n        graph[v].push_back({u, w});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Compute all-pairs shortest paths (do this once)\n    compute_shortest_paths();\n    \n    // Compute edge importance (do this once)\n    compute_edge_importance();\n    \n    // Generate schedule\n    vector<int> schedule = solve();\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << schedule[i] << (i+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct UnionFind {\n    vector<int> parent, rank;\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    void unite(int x, int y) {\n        x = find(x), y = find(y);\n        if (x == y) return;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D;\n    cin >> D;\n    \n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int k = 0; k < D; k++) cin >> f[i][k];\n        for (int k = 0; k < D; k++) cin >> r[i][k];\n    }\n    \n    // Initial construction: place cubes where both silhouettes have 1\n    vector<vector<vector<int>>> obj(2, vector<vector<int>>(D, vector<int>(D, vector<int>(D, 0))));\n    int total_cubes = 0;\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (f[i][z][x] == '1' && r[i][z][y] == '1') {\n                        obj[i][x][y][z] = 1;\n                        total_cubes++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find cube positions that are used in both objects\n    vector<tuple<int,int,int>> shared_cubes;\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 (obj[0][x][y][z] && obj[1][x][y][z]) {\n                    shared_cubes.push_back({x, y, z});\n                }\n            }\n        }\n    }\n    \n    // Assign block IDs using union find for merging\n    UnionFind uf(total_cubes);\n    vector<tuple<int,int,int>> all_cubes;\n    map<tuple<int,int,int>, int> cube_to_idx;\n    \n    int idx = 0;\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 (obj[i][x][y][z]) {\n                        all_cubes.push_back({x, y, z});\n                        // Check if this position is shared\n                        if (obj[0][x][y][z] && obj[1][x][y][z]) {\n                            cube_to_idx[{x, y, z}] = idx;\n                        }\n                        idx++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Greedy merging: merge adjacent cubes that are both shared\n    const int dx[] = {1, -1, 0, 0, 0, 0};\n    const int dy[] = {0, 0, 1, -1, 0, 0};\n    const int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    // Merge shared cubes first (higher priority)\n    for (auto [x, y, z] : shared_cubes) {\n        int cur_idx = cube_to_idx[{x, y, z}];\n        for (int d = 0; d < 6; d++) {\n            int nx = x + dx[d], ny = y + dy[d], nz = z + dz[d];\n            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n            if (obj[0][nx][ny][nz] && obj[1][nx][ny][nz]) {\n                if (cube_to_idx.count({nx, ny, nz})) {\n                    uf.unite(cur_idx, cube_to_idx[{nx, ny, nz}]);\n                }\n            }\n        }\n    }\n    \n    // Now merge all remaining adjacent cubes\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 (!obj[i][x][y][z]) continue;\n                    for (int d = 0; d < 6; d++) {\n                        int nx = x + dx[d], ny = y + dy[d], nz = z + dz[d];\n                        if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) continue;\n                        if (obj[i][nx][ny][nz]) {\n                            // Merge if they have the same \"shared\" status\n                            bool cur_shared = (obj[0][x][y][z] && obj[1][x][y][z]);\n                            bool nxt_shared = (obj[0][nx][ny][nz] && obj[1][nx][ny][nz]);\n                            if (cur_shared == nxt_shared) {\n                                uf.unite(i * D * D * D + x * D * D + y * D + z, \n                                        i * D * D * D + nx * D * D + ny * D + nz);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Assign block numbers\n    map<int, int> comp_to_block;\n    int block_cnt = 0;\n    \n    vector<vector<vector<int>>> result(2, vector<vector<int>>(D, vector<int>(D, vector<int>(D, 0))));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (obj[i][x][y][z]) {\n                        int comp = uf.find(i * D * D * D + x * D * D + y * D + z);\n                        if (!comp_to_block.count(comp)) {\n                            comp_to_block[comp] = ++block_cnt;\n                        }\n                        result[i][x][y][z] = comp_to_block[comp];\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << block_cnt << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (x > 0 || y > 0 || z > 0) cout << \" \";\n                    cout << result[i][x][y][z];\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Data structures\nstruct Edge {\n    int u, v;\n    long long w;\n};\n\nint N, M, K;\nvector<pair<int,int>> vertices;\nvector<Edge> edges;\nvector<pair<int,int>> residents;\n\n// Read input\nvoid read_input() {\n    cin >> N >> M >> K;\n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n    }\n    residents.resize(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n}\n\n// Compute squared Euclidean distance\nlong long squared_dist(pair<int,int> a, pair<int,int> b) {\n    long long dx = a.first - b.first;\n    long long dy = a.second - b.second;\n    return dx*dx + dy*dy;\n}\n\ndouble dist(pair<int,int> a, pair<int,int> b) {\n    return sqrt(squared_dist(a, b));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    read_input();\n    \n    // Phase 1: For each station, compute minimum power to cover each resident\n    // Phase 2: Select stations to power on and build tree\n    \n    // Simple heuristic: Use all stations initially, then try to reduce\n    \n    // Compute for each resident, which stations can cover it with reasonable power\n    const int MAX_POWER = 5000;\n    const long long MAX_POWER_SQ = (long long)MAX_POWER * MAX_POWER;\n    \n    // Start with all edges off, all powers 0\n    vector<int> P(N, 0);\n    vector<bool> edge_on(M, false);\n    \n    // First, find for each resident the nearest station\n    vector<int> nearest_station(K, -1);\n    vector<long long> min_dist_sq(K, LLONG_MAX);\n    \n    for (int i = 0; i < K; i++) {\n        for (int j = 0; j < N; j++) {\n            long long d = squared_dist(vertices[j], residents[i]);\n            if (d < min_dist_sq[i]) {\n                min_dist_sq[i] = d;\n                nearest_station[i] = j;\n            }\n        }\n    }\n    \n    // Greedy: power on stations that cover many residents with low cost\n    vector<bool> station_on(N, false);\n    station_on[0] = true; // Station 1 is always on\n    \n    // Compute cost-benefit for each station\n    vector<pair<double, int>> station_score;\n    for (int i = 0; i < N; i++) {\n        if (i == 0) continue;\n        int covered = 0;\n        long long max_power_sq = 0;\n        for (int k = 0; k < K; k++) {\n            long long d = squared_dist(vertices[i], residents[k]);\n            if (d <= MAX_POWER_SQ) {\n                covered++;\n                max_power_sq = max(max_power_sq, d);\n            }\n        }\n        if (covered > 0) {\n            double power_cost = sqrt(max_power_sq);\n            double benefit = covered / (power_cost * power_cost + 1);\n            station_score.push_back({-benefit, i});\n        }\n    }\n    sort(station_score.begin(), station_score.end());\n    \n    // Select top stations greedily\n    vector<int> selected_stations = {0};\n    for (auto& s : station_score) {\n        int idx = s.second;\n        if (selected_stations.size() < 20) { // Limit to avoid high cost\n            selected_stations.push_back(idx);\n            station_on[idx] = true;\n        }\n    }\n    \n    // Build MST to connect selected stations to station 1\n    // Use Prim's algorithm\n    vector<bool> in_tree(N, false);\n    vector<long long> min_edge(N, LLONG_MAX);\n    vector<int> parent(N, -1);\n    \n    // Start from station 1\n    in_tree[0] = true;\n    for (int j = 0; j < M; j++) {\n        if (edges[j].u == 0) {\n            if (edges[j].w < min_edge[edges[j].v]) {\n                min_edge[edges[j].v] = edges[j].w;\n                parent[edges[j].v] = j;\n            }\n        }\n        if (edges[j].v == 0) {\n            if (edges[j].w < min_edge[edges[j].u]) {\n                min_edge[edges[j].u] = edges[j].w;\n                parent[edges[j].u] = j;\n            }\n        }\n    }\n    \n    // Add stations layer by layer\n    for (int iter = 0; iter < 5; iter++) {\n        // Find nearest not-in-tree station that we want\n        int best = -1;\n        long long best_cost = LLONG_MAX;\n        for (int i : selected_stations) {\n            if (!in_tree[i] && min_edge[i] < best_cost) {\n                best_cost = min_edge[i];\n                best = i;\n            }\n        }\n        if (best == -1) break;\n        \n        // Add the edge\n        int e_idx = parent[best];\n        edge_on[e_idx] = true;\n        in_tree[best] = true;\n        \n        // Update distances\n        for (int j = 0; j < M; j++) {\n            if (edges[j].u == best && !in_tree[edges[j].v]) {\n                if (edges[j].w < min_edge[edges[j].v]) {\n                    min_edge[edges[j].v] = edges[j].w;\n                    parent[edges[j].v] = j;\n                }\n            }\n            if (edges[j].v == best && !in_tree[edges[j].u]) {\n                if (edges[j].w < min_edge[edges[j].u]) {\n                    min_edge[edges[j].u] = edges[j].w;\n                    parent[edges[j].u] = j;\n                }\n            }\n        }\n    }\n    \n    // Add remaining edges to make graph connected (if needed)\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    for (int i = 0; i < N; i++) {\n        if (in_tree[i]) {\n            for (int j = 0; j < M; j++) {\n                if (edges[j].u == i && !in_tree[edges[j].v]) {\n                    pq.push({edges[j].w, j});\n                }\n                if (edges[j].v == i && !in_tree[edges[j].u]) {\n                    pq.push({edges[j].w, j});\n                }\n            }\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [cost, e_idx] = pq.top();\n        pq.pop();\n        int u = edges[e_idx].u, v = edges[e_idx].v;\n        if (in_tree[u] && in_tree[v]) continue;\n        int new_node = in_tree[u] ? v : u;\n        if (in_tree[new_node]) continue;\n        \n        edge_on[e_idx] = true;\n        in_tree[new_node] = true;\n        \n        for (int j = 0; j < M; j++) {\n            if (edges[j].u == new_node && !in_tree[edges[j].v]) {\n                pq.push({edges[j].w, j});\n            }\n            if (edges[j].v == new_node && !in_tree[edges[j].u]) {\n                pq.push({edges[j].w, j});\n            }\n        }\n    }\n    \n    // Now compute power levels for each station\n    // Only stations reachable from station 1 matter\n    // Compute reachable set\n    vector<bool> reachable(N, false);\n    queue<int> q;\n    q.push(0);\n    reachable[0] = true;\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for (int j = 0; j < M; j++) {\n            if (!edge_on[j]) continue;\n            int v = (edges[j].u == u) ? edges[j].v : (edges[j].v == u ? edges[j].u : -1);\n            if (v != -1 && !reachable[v]) {\n                reachable[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    // For each resident, find nearest reachable station and compute needed power\n    for (int k = 0; k < K; k++) {\n        long long best_d = LLONG_MAX;\n        int best_st = -1;\n        for (int i = 0; i < N; i++) {\n            if (!reachable[i]) continue;\n            long long d = squared_dist(vertices[i], residents[k]);\n            if (d < best_d) {\n                best_d = d;\n                best_st = i;\n            }\n        }\n        if (best_st != -1) {\n            long long needed = ceill(sqrt(best_d));\n            P[best_st] = max(P[best_st], (int)needed);\n        }\n    }\n    \n    // Clamp power to MAX_POWER\n    for (int i = 0; i < N; i++) {\n        P[i] = min(P[i], MAX_POWER);\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << P[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (edge_on[j] ? 1 : 0) << (j+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2; // 465\n\n// Direction vectors for 6-directional movement\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Check if coordinates are valid\nbool valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\n\n// Get target position for a number\npair<int,int> target_pos(int val) {\n    int n = 1;\n    while (n * (n + 1) / 2 <= val) n++;\n    n--;\n    int x = n;\n    int y = val - n * (n + 1) / 2;\n    return {x, y};\n}\n\nint main() {\n    vector<vector<int>> grid(N, vector<int>(N));\n    vector<pair<int,int>> pos(TOTAL);\n    \n    // Read input\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    \n    vector<tuple<int,int,int,int>> operations;\n    \n    // Process balls from smallest to largest\n    for (int val = 0; val < TOTAL; val++) {\n        auto [cx, cy] = pos[val];\n        auto [tx, ty] = target_pos(val);\n        \n        // BFS to find shortest path from current to target\n        vector<vector<int>> dist(N, vector<int>(N, -1));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1, -1}));\n        queue<pair<int,int>> q;\n        \n        dist[cx][cy] = 0;\n        q.push({cx, cy});\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            if (x == tx && y == ty) break;\n            \n            for (int d = 0; d < 6; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (valid(nx, ny) && dist[nx][ny] == -1) {\n                    dist[nx][ny] = dist[x][y] + 1;\n                    prev[nx][ny] = {x, y};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        // Reconstruct path and perform swaps\n        int cur_x = tx, cur_y = ty;\n        vector<pair<int,int>> path;\n        while (cur_x != cx || cur_y != cy) {\n            path.push_back({cur_x, cur_y});\n            auto [p_x, p_y] = prev[cur_x][cur_y];\n            cur_x = p_x; cur_y = p_y;\n        }\n        path.push_back({cx, cy});\n        reverse(path.begin(), path.end());\n        \n        // Execute swaps along the path\n        for (int i = 0; i + 1 < (int)path.size(); i++) {\n            auto [x1, y1] = path[i];\n            auto [x2, y2] = path[i+1];\n            \n            // Swap values\n            swap(grid[x1][y1], grid[x2][y2]);\n            pos[grid[x1][y1]] = {x1, y1};\n            pos[grid[x2][y2]] = {x2, y2};\n            \n            operations.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nvector<vector<int>> input, output;\n\n// Check if adjacency relationships are preserved for the current output\nbool checkAdjacencies() {\n    // For each pair of colors (0..M), check if their adjacency status matches input\n    for (int c = 0; c <= m; c++) {\n        for (int d = c + 1; d <= m; d++) {\n            bool adjInput = false, adjOutput = false;\n            \n            // Check input adjacency (excluding boundary for now)\n            for (int i = 0; i < n && !adjInput; i++) {\n                for (int j = 0; j < n && !adjInput; j++) {\n                    if (input[i][j] == c || input[i][j] == d) {\n                        // Check neighbors\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (input[i][j] == c && input[ni][nj] == d) adjInput = true;\n                                if (input[i][j] == d && input[ni][nj] == c) adjInput = true;\n                            } else if (input[i][j] == 0) {\n                                // Boundary tile of color 0\n                                adjInput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Check output adjacency\n            for (int i = 0; i < n && !adjOutput; i++) {\n                for (int j = 0; j < n && !adjOutput; j++) {\n                    if (output[i][j] == c) {\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (output[ni][nj] == d) adjOutput = true;\n                            } else {\n                                // Cell is on boundary - adjacent to color 0\n                                if (d == 0) adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Also check for c=0: cells on boundary are adjacent to color 0\n            if (c == 0) {\n                for (int i = 0; i < n && !adjOutput; i++) {\n                    for (int j = 0; j < n && !adjOutput; j++) {\n                        if (output[i][j] == d) {\n                            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                                adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (adjInput != adjOutput) return false;\n        }\n    }\n    return true;\n}\n\n// Check connectivity for all colors (including 0)\nbool checkConnectivity() {\n    // For each color, check if its cells are connected (4-directional)\n    for (int c = 0; c <= m; c++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == c) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 0;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            count++;\n            \n            int di[] = {0, 1, 0, -1};\n            int dj[] = {1, 0, -1, 0};\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) {\n                    if (!visited[ni][nj] && output[ni][nj] == c) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                } else if (c == 0) {\n                    // Color 0 can connect through outside\n                    // Already counted as connected if adjacent to boundary\n                }\n            }\n        }\n        \n        if (count != (int)cells.size()) return false;\n    }\n    return true;\n}\n\n// Check if a cell can be safely set to 0 (empty)\nbool canSetToZero(int i, int j, int originalColor) {\n    int saved = output[i][j];\n    output[i][j] = 0;\n    \n    // Check constraints\n    bool valid = checkAdjacencies() && checkConnectivity();\n    \n    output[i][j] = saved;\n    return valid;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    input.assign(n, vector<int>(n));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    // Start with a copy of input\n    output = input;\n    \n    // Multiple passes to remove unnecessary cells\n    for (int pass = 0; pass < 10; pass++) {\n        // Collect all cells that might be removable\n        vector<pair<int,int>> candidates;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] > 0) {\n                    // Check if this color appears elsewhere\n                    bool hasOtherCell = false;\n                    for (int ii = 0; ii < n && !hasOtherCell; ii++) {\n                        for (int jj = 0; jj < n && !hasOtherCell; jj++) {\n                            if ((ii != i || jj != j) && output[ii][jj] == output[i][j]) {\n                                hasOtherCell = true;\n                            }\n                        }\n                    }\n                    if (hasOtherCell) {\n                        candidates.push_back({i, j});\n                    }\n                }\n            }\n        }\n        \n        // Shuffle candidates for randomness\n        random_device rd;\n        mt19937 g(rd());\n        shuffle(candidates.begin(), candidates.end(), g);\n        \n        // Try to remove cells\n        for (auto [i, j] : candidates) {\n            int originalColor = output[i][j];\n            if (originalColor == 0) continue;\n            \n            if (canSetToZero(i, j, originalColor)) {\n                output[i][j] = 0;\n            }\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << output[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Utility for random\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint N, D, Q;\n\n// Structure to store comparison results\nstruct ComparisonResult {\n    int left_sum, right_sum;\n    char result;\n};\n\n// Compare two sets and return result\nchar compare_sets(const vector<int>& left, const vector<int>& right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    string res;\n    cin >> res;\n    return res[0];\n}\n\n// Compare single items indirectly\nchar compare_items(int a, int b) {\n    return compare_sets({a}, {b});\n}\n\n// Binary search to find position in sorted array\nint find_position(const vector<int>& sorted_items, int item, int l, int r) {\n    if (l >= r) return l;\n    int mid = (l + r) / 2;\n    \n    // Compare item with the middle element\n    char res = compare_items(item, sorted_items[mid]);\n    \n    if (res == '<') {\n        return find_position(sorted_items, item, l, mid);\n    } else if (res == '>') {\n        return find_position(sorted_items, item, mid + 1, r);\n    } else {\n        return mid;\n    }\n}\n\n// Compare sums of two groups\nchar compare_groups(const vector<vector<int>>& groups, int g1, int g2) {\n    vector<int> left = groups[g1];\n    vector<int> right = groups[g2];\n    \n    if (left.empty() || right.empty()) {\n        // Handle empty groups by adding a dummy comparison\n        if (left.empty() && right.empty()) return '=';\n        if (left.empty()) return '<';\n        return '>';\n    }\n    \n    return compare_sets(left, right);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Phase 1: Sort items by weight using comparisons\n    vector<int> order;\n    order.push_back(0);\n    \n    for (int i = 1; i < N && Q > 0; i++) {\n        // Binary search to find position\n        int pos = find_position(order, i, 0, order.size());\n        order.insert(order.begin() + pos, i);\n        Q--;\n        \n        // If few queries remain, stop sorting\n        if (Q <= N) break;\n    }\n    \n    // Phase 2: Create initial groups using greedy assignment\n    // Assign items to groups trying to balance weights\n    vector<vector<int>> groups(D);\n    vector<long long> group_weights(D, 0);\n    \n    // First pass: assign each item to the lightest group\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        \n        // Find group with minimum weight\n        int min_group = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] < group_weights[min_group]) {\n                min_group = j;\n            }\n        }\n        \n        groups[min_group].push_back(item);\n        group_weights[min_group]++; // approximate weight\n    }\n    \n    // Phase 3: Refine groups using remaining queries\n    // Try to balance groups by moving items\n    int remaining_queries = Q;\n    \n    for (int iter = 0; iter < min(remaining_queries / 2, 10 * D); iter++) {\n        // Find heaviest and lightest groups\n        int heaviest = 0, lightest = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] > group_weights[heaviest]) heaviest = j;\n            if (group_weights[j] < group_weights[lightest]) lightest = j;\n        }\n        \n        if (heaviest == lightest) break;\n        \n        // Try to move an item from heaviest to lightest\n        if (!groups[heaviest].empty()) {\n            // Pick a random item from heaviest group\n            int idx = rng() % groups[heaviest].size();\n            int item = groups[heaviest][idx];\n            \n            // Temporarily move item\n            groups[heaviest].erase(groups[heaviest].begin() + idx);\n            groups[lightest].push_back(item);\n            \n            // Compare the modified groups\n            char result = compare_groups(groups, heaviest, lightest);\n            remaining_queries--;\n            \n            if (result == '<' || result == '=') {\n                // Improvement: keep the move\n                group_weights[heaviest]--;\n                group_weights[lightest]++;\n            } else {\n                // Revert the move\n                groups[lightest].pop_back();\n                groups[heaviest].insert(groups[heaviest].begin() + idx, item);\n            }\n        }\n        \n        if (remaining_queries <= 0) break;\n    }\n    \n    // Use any remaining queries for final verification\n    while (remaining_queries > 0) {\n        // Dummy comparison to waste queries\n        compare_sets({0}, {1});\n        remaining_queries--;\n    }\n    \n    // Phase 4: Output final partition\n    vector<int> assignment(N);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int n = 200, m = 10;\n    const int h = n / m; // 20\n    \n    // Read input\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; j++) {\n            cin >> stacks[i][j];\n        }\n        reverse(stacks[i].begin(), stacks[i].end()); // top is at back\n    }\n    \n    vector<array<int, 2>> operations;\n    int next_to_remove = 1;\n    \n    // Helper to remove from top\n    auto try_remove = [&]() -> bool {\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_to_remove) {\n                stacks[i].pop_back();\n                operations.push_back({next_to_remove, 0});\n                next_to_remove++;\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    // Helper to find stack containing a given box\n    auto find_stack = [&](int v) -> 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] == v) return i;\n            }\n        }\n        return -1;\n    };\n    \n    // Remove easily accessible boxes first\n    while (true) {\n        bool removed = try_remove();\n        if (!removed) break;\n    }\n    \n    // Process remaining boxes\n    while (next_to_remove <= n) {\n        int target_stack = find_stack(next_to_remove);\n        if (target_stack == -1) {\n            break;\n        }\n        \n        auto& st = stacks[target_stack];\n        // Find position of target box (from top, which is back)\n        int pos = -1;\n        for (int i = 0; i < (int)st.size(); i++) {\n            if (st[i] == next_to_remove) {\n                pos = i;\n                break;\n            }\n        }\n        \n        if (pos == (int)st.size() - 1) {\n            // It's already on top\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n            continue;\n        }\n        \n        // Need to move boxes above it\n        // Find best destination: stack with smallest top, or empty stack\n        int best_dest = -1;\n        int best_top = n + 1;\n        for (int i = 0; i < m; i++) {\n            if (i == target_stack) continue;\n            if (stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n            if (stacks[i].back() < best_top) {\n                best_top = stacks[i].back();\n                best_dest = i;\n            }\n        }\n        \n        // Move boxes from position pos+1 to end to best_dest\n        int k = (int)st.size() - pos - 1;\n        // Move in one operation by moving the top box v = st[pos+1]\n        if (k > 0) {\n            int v = st[pos + 1];\n            operations.push_back({v, best_dest});\n            // Update stacks\n            vector<int> moved(st.begin() + pos + 1, st.end());\n            st.resize(pos + 1);\n            for (int x : moved) {\n                stacks[best_dest].push_back(x);\n            }\n        }\n        \n        // Now remove the target box\n        if (!st.empty() && st.back() == next_to_remove) {\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n        }\n        \n        // Try to remove any consecutive boxes that are now on top\n        while (true) {\n            bool removed = try_remove();\n            if (!removed) break;\n        }\n        \n        if (operations.size() > 5000) break;\n    }\n    \n    // Output\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_CELL = MAX_N * MAX_N;\nconst int INF = 1e9;\n\nint N;\nvector<string> h, v; // walls\nvector<vector<int>> d; // dirt rates\n\n// neighbor directions: 0: R, 1: D, 2: L, 3: U\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dirChar[4] = {'R', 'D', 'L', 'U'};\n\nint cellId(int i, int j) { return i * N + j; }\n\nvector<int> neighbors[MAX_CELL];\nint firstMove[MAX_CELL][MAX_CELL]; // direction to take from src to reach dst (0-3)\n\nvoid buildGraph() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = cellId(i, j);\n            // right\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = cellId(i, j+1);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            // down\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = cellId(i+1, j);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            // left and up are covered by symmetry\n        }\n    }\n}\n\nvoid precomputeFirstMove() {\n    int totalCells = N * N;\n    for (int src = 0; src < totalCells; src++) {\n        vector<int> dist(totalCells, INF);\n        vector<int> first(totalCells, -1);\n        queue<int> q;\n        dist[src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < (int)neighbors[u].size(); dir++) {\n                int v = neighbors[u][dir];\n                if (dist[v] == INF) {\n                    dist[v] = dist[u] + 1;\n                    // record the first move from src: for v, it's the direction from src to the neighbor on the path\n                    // we can store it later when we reconstruct\n                    first[v] = (u == src) ? dir : first[u];\n                    q.push(v);\n                }\n            }\n        }\n        // map first[neighbor] to actual direction from src\n        // but we stored dir relative to neighbor list of u. We need global direction.\n        // Better: during BFS, when we expand from src, we know the direction index (0-3) to each neighbor.\n        // So we store for each v the global direction index from src.\n        // Adjust: for each neighbor v of src, we know its direction.\n        // For others, first[v] = first[u] (the direction from src to u's predecessor).\n        // We'll compute differently: after BFS, run a second pass to fill global direction.\n        // We'll just use BFS each time to get direction? Simpler: precompute firstMove as path direction using BFS from src each time? Not efficient.\n        // Alternative: store for each src,dst the first move direction by doing a BFS and tracing back.\n        // We'll do: for each src, BFS, then for each dst, backtrack to src to get first move.\n        // Backtrack uses parent array. Let's reimplement.\n    }\n}\n\n// We'll implement BFS on the fly in the main loop? Too heavy. Let's precompute full direction table.\n\nvoid precomputeFirstMove2() {\n    int total = N * N;\n    for (int src = 0; src < total; src++) {\n        vector<int> dist(total, INF);\n        vector<int> parent(total, -1);\n        vector<int> moveFromParent(total, -1); // direction from parent to child\n        queue<int> q;\n        dist[src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int nb : neighbors[u]) {\n                if (dist[nb] == INF) {\n                    dist[nb] = dist[u] + 1;\n                    parent[nb] = u;\n                    // determine direction from u to nb\n                    int iu = u / N, ju = u % N;\n                    int inb = nb / N, jnb = nb % N;\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (iu + di[dir] == inb && ju + dj[dir] == jnb) {\n                            moveFromParent[nb] = dir;\n                            break;\n                        }\n                    }\n                    q.push(nb);\n                }\n            }\n        }\n        // for each dst, walk back to src to find first move\n        for (int dst = 0; dst < total; dst++) {\n            if (dst == src) { firstMove[src][dst] = -1; continue; }\n            int cur = dst;\n            while (parent[cur] != src) cur = parent[cur];\n            firstMove[src][dst] = moveFromParent[cur];\n        }\n    }\n}\n\nstring dfs_route;\n\nvoid dfs(int i, int j, vector<vector<bool>>& vis) {\n    vis[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !vis[ni][nj]) {\n            // check wall\n            if (dir == 0 && v[i][j] == '1') continue;\n            if (dir == 1 && h[i][j] == '1') continue;\n            if (dir == 2 && v[i][j-1] == '1') continue;\n            if (dir == 3 && h[i-1][j] == '1') continue;\n            dfs_route.push_back(dirChar[dir]);\n            dfs(ni, nj, vis);\n            dfs_route.push_back(dirChar[(dir+2)%4]);\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    v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n\n    buildGraph();\n    precomputeFirstMove2();\n\n    // 1. DFS covering all cells\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    dfs_route.clear();\n    dfs(0, 0, vis);\n    string route = dfs_route;\n\n    // simulate DFS to get dirt array and last visit times\n    vector<vector<int>> dirt(N, vector<int>(N, 0));\n    vector<vector<int>> lastVisit(N, vector<int>(N, -1));\n    int ci = 0, cj = 0;\n    lastVisit[0][0] = 0;\n    // initial dirt update not needed because all zero at t=0.\n    // For each move in dfs_route:\n    for (char ch : route) {\n        // add d to all cells\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n        // move\n        int dir = -1;\n        if (ch == 'R') dir = 0;\n        else if (ch == 'D') dir = 1;\n        else if (ch == 'L') dir = 2;\n        else if (ch == 'U') dir = 3;\n        ci += di[dir]; cj += dj[dir];\n        dirt[ci][cj] = 0;\n        lastVisit[ci][cj] = (int)route.size(); // approximate, but we'll track step count later\n    }\n\n    // After DFS, we have visited all cells.\n    // Now greedy extra moves\n    int dfsLen = (int)route.size();\n    int maxMoves = 100000;\n    int remaining = maxMoves - dfsLen;\n    if (remaining < 0) { /* too long, but unlikely */ }\n\n    // we will add extra moves\n    string extra;\n    int curId = cellId(ci, cj);\n    // we need to track step count for dirt accumulation\n    int step = dfsLen; // next step index (0-indexed after DFS)\n    vector<vector<int>> curDirt = dirt; // copy\n    // we also need lastVisit for dirt calculation? we maintain curDirt directly.\n    auto findMaxDirtCell = [&]() -> pair<int,int> {\n        int maxVal = -1;\n        int mi = -1, mj = -1;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (curDirt[i][j] > maxVal) {\n                    maxVal = curDirt[i][j];\n                    mi = i; mj = j;\n                }\n            }\n        }\n        return {mi, mj};\n    };\n\n    // Precompute distance to origin for deadline\n    vector<vector<int>> distToOrigin(N, vector<int>(N, INF));\n    {\n        queue<pair<int,int>> q;\n        distToOrigin[0][0] = 0;\n        q.push({0,0});\n        while (!q.empty()) {\n            auto [i,j] = q.front(); q.pop();\n            int u = cellId(i,j);\n            for (int nb : neighbors[u]) {\n                int ni = nb/N, nj = nb%N;\n                if (distToOrigin[ni][nj] > distToOrigin[i][j] + 1) {\n                    distToOrigin[ni][nj] = distToOrigin[i][j] + 1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n    }\n\n    int stepsLeft = remaining - 1; // reserve last step to return\n    for (int t = 0; t < stepsLeft; t++) {\n        // find cell with max dirt\n        auto [ti, tj] = findMaxDirtCell();\n        int targetId = cellId(ti, tj);\n        int dir = firstMove[curId][targetId];\n        int ni = ci + di[dir];\n        int nj = cj + dj[dir];\n        // check deadline: after move, distance to origin must be <= (remaining - t - 1 - 1) because we need one more step after loop\n        int remAfterMove = stepsLeft - t - 1; // steps left after this move (excluding final return)\n        if (distToOrigin[ni][nj] > remAfterMove) {\n            // choose alternative: move toward origin? Instead, find any reachable cell that satisfies deadline and high dirt.\n            // Simple fallback: move to neighbor with smallest distance to origin that satisfies deadline.\n            int bestDir = -1;\n            int bestDist = INF;\n            for (int dir2 = 0; dir2 < 4; dir2++) {\n                int ni2 = ci + di[dir2];\n                int nj2 = cj + dj[dir2];\n                if (ni2 < 0 || ni2 >= N || nj2 < 0 || nj2 >= N) continue;\n                // check wall\n                if (dir2 == 0 && v[ci][cj] == '1') continue;\n                if (dir2 == 1 && h[ci][cj] == '1') continue;\n                if (dir2 == 2 && v[ci][cj-1] == '1') continue;\n                if (dir2 == 3 && h[ci-1][cj] == '1') continue;\n                if (distToOrigin[ni2][nj2] <= remAfterMove) {\n                    if (distToOrigin[ni2][nj2] < bestDist) {\n                        bestDist = distToOrigin[ni2][nj2];\n                        bestDir = dir2;\n                    }\n                }\n            }\n            if (bestDir == -1) break; // no feasible move? shouldn't happen\n            dir = bestDir;\n            ni = ci + di[dir];\n            nj = cj + dj[dir];\n        }\n        extra.push_back(dirChar[dir]);\n        // update dirt\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) curDirt[i][j] += d[i][j];\n        ci = ni; cj = nj;\n        curDirt[ci][cj] = 0;\n        curId = cellId(ci, cj);\n    }\n\n    // finally return to (0,0)\n    // BFS from current to origin\n    int target = 0;\n    while (curId != target) {\n        int dir = firstMove[curId][target];\n        extra.push_back(dirChar[dir]);\n        int ni = ci + di[dir];\n        int nj = cj + dj[dir];\n        ci = ni; cj = nj;\n        curId = cellId(ci, cj);\n        // (no need to update dirt for return moves as output length may exceed, but we have to ensure length <=100000)\n    }\n\n    string finalRoute = route + extra;\n    if ((int)finalRoute.size() > 100000) finalRoute.resize(100000);\n\n    cout << finalRoute << endl;\n\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Constants\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\n// Grid information\nvector<string> grid(N);\nint si, sj;\n\n// Word information\nvector<string> words(M);\nvector<vector<pair<int,int>>> char_positions[26];\n\n// For each word, store the best position to start/end\nstruct WordInfo {\n    string word;\n    vector<int> best_path_i, best_path_j;\n    int best_cost;\n};\n\nvector<WordInfo> word_info(M);\n\n// Precompute positions of each character on the grid\nvoid precompute_positions() {\n    for (int c = 0; c < 26; c++) {\n        char_positions[c].clear();\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n}\n\n// Compute optimal path for a single word starting from (si, sj)\npair<vector<int>, vector<int>> optimize_word_path(const string& word, int start_i, int start_j) {\n    int len = word.size();\n    vector<vector<vector<int>>> dp(len, vector<vector<int>>(N, vector<int>(N, 1e9)));\n    vector<vector<vector<pair<int,int>>>> prev(len, vector<vector<pair<int,int>>>(N, vector<pair<int,int>>(N, {-1, -1})));\n    \n    // Initialize first character\n    for (auto [i, j] : char_positions[word[0] - 'A']) {\n        dp[0][i][j] = abs(i - start_i) + abs(j - start_j) + 1;\n        prev[0][i][j] = {start_i, start_j};\n    }\n    \n    // DP for remaining characters\n    for (int pos = 1; pos < len; pos++) {\n        for (auto [i, j] : char_positions[word[pos] - 'A']) {\n            for (auto [pi, pj] : char_positions[word[pos-1] - 'A']) {\n                int cost = dp[pos-1][pi][pj] + abs(i - pi) + abs(j - pj) + 1;\n                if (cost < dp[pos][i][j]) {\n                    dp[pos][i][j] = cost;\n                    prev[pos][i][j] = {pi, pj};\n                }\n            }\n        }\n    }\n    \n    // Find best ending position\n    int best_i = 0, best_j = 0, best_cost = 1e9;\n    for (auto [i, j] : char_positions[word[len-1] - 'A']) {\n        if (dp[len-1][i][j] < best_cost) {\n            best_cost = dp[len-1][i][j];\n            best_i = i;\n            best_j = j;\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path_i(len), path_j(len);\n    int ci = best_i, cj = best_j;\n    for (int pos = len-1; pos >= 0; pos--) {\n        path_i[pos] = ci;\n        path_j[pos] = cj;\n        if (pos > 0) {\n            auto [pi, pj] = prev[pos][ci][cj];\n            ci = pi;\n            cj = pj;\n        }\n    }\n    \n    return {path_i, path_j};\n}\n\n// Compute transition cost between two words\nint transition_cost(const pair<int,int>& end1, const pair<int,int>& start2) {\n    return abs(end1.first - start2.first) + abs(end1.second - start2.second) + 1;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M;\n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    precompute_positions();\n    \n    // Precompute optimal paths for each word\n    for (int i = 0; i < M; i++) {\n        auto [path_i, path_j] = optimize_word_path(words[i], si, sj);\n        int cost = 0, ci = si, cj = sj;\n        for (int p = 0; p < 5; p++) {\n            cost += abs(path_i[p] - ci) + abs(path_j[p] - cj) + 1;\n            ci = path_i[p];\n            cj = path_j[p];\n        }\n        word_info[i] = {words[i], path_i, path_j, cost};\n    }\n    \n    // Greedy construction of superstring with path optimization\n    vector<bool> used(M, false);\n    vector<int> order;\n    int cur_i = si, cur_j = sj;\n    int total_cost = 0;\n    int ops = 0;\n    \n    // Start with the cheapest first word\n    int best_first = 0, best_first_cost = 1e9;\n    for (int i = 0; i < M; i++) {\n        int cost = transition_cost({si, sj}, {word_info[i].best_path_i[0], word_info[i].best_path_j[0]});\n        if (cost < best_first_cost) {\n            best_first_cost = cost;\n            best_first = i;\n        }\n    }\n    \n    order.push_back(best_first);\n    used[best_first] = true;\n    cur_i = word_info[best_first].best_path_i[4];\n    cur_j = word_info[best_first].best_path_j[4];\n    \n    // Greedy selection of remaining words\n    while ((int)order.size() < M) {\n        int best_next = -1, best_next_cost = 1e9;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            \n            // Check if we can overlap with the last word\n            string& last_word = words[order.back()];\n            string& next_word = words[i];\n            \n            int overlap = 0;\n            for (int o = 1; o <= 4; o++) {\n                if (last_word.substr(5-o) == next_word.substr(0, o)) {\n                    overlap = o;\n                }\n            }\n            \n            int cost;\n            if (overlap > 0) {\n                // Only need to type the non-overlapping part\n                cost = 0;\n                int ci = cur_i, cj = cur_j;\n                for (int p = overlap; p < 5; p++) {\n                    cost += abs(word_info[i].best_path_i[p] - ci) + abs(word_info[i].best_path_j[p] - cj) + 1;\n                    ci = word_info[i].best_path_i[p];\n                    cj = word_info[i].best_path_j[p];\n                }\n            } else {\n                // Full cost\n                cost = transition_cost({cur_i, cur_j}, {word_info[i].best_path_i[0], word_info[i].best_path_j[0]});\n                for (int p = 0; p < 5; p++) {\n                    if (p > 0) {\n                        cost += abs(word_info[i].best_path_i[p] - word_info[i].best_path_i[p-1]) + \n                               abs(word_info[i].best_path_j[p] - word_info[i].best_path_j[p-1]) + 1;\n                    } else {\n                        cost += 1; // Already counted transition cost\n                    }\n                }\n            }\n            \n            if (cost < best_next_cost) {\n                best_next_cost = cost;\n                best_next = i;\n            }\n        }\n        \n        order.push_back(best_next);\n        used[best_next] = true;\n        cur_i = word_info[best_next].best_path_i[4];\n        cur_j = word_info[best_next].best_path_j[4];\n    }\n    \n    // Output the sequence of operations\n    cur_i = si, cur_j = sj;\n    for (int idx : order) {\n        // Move to first character of this word\n        vector<int>& path_i = word_info[idx].best_path_i;\n        vector<int>& path_j = word_info[idx].best_path_j;\n        \n        if (!(path_i[0] == cur_i && path_j[0] == cur_j)) {\n            cout << path_i[0] << \" \" << path_j[0] << \"\\n\";\n            cur_i = path_i[0];\n            cur_j = path_j[0];\n            ops++;\n        }\n        \n        // Type the word\n        for (int p = 0; p < 5; p++) {\n            if (p > 0 || !(path_i[p] == cur_i && path_j[p] == cur_j)) {\n                cout << path_i[p] << \" \" << path_j[p] << \"\\n\";\n                cur_i = path_i[p];\n                cur_j = path_j[p];\n                ops++;\n            }\n        }\n    }\n    \n    cerr << \"Total operations: \" << ops << endl;\n    cerr << \"Total cost: \" << total_cost << endl;\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct OilField {\n    int id;\n    int size;\n    vector<pair<int,int>> cells; // relative positions\n    int max_i, max_j; // maximum coordinates\n};\n\nint N, M;\ndouble eps;\nvector<OilField> fields;\nset<pair<int,int>> known_oil, known_dry;\n\n// Safely read double response\ndouble read_double() {\n    string line;\n    while (line.empty()) {\n        if (!getline(cin, line)) break;\n    }\n    return stod(line);\n}\n\n// Query single cell\nint query_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl << flush;\n    return (int)read_double();\n}\n\n// Query set of cells\ndouble query_set(const vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto [i,j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n    return read_double();\n}\n\n// Make guess\nbool make_guess(const vector<pair<int,int>>& guess) {\n    cout << \"a \" << guess.size();\n    for (auto [i,j] : guess) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n    int result = (int)read_double();\n    return result == 1;\n}\n\nint main() {\n    // Read parameters\n    string first_line;\n    getline(cin, first_line);\n    stringstream ss(first_line);\n    ss >> N >> M >> eps;\n    \n    // Read oil field shapes\n    fields.resize(M);\n    for (int k = 0; k < M; k++) {\n        string line;\n        getline(cin, line);\n        stringstream ssf(line);\n        \n        int d;\n        ssf >> d;\n        \n        fields[k].id = k;\n        fields[k].size = d;\n        fields[k].cells.resize(d);\n        fields[k].max_i = 0;\n        fields[k].max_j = 0;\n        \n        for (int t = 0; t < d; t++) {\n            ssf >> fields[k].cells[t].first >> fields[k].cells[t].second;\n            fields[k].max_i = max(fields[k].max_i, fields[k].cells[t].first);\n            fields[k].max_j = max(fields[k].max_j, fields[k].cells[t].second);\n        }\n    }\n    \n    // Strategy: Use grid-based probing with small random sets\n    // First, do some initial divinations to get a rough idea\n    \n    // Phase 1: Row queries (cost effective)\n    vector<double> row_sums(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) {\n            row.push_back({i,j});\n        }\n        row_sums[i] = query_set(row);\n    }\n    \n    // Phase 2: Column queries\n    vector<double> col_sums(N, 0.0);\n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) {\n            col.push_back({i,j});\n        }\n        col_sums[j] = query_set(col);\n    }\n    \n    // Estimate oil probabilities using tomographic reconstruction\n    vector<vector<double>> prob(N, vector<double>(N, 0.0));\n    double total_estimate = 0;\n    for (int i = 0; i < N; i++) total_estimate += row_sums[i];\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            // Simple reconstruction: average of row and column estimates\n            double row_contrib = row_sums[i] / N;\n            double col_contrib = col_sums[j] / N;\n            prob[i][j] = (row_contrib + col_contrib) / 2.0;\n            prob[i][j] = max(0.0, min(1.0, prob[i][j]));\n        }\n    }\n    \n    // Phase 3: Drill cells with highest probability\n    int ops_used = 2 * N; // for initial queries\n    int max_ops = 2 * N * N - M; // leave room for final guess and some extra queries\n    \n    // Collect cells sorted by probability\n    vector<tuple<double,int,int>> priority;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            priority.push_back({prob[i][j], i, j});\n        }\n    }\n    sort(priority.rbegin(), priority.rend());\n    \n    // Drill cells, but also try to verify with small divination sets\n    for (auto [p, i, j] : priority) {\n        if (ops_used >= max_ops) break;\n        if (known_oil.count({i,j}) || known_dry.count({i,j})) continue;\n        \n        // If probability is very low, skip (likely no oil)\n        if (p < 0.1 && known_oil.size() > 0) break;\n        \n        int val = query_cell(i, j);\n        ops_used++;\n        \n        if (val > 0) {\n            known_oil.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n        }\n    }\n    \n    // Phase 4: Use known oil field shapes to predict remaining cells\n    set<pair<int,int>> final_guess = known_oil;\n    \n    // For each oil field, try to find a position that covers all known oil cells\n    for (int k = 0; k < M && ops_used < max_ops; k++) {\n        bool found = false;\n        int best_i = 0, best_j = 0;\n        int max_covered = 0;\n        \n        // Try all positions\n        for (int pi = 0; pi + fields[k].max_i < N; pi++) {\n            for (int pj = 0; pj + fields[k].max_j < N; pj++) {\n                int covered = 0;\n                bool valid = true;\n                \n                // Check if position overlaps with known dry cells\n                for (auto [di,dj] : fields[k].cells) {\n                    int ni = pi + di, nj = pj + dj;\n                    if (known_dry.count({ni,nj})) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (!valid) continue;\n                \n                // Count how many known oil cells are covered\n                for (auto [oi,oj] : known_oil) {\n                    for (auto [di,dj] : fields[k].cells) {\n                        if (pi + di == oi && pj + dj == oj) {\n                            covered++;\n                            break;\n                        }\n                    }\n                }\n                \n                if (covered > max_covered) {\n                    max_covered = covered;\n                    best_i = pi;\n                    best_j = pj;\n                    found = true;\n                }\n            }\n        }\n        \n        // If we found a good position, add its cells\n        if (found && max_covered > 0) {\n            for (auto [di,dj] : fields[k].cells) {\n                int ni = best_i + di, nj = best_j + dj;\n                if (known_dry.count({ni,nj}) == 0) {\n                    final_guess.insert({ni,nj});\n                }\n            }\n        }\n    }\n    \n    // Phase 5: Verify suspicious cells with divination if we have operations left\n    // Look for cells that are likely oil but not yet confirmed\n    vector<pair<int,int>> suspect_cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (final_guess.count({i,j}) || known_dry.count({i,j})) continue;\n            // Check if this cell is near known oil (could be part of a shape)\n            bool near_oil = false;\n            for (int di = -1; di <= 1 && !near_oil; di++) {\n                for (int dj = -1; dj <= 1 && !near_oil; dj++) {\n                    if (known_oil.count({i+di, j+dj})) {\n                        near_oil = true;\n                    }\n                }\n            }\n            if (near_oil && prob[i][j] > 0.3) {\n                suspect_cells.push_back({i,j});\n            }\n        }\n    }\n    \n    // Drill suspect cells if we have enough operations\n    for (auto [i,j] : suspect_cells) {\n        if (ops_used >= max_ops) break;\n        int val = query_cell(i, j);\n        ops_used++;\n        if (val > 0) {\n            known_oil.insert({i,j});\n            final_guess.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n            final_guess.erase({i,j});\n        }\n    }\n    \n    // Generate final guess\n    vector<pair<int,int>> guess_list(final_guess.begin(), final_guess.end());\n    make_guess(guess_list);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Store rectangles: for each day [d], store N rectangles as (i0, j0, i1, j1)\n    vector<vector<array<int,4>>> rect(D, vector<array<int,4>>(N));\n    \n    // Day 0: simple strips\n    {\n        int cur_y = 0;\n        for (int k = 0; k < N; k++) {\n            int need_h = (a[0][k] + W - 1) / W;  // ceil division\n            // If last reservation, take remaining space\n            if (k == N - 1) {\n                need_h = W - cur_y;\n            }\n            // Ensure we don't exceed W\n            if (cur_y + need_h > W) {\n                need_h = W - cur_y;\n            }\n            rect[0][k] = {cur_y, 0, cur_y + need_h, W};\n            cur_y += need_h;\n        }\n    }\n    \n    // Store previous boundaries\n    vector<int> prev_bounds(N + 1);\n    {\n        int cur = 0;\n        prev_bounds[0] = 0;\n        for (int k = 0; k < N; k++) {\n            cur += rect[0][k][2] - rect[0][k][0];  // height\n            prev_bounds[k + 1] = cur;\n        }\n    }\n    \n    // For each subsequent day\n    for (int d = 1; d < D; d++) {\n        // First compute minimal heights needed for each reservation\n        vector<int> need_h(N);\n        int total_need = 0;\n        for (int k = 0; k < N; k++) {\n            need_h[k] = (a[d][k] + W - 1) / W;  // ceil division\n            total_need += need_h[k];\n        }\n        \n        // DP: dp[current_boundary] = min cost\n        const int INF = 1e9;\n        vector<int> dp(W + 1, INF);\n        dp[0] = 0;\n        \n        for (int k = 0; k < N; k++) {\n            vector<int> ndp(W + 1, INF);\n            int prev_start = prev_bounds[k];\n            int prev_end = prev_bounds[k + 1];\n            \n            for (int cur_start = 0; cur_start <= W; cur_start++) {\n                if (dp[cur_start] >= INF) continue;\n                \n                // Try all possible heights for this reservation\n                for (int h = need_h[k]; h <= W - cur_start; h++) {\n                    int cur_end = cur_start + h;\n                    \n                    // Cost to change boundaries\n                    int change_cost = abs(cur_start - prev_start) + abs(cur_end - prev_end);\n                    \n                    // Area penalty\n                    int area = h * W;\n                    int penalty = 0;\n                    if (area < a[d][k]) {\n                        penalty = 100 * (a[d][k] - area);\n                    }\n                    \n                    int new_cost = dp[cur_start] + change_cost + penalty;\n                    if (new_cost < ndp[cur_end]) {\n                        ndp[cur_end] = new_cost;\n                    }\n                }\n            }\n            dp = move(ndp);\n        }\n        \n        // Find best final boundary\n        int best_cost = INF;\n        int best_final = W;  // must end at W\n        for (int h = W; h <= W; h++) {\n            if (dp[h] < best_cost) {\n                best_cost = dp[h];\n                best_final = h;\n            }\n        }\n        \n        // Backtrack to get boundaries\n        vector<int> new_bounds(N + 1);\n        new_bounds[N] = W;\n        \n        // Greedy approximation: just use need_h with possible trimming\n        {\n            int cur_y = 0;\n            for (int k = 0; k < N; k++) {\n                int h = need_h[k];\n                if (k == N - 1) {\n                    h = W - cur_y;\n                }\n                if (cur_y + h > W) {\n                    h = W - cur_y;\n                }\n                rect[d][k] = {cur_y, 0, cur_y + h, W};\n                new_bounds[k] = cur_y;\n                cur_y += h;\n            }\n            new_bounds[N] = W;\n        }\n        \n        // Update previous boundaries\n        prev_bounds = move(new_bounds);\n    }\n    \n    // Output rectangles\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto [i0, j0, i1, j1] = rect[d][k];\n            cout << i0 << \" \" << j0 << \" \" << i1 << \" \" << j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int STAMP_SIZE = 3;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_actual, M, K;\n    cin >> N_actual >> M >> K;\n    \n    // Initialize board\n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    // Read stamps\n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(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 >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    // Precompute stamp effectiveness for each cell\n    // For each cell (i,j), find which stamps/positions affect it\n    // A stamp at position (p,q) affects cells (p..p+2, q..q+2)\n    vector<vector<vector<pair<int,int>>>> covering_stamps(N, vector<vector<pair<int,int>>>(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                for (int i = 0; i < 3; i++) {\n                    for (int j = 0; j < 3; j++) {\n                        covering_stamps[p+i][q+j].push_back({m, stamps[m][i][j] % MOD});\n                    }\n                }\n            }\n        }\n    }\n    \n    vector<tuple<int,int,int>> operations; // (m, p, q)\n    \n    // Track remaining budget for each cell's potential\n    // We'll use a priority queue approach based on need\n    auto get_cell_value = [&](int i, int j) {\n        return board[i][j] % MOD;\n    };\n    \n    auto get_cell_potential = [&](int i, int j) {\n        long long cur = get_cell_value(i, j);\n        return (MOD - 1 - cur + MOD) % MOD; // How much more we need\n    };\n    \n    // For each operation, we'll do beam search over a few best options\n    for (int op = 0; op < K; op++) {\n        // Find most needy cell\n        double max_need = -1;\n        int target_i = -1, target_j = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                double need = get_cell_potential(i, j);\n                if (need > max_need) {\n                    max_need = need;\n                    target_i = i;\n                    target_j = j;\n                }\n            }\n        }\n        \n        // Now find best stamp/position that helps this cell and nearby cells\n        double best_score = -1e9;\n        int best_m = -1, best_p = -1, best_q = -1;\n        \n        // Search all stamps and positions that can affect target cell\n        for (int m = 0; m < M; m++) {\n            for (int p = max(0, target_i - 2); p <= min(N - 3, target_i); p++) {\n                for (int q = max(0, target_j - 2); q <= min(N - 3, target_j); q++) {\n                    // Check if this placement actually affects the target cell\n                    if (p > target_i || p + 2 < target_i || q > target_j || q + 2 < target_j) continue;\n                    \n                    double score = 0;\n                    \n                    // Evaluate all 9 cells affected\n                    for (int di = 0; di < 3; di++) {\n                        for (int dj = 0; dj < 3; dj++) {\n                            int ci = p + di, cj = q + dj;\n                            long long cur_val = board[ci][cj];\n                            long long cur_rem = cur_val % MOD;\n                            long long add_val = stamps[m][di][dj] % MOD;\n                            long long new_rem = (cur_rem + add_val) % MOD;\n                            \n                            // Score: improvement in remainder, weighted by how bad the cell is\n                            long long current_potential = (MOD - 1 - cur_rem + MOD) % MOD;\n                            long long new_potential = (MOD - 1 - new_rem + MOD) % MOD;\n                            long long improvement = current_potential - new_potential;\n                            \n                            // Weight: cells with high potential (far from MOD-1) get more weight\n                            double weight = 1.0 + (double)current_potential / MOD * 2.0;\n                            \n                            // Extra bonus for the target cell\n                            if (ci == target_i && cj == target_j) {\n                                weight *= 3.0;\n                            }\n                            \n                            score += improvement * weight;\n                        }\n                    }\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation\n        if (best_m != -1) {\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n            operations.push_back({best_m, best_p, best_q});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Precompute target positions for each container\n    vector<int> targetRow(N*N), targetCol(N*N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int container = i*N + j;\n            targetRow[container] = i;\n            targetCol[container] = 4;\n        }\n    }\n    \n    // State tracking\n    vector<int> craneRow(N, 0), craneCol(N, 0);\n    for (int i = 0; i < N; i++) {\n        craneRow[i] = i;\n        craneCol[i] = 0;\n    }\n    \n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<int> holding(N, -1);\n    vector<int> nextReceiving(N, 0);\n    vector<int> nextDispatch(N, 0);\n    vector<bool> dispatched(N*N, false);\n    \n    // Check if move is valid\n    auto canMove = [&](int crane, int nr, int nc) -> bool {\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n        \n        // Check if destination has container and crane is small and carries container\n        if (grid[nr][nc] != -1 && holding[crane] != -1 && crane > 0) return false;\n        \n        // Check for other cranes at destination\n        for (int i = 0; i < N; i++) {\n            if (i == crane) continue;\n            if (craneRow[i] == nr && craneCol[i] == nc) return false;\n        }\n        \n        // Check for position swap\n        for (int i = 0; i < N; i++) {\n            if (i == crane) continue;\n            if (craneRow[i] == craneRow[crane] && craneCol[i] == craneCol[crane] + (nc - craneCol[crane]) * -1) return false;\n        }\n        \n        return true;\n    };\n    \n    vector<string> ops(N);\n    \n    // Simulation\n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        // Step 1: Deliver new containers to receiving gates\n        for (int i = 0; i < N; i++) {\n            if (nextReceiving[i] < N && grid[i][0] == -1) {\n                bool craneHere = false;\n                for (int j = 0; j < N; j++) {\n                    if (craneRow[j] == i && craneCol[j] == 0 && holding[j] == -1) {\n                        craneHere = true;\n                        break;\n                    }\n                }\n                if (!craneHere) {\n                    grid[i][0] = A[i][nextReceiving[i]];\n                    nextReceiving[i]++;\n                }\n            }\n        }\n        \n        // Step 3: Dispatch containers at gates (done before actions in this implementation)\n        for (int i = 0; i < N; i++) {\n            if (grid[i][4] != -1) {\n                int container = grid[i][4];\n                if (container / N == i && container % N == nextDispatch[i]) {\n                    dispatched[container] = true;\n                    grid[i][4] = -1;\n                    nextDispatch[i]++;\n                }\n            }\n        }\n        \n        // Determine actions for each crane\n        vector<char> actions(N, '.');\n        \n        for (int crane = 0; crane < N; crane++) {\n            int r = craneRow[crane], c = craneCol[crane];\n            char action = '.';\n            \n            if (crane == 0) {\n                // Large crane: move containers to correct rows\n                if (holding[crane] == -1) {\n                    // Find a container to move\n                    bool found = false;\n                    for (int dr = -1; dr <= 1 && !found; dr += 2) {\n                        for (int dc = -1; dc <= 1 && !found; dc += 2) {\n                            int nr = r, nc = c;\n                            // Try to move towards receiving gates\n                            if (canMove(crane, r, c-1) && c > 0) {\n                                action = 'L';\n                                found = true;\n                            } else if (canMove(crane, r, c+1) && c < 4) {\n                                action = 'R';\n                                found = true;\n                            } else if (canMove(crane, r-1, c) && r > 0) {\n                                action = 'U';\n                                found = true;\n                            } else if (canMove(crane, r+1, c) && r < 4) {\n                                action = 'D';\n                                found = true;\n                            }\n                        }\n                    }\n                    \n                    // If at a container and not holding anything\n                    if (grid[r][c] != -1 && !found) {\n                        action = 'P';\n                    }\n                } else {\n                    // Move towards target row\n                    int container = holding[crane];\n                    int targetR = container / N;\n                    \n                    if (r == targetR && c == 4) {\n                        // At dispatch gate, check if we should drop\n                        if (grid[r][4] == -1 && container % N == nextDispatch[targetR]) {\n                            action = 'Q';\n                        } else {\n                            // Move away temporarily\n                            if (canMove(crane, r, c-1)) action = 'L';\n                        }\n                    } else {\n                        // Move towards target\n                        if (c < 4 && canMove(crane, r, c+1)) action = 'R';\n                        else if (c > 0 && canMove(crane, r, c-1)) action = 'L';\n                        else if (r < targetR && canMove(crane, r+1, c)) action = 'D';\n                        else if (r > targetR && canMove(crane, r-1, c)) action = 'U';\n                    }\n                }\n            } else {\n                // Small crane: sort containers in its row\n                if (holding[crane] == -1) {\n                    // Look for a container to pick up\n                    bool found = false;\n                    \n                    // Check adjacent cells first\n                    for (int dc = -1; dc <= 1 && !found; dc += 2) {\n                        int nc = c + dc;\n                        if (nc >= 0 && nc < N && grid[r][nc] != -1) {\n                            // Move towards it\n                            if (nc == c) {\n                                int container = grid[r][c];\n                                // Only pick up if it belongs to our row or is out of place\n                                if (container / N != r || container % N != nextDispatch[r]) {\n                                    action = 'P';\n                                    found = true;\n                                }\n                            } else if (canMove(crane, r, nc)) {\n                                if (dc == -1) action = 'L';\n                                else action = 'R';\n                                found = true;\n                            }\n                        }\n                    }\n                    \n                    // Move towards receiving gate area\n                    if (!found) {\n                        if (c > 0 && canMove(crane, r, c-1)) action = 'L';\n                        else if (c < 3 && canMove(crane, r, c+1)) action = 'R';\n                    }\n                } else {\n                    // Holding container, try to dispatch\n                    int container = holding[crane];\n                    int targetR = container / N;\n                    \n                    if (targetR == r) {\n                        // Belongs to our row\n                        if (c < 4 && canMove(crane, r, c+1)) {\n                            action = 'R';\n                        } else if (c == 4 && grid[r][4] == -1) {\n                            if (container % N == nextDispatch[r]) {\n                                action = 'Q';\n                            } else {\n                                // Need to wait, move away\n                                if (canMove(crane, r, c-1)) action = 'L';\n                            }\n                        }\n                    } else {\n                        // Belongs to another row, move towards it\n                        if (r < targetR && canMove(crane, r+1, c)) action = 'D';\n                        else if (r > targetR && canMove(crane, r-1, c)) action = 'U';\n                        else if (c > 0 && canMove(crane, r, c-1)) action = 'L';\n                        else if (c < 4 && canMove(crane, r, c+1)) action = 'R';\n                    }\n                }\n            }\n            \n            actions[crane] = action;\n        }\n        \n        // Execute actions\n        for (int crane = 0; crane < N; crane++) {\n            char action = actions[crane];\n            int r = craneRow[crane], c = craneCol[crane];\n            \n            if (action == 'P') {\n                if (grid[r][c] != -1 && holding[crane] == -1) {\n                    holding[crane] = grid[r][c];\n                    grid[r][c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (grid[r][c] == -1 && holding[crane] != -1) {\n                    grid[r][c] = holding[crane];\n                    holding[crane] = -1;\n                }\n            } else if (action == 'U' && canMove(crane, r-1, c)) {\n                craneRow[crane] = r-1;\n            } else if (action == 'D' && canMove(crane, r+1, c)) {\n                craneRow[crane] = r+1;\n            } else if (action == 'L' && canMove(crane, r, c-1)) {\n                craneCol[crane] = c-1;\n            } else if (action == 'R' && canMove(crane, r, c+1)) {\n                craneCol[crane] = c+1;\n            }\n            \n            ops[crane] += action;\n        }\n        \n        // Check if all containers dispatched\n        bool allDone = true;\n        for (int i = 0; i < N*N; i++) {\n            if (!dispatched[i]) {\n                allDone = false;\n                break;\n            }\n        }\n        if (allDone) break;\n    }\n    \n    // Normalize lengths\n    int maxLen = 0;\n    for (int i = 0; i < N; i++) {\n        maxLen = max(maxLen, (int)ops[i].length());\n    }\n    for (int i = 0; i < N; i++) {\n        while ((int)ops[i].length() < maxLen) {\n            ops[i] += '.';\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << ops[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\nconst int MAX_TURNS = 100000;\nconst int DX[] = {-1, 1, 0, 0};\nconst int DY[] = {0, 0, -1, 1};\nconst string DIR = \"UDLR\";\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int x = 0, y = 0;\n    int load = 0;\n    \n    // BFS for shortest path\n    auto get_path = [&](int sx, int sy, int tx, int ty) -> vector<pair<int,int>> {\n        if (sx == tx && sy == ty) return {};\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n        \n        dist[sx][sy] = 0;\n        q.push({sx, sy});\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            if (cx == tx && cy == ty) break;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cx + DX[d], ny = cy + DY[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] > dist[cx][cy] + 1) {\n                    dist[nx][ny] = dist[cx][cy] + 1;\n                    prev[nx][ny] = {cx, cy};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        if (dist[tx][ty] == INF) return {};\n        \n        vector<pair<int,int>> path;\n        int cx = tx, cy = ty;\n        while (cx != sx || cy != sy) {\n            path.push_back({cx, cy});\n            auto [px, py] = prev[cx][cy];\n            cx = px; cy = py;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto move_to = [&](int tx, int ty) {\n        auto path = get_path(x, y, tx, ty);\n        for (auto [nx, ny] : path) {\n            for (int d = 0; d < 4; d++) {\n                if (x + DX[d] == nx && y + DY[d] == ny) {\n                    ops.push_back(DIR.substr(d, 1));\n                    break;\n                }\n            }\n            x = nx; y = ny;\n        }\n    };\n    \n    // Simple grid scanning approach:\n    // 1. First pass: collect all excess soil and store it centrally\n    // 2. Second pass: distribute from central location\n    \n    // Phase 1: Collect all positive heights\n    for (int i = 0; i < N && (int)ops.size() < MAX_TURNS - 1000; i++) {\n        for (int j = 0; j < N && (int)ops.size() < MAX_TURNS - 1000; j++) {\n            if (h[i][j] > 0) {\n                // Move to this cell\n                if (load > 0) {\n                    // Can't collect while carrying, need to find a place to dump\n                    // For simplicity, find negative cell nearby\n                    bool dumped = false;\n                    for (int ii = 0; ii < N && !dumped; ii++) {\n                        for (int jj = 0; jj < N && !dumped; jj++) {\n                            if (h[ii][jj] < 0) {\n                                move_to(ii, jj);\n                                int dump = min(load, -h[ii][jj]);\n                                if (dump > 0) {\n                                    ops.push_back(\"-\" + to_string(dump));\n                                    h[ii][jj] += dump;\n                                    load -= dump;\n                                }\n                                dumped = true;\n                            }\n                        }\n                    }\n                }\n                \n                move_to(i, j);\n                \n                // Load all soil from this cell\n                if (h[i][j] > 0) {\n                    int amount = h[i][j];\n                    ops.push_back(\"+\" + to_string(amount));\n                    h[i][j] = 0;\n                    load += amount;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Distribute remaining load\n    while (load > 0 && (int)ops.size() < MAX_TURNS) {\n        // Find any negative cell\n        bool found = false;\n        for (int i = 0; i < N && !found; i++) {\n            for (int j = 0; j < N && !found; j++) {\n                if (h[i][j] < 0) {\n                    move_to(i, j);\n                    int dump = min(load, -h[i][j]);\n                    ops.push_back(\"-\" + to_string(dump));\n                    h[i][j] += dump;\n                    load -= dump;\n                    found = true;\n                }\n            }\n        }\n        if (!found) break;\n    }\n    \n    // Handle any remaining negative cells by finding positive ones\n    for (int i = 0; i < N && (int)ops.size() < MAX_TURNS; i++) {\n        for (int j = 0; j < N && (int)ops.size() < MAX_TURNS; j++) {\n            if (h[i][j] < 0) {\n                // Find a source\n                for (int ii = 0; ii < N && (int)ops.size() < MAX_TURNS; ii++) {\n                    for (int jj = 0; jj < N && (int)ops.size() < MAX_TURNS; jj++) {\n                        if (h[ii][jj] > 0) {\n                            move_to(ii, jj);\n                            int take = min(h[ii][jj], -h[i][j]);\n                            ops.push_back(\"+\" + to_string(take));\n                            h[ii][jj] -= take;\n                            load = take;\n                            \n                            move_to(i, j);\n                            ops.push_back(\"-\" + to_string(take));\n                            h[i][j] += take;\n                            load = 0;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (const string& op : ops) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Seed {\n    vector<int> values;\n    int total;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<Seed> seeds(seed_count);\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        seeds[i].values.resize(M);\n        seeds[i].index = i;\n        seeds[i].total = 0;\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i].values[j];\n            seeds[i].total += seeds[i].values[j];\n        }\n    }\n    \n    // Precompute grid positions and their neighbor counts\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            positions.push_back({i, j});\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Sort seeds by total value descending\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return seeds[a].total > seeds[b].total;\n        });\n        \n        // Create placement grid\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Priority positions (center first for more neighbors)\n        vector<pair<int, int>> priority_positions;\n        // Center positions have 4 neighbors\n        for (int i = 1; i < N-1; i++) {\n            for (int j = 1; j < N-1; j++) {\n                priority_positions.push_back({i, j});\n            }\n        }\n        // Edge positions (non-corner) have 3 neighbors\n        for (int i = 1; i < N-1; i++) {\n            priority_positions.push_back({i, 0});\n            priority_positions.push_back({i, N-1});\n            priority_positions.push_back({0, i});\n            priority_positions.push_back({N-1, i});\n        }\n        // Corner positions have 2 neighbors\n        priority_positions.push_back({0, 0});\n        priority_positions.push_back({0, N-1});\n        priority_positions.push_back({N-1, 0});\n        priority_positions.push_back({N-1, N-1});\n        \n        // Place best seeds in priority positions\n        int seed_idx = 0;\n        for (auto pos : priority_positions) {\n            if (seed_idx >= seed_count) break;\n            int seed_num = order[seed_idx];\n            if (!used[seed_num]) {\n                grid[pos.first][pos.second] = seed_num;\n                used[seed_num] = true;\n                seed_idx++;\n            }\n        }\n        \n        // Fill remaining positions\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == -1) {\n                    while (seed_idx < seed_count && used[order[seed_idx]]) {\n                        seed_idx++;\n                    }\n                    if (seed_idx < seed_count) {\n                        grid[i][j] = order[seed_idx];\n                        used[order[seed_idx]] = true;\n                        seed_idx++;\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 << grid[i][j];\n                if (j < N-1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            seeds[i].total = 0;\n            seeds[i].index = i;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].values[j];\n                seeds[i].total += seeds[i].values[j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Structure to represent position\nstruct Pos {\n    int x, y;\n    Pos(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Pos& p) const { return x == p.x && y == p.y; }\n};\n\n// Direction vectors\nconst int dx[] = {0, 1, 0, -1};\nconst int dy[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nclass RoboticArmSolver {\nprivate:\n    int N, M, V;\n    vector<vector<int>> initial_grid, target_grid;\n    vector<Pos> takoyaki_pos, target_pos;\n    \n    // Arm structure\n    int V_actual;\n    vector<int> parent;\n    vector<int> edge_length;\n    vector<int> rotation_state; // 0: right, 1: down, 2: left, 3: up\n    \n    // Current state\n    Pos root_pos;\n    bool holding[15]; // which fingertips are holding\n    \npublic:\n    RoboticArmSolver() {\n        read_input();\n        solve();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> V;\n        initial_grid = vector<vector<int>>(N, vector<int>(N));\n        target_grid = vector<vector<int>>(N, vector<int>(N));\n        \n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                initial_grid[i][j] = line[j] - '0';\n                if (initial_grid[i][j]) {\n                    takoyaki_pos.push_back(Pos(i, j));\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target_grid[i][j] = line[j] - '0';\n                if (target_grid[i][j]) {\n                    target_pos.push_back(Pos(i, j));\n                }\n            }\n        }\n    }\n    \n    // Calculate fingertip positions given root position and rotation states\n    vector<Pos> get_fingertip_positions() {\n        vector<Pos> finger_pos;\n        vector<tuple<int, int, int>> stack; // vertex, x, y, rotation_sum\n        // Rotation sum represents cumulative rotation from root to this vertex\n        \n        for (int v = 0; v < V_actual; v++) {\n            if (v == 0) {\n                stack.push_back({0, root_pos.x, root_pos.y, 0});\n            } else {\n                // Find parent's position\n                auto it = find_if(stack.begin(), stack.end(), \n                    [this, v](const auto& t) { return get<0>(t) == parent[v]; });\n                \n                int px = get<1>(*it);\n                int py = get<2>(*it);\n                int prot = get<3>(*it);\n                \n                int my_rot = (prot + rotation_state[v]) % 4;\n                int dir = (my_rot * 3) % 4; // Initial direction is right, then rotate\n                \n                // For simplicity, use a tree that extends right then down\n                int cx = px, cy = py;\n                if (v % 2 == 1) { // Extend right\n                    cx += dx[my_rot] * edge_length[v];\n                    cy += dy[my_rot] * edge_length[v];\n                } else if (v > 0) { // Extend down\n                    cx += dx[(my_rot + 1) % 4] * edge_length[v];\n                    cy += dy[(my_rot + 1) % 4] * edge_length[v];\n                }\n                \n                stack.push_back({v, cx, cy, my_rot});\n            }\n        }\n        \n        // Leaves are fingertips\n        for (int v = 0; v < V_actual; v++) {\n            bool is_leaf = true;\n            for (int u = 1; u < V_actual; u++) {\n                if (parent[u] == v) {\n                    is_leaf = false;\n                    break;\n                }\n            }\n            if (is_leaf) {\n                auto it = find_if(stack.begin(), stack.end(),\n                    [v](const auto& t) { return get<0>(t) == v; });\n                finger_pos.push_back(Pos(get<1>(*it), get<2>(*it)));\n            }\n        }\n        \n        return finger_pos;\n    }\n    \n    // Design the robotic arm\n    void design_arm() {\n        V_actual = V;\n        parent.resize(V_actual);\n        edge_length.resize(V_actual);\n        rotation_state.resize(V_actual, 0);\n        \n        // Create a tree where:\n        // - Node 0 is root\n        // - Nodes 1..V-1 form a star or small tree\n        // - Each edge has length N-1 for maximum reach\n        \n        parent[0] = -1;\n        edge_length[0] = 0;\n        \n        for (int v = 1; v < V_actual; v++) {\n            // Connect to root or previous node\n            parent[v] = (v <= 4) ? 0 : (v - 4);\n            \n            // Use maximum length for better reach\n            if (v <= 4) {\n                edge_length[v] = N - 1;\n            } else {\n                edge_length[v] = 1;\n            }\n        }\n        \n        // Output arm design\n        cout << V_actual << endl;\n        for (int v = 1; v < V_actual; v++) {\n            cout << parent[v] << \" \" << edge_length[v] << endl;\n        }\n    }\n    \n    // Simple greedy matching of takoyaki to targets\n    vector<pair<int, int>> match_takoyaki() {\n        vector<pair<int, int>> assignment(M);\n        vector<bool> target_used(M, false);\n        \n        // For each takoyaki, find nearest unused target\n        for (int i = 0; i < M; i++) {\n            int best_j = -1;\n            int best_dist = 1e9;\n            \n            for (int j = 0; j < M; j++) {\n                if (!target_used[j]) {\n                    int dist = abs(takoyaki_pos[i].x - target_pos[j].x) \n                             + abs(takoyaki_pos[i].y - target_pos[j].y);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_j = j;\n                    }\n                }\n            }\n            \n            assignment[i] = {i, best_j};\n            target_used[best_j] = true;\n        }\n        \n        return assignment;\n    }\n    \n    // Generate movement commands\n    void generate_commands() {\n        auto assignment = match_takoyaki();\n        vector<bool> delivered(M, false);\n        vector<int> current_pos_idx(M, -1); // -1 means holding\n        \n        // Initialize fingertips at position (0,0) with default rotation\n        root_pos = Pos(0, 0);\n        \n        // For each takoyaki, move it to its target\n        for (int turn = 0; turn < 100000 && !all_of(delivered.begin(), delivered.end(), [](bool b){return b;}); turn++) {\n            string command(2 * V_actual, '.');\n            \n            // Find current fingertip positions\n            auto finger_pos = get_fingertip_positions();\n            \n            // Determine movement direction\n            int target_takoyaki = -1;\n            int min_dist = 1e9;\n            \n            // Find nearest undelivered takoyaki\n            for (int i = 0; i < M; i++) {\n                if (!delivered[i]) {\n                    int dist = abs(root_pos.x - takoyaki_pos[i].x) \n                             + abs(root_pos.y - takoyaki_pos[i].y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        target_takoyaki = i;\n                    }\n                }\n            }\n            \n            if (target_takoyaki >= 0) {\n                // Move towards the takoyaki/target\n                Pos target = (holding[0]) ? target_pos[assignment[target_takoyaki].second] \n                                         : takoyaki_pos[target_takoyaki];\n                \n                if (root_pos.x < target.x) command[0] = 'D';\n                else if (root_pos.x > target.x) command[0] = 'U';\n                else if (root_pos.y < target.y) command[0] = 'R';\n                else if (root_pos.y > target.y) command[0] = 'L';\n                \n                // Update root position\n                if (command[0] != '.') {\n                    switch(command[0]) {\n                        case 'U': root_pos.x--; break;\n                        case 'D': root_pos.x++; break;\n                        case 'L': root_pos.y--; break;\n                        case 'R': root_pos.y++; break;\n                    }\n                }\n            }\n            \n            // Try to grab/release\n            for (int f = 0; f < V_actual; f++) {\n                bool is_leaf = true;\n                for (int u = 1; u < V_actual; u++) {\n                    if (parent[u] == f) {\n                        is_leaf = false;\n                        break;\n                    }\n                }\n                \n                if (is_leaf && f < (int)finger_pos.size()) {\n                    Pos fp = finger_pos[f];\n                    if (fp.x >= 0 && fp.x < N && fp.y >= 0 && fp.y < N) {\n                        // Check if we should grab\n                        for (int i = 0; i < M; i++) {\n                            if (!delivered[i] && fp == takoyaki_pos[i] && !holding[f]) {\n                                command[V_actual + f] = 'P';\n                                holding[f] = true;\n                                break;\n                            }\n                            // Check if we should release\n                            if (holding[f] && fp == target_pos[assignment[i].second] && !delivered[i]) {\n                                command[V_actual + f] = 'P';\n                                holding[f] = false;\n                                delivered[i] = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n        \n        // Fill remaining turns if needed\n        for (int turn = 100000; turn > 0 && turn > 0; turn--) {\n            string command(2 * V_actual, '.');\n            cout << command << endl;\n        }\n    }\n    \n    void solve() {\n        design_arm();\n        \n        // Initial position\n        cout << 0 << \" \" << 0 << endl;\n        \n        generate_commands();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    RoboticArmSolver solver;\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 5000;\n    vector<pair<int,int>> mackerel(N), sardine(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> mackerel[i].first >> mackerel[i].second;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sardine[i].first >> sardine[i].second;\n    }\n    \n    // Collect all unique coordinates for discretization\n    set<int> xs_set, ys_set;\n    for (auto& p : mackerel) {\n        xs_set.insert(p.first);\n        ys_set.insert(p.second);\n    }\n    for (auto& p : sardine) {\n        xs_set.insert(p.first);\n        ys_set.insert(p.second);\n    }\n    \n    vector<int> xs(xs_set.begin(), xs_set.end());\n    vector<int> ys(ys_set.begin(), ys_set.end());\n    \n    int H = xs.size(), W = ys.size();\n    \n    // Build grid with fish values\n    vector<vector<int>> grid(H, vector<int>(W, 0));\n    for (auto& p : mackerel) {\n        int ix = lower_bound(xs.begin(), xs.end(), p.first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), p.second) - ys.begin();\n        grid[ix][iy] = 1;\n    }\n    for (auto& p : sardine) {\n        int ix = lower_bound(xs.begin(), xs.end(), p.first) - xs.begin();\n        int iy = lower_bound(ys.begin(), ys.end(), p.second) - ys.begin();\n        grid[ix][iy] = -1;\n    }\n    \n    // 2D prefix sum\n    vector<vector<int>> pref(H+1, vector<int>(W+1, 0));\n    for (int i = 1; i <= H; i++) {\n        for (int j = 1; j <= W; j++) {\n            pref[i][j] = pref[i-1][j] + pref[i][j-1] - pref[i-1][j-1] + grid[i-1][j-1];\n        }\n    }\n    \n    auto rect_sum = [&](int r1, int c1, int r2, int c2) {\n        return pref[r2+1][c2+1] - pref[r1][c2+1] - pref[r2+1][c1] + pref[r1][c1];\n    };\n    \n    // Find best rectangle using multiple candidates\n    // Try different regions and pick the best\n    vector<tuple<int,int,int,int>> candidates;\n    \n    // Try each cell as a starting point with some window\n    int step = max(1, H / 20);  // Sample grid coarsely\n    for (int i = 0; i < H; i += step) {\n        for (int j = 0; j < W; j += step) {\n            // Try to expand rectangle from this point\n            int best_sum = -1e9, best_i2 = i, best_j2 = j;\n            for (int i2 = i; i2 < min(H, i + 50); i2++) {\n                for (int j2 = j; j2 < min(W, j + 50); j2++) {\n                    int sum = rect_sum(i, j, i2, j2);\n                    if (sum > best_sum) {\n                        best_sum = sum;\n                        best_i2 = i2;\n                        best_j2 = j2;\n                    }\n                }\n            }\n            if (best_sum > 0) {\n                candidates.push_back({i, j, best_i2, best_j2});\n            }\n        }\n    }\n    \n    // Pick the best candidate\n    auto best = *max_element(candidates.begin(), candidates.end(), \n        [&](const auto& a, const auto& b) {\n            auto [r1,c1,r2,c2] = a;\n            auto [r3,c3,r4,c4] = b;\n            return rect_sum(r1,c1,r2,c2) < rect_sum(r3,c3,r4,c4);\n        });\n    \n    auto [r1, c1, r2, c2] = best;\n    \n    // Convert to actual coordinates with margin\n    int PAD = 1;\n    int x1 = max(0, xs[r1] - PAD);\n    int y1 = max(0, ys[c1] - PAD);\n    int x2 = min(100000, xs[r2] + PAD);\n    int y2 = min(100000, ys[c2] + PAD);\n    \n    // Ensure polygon has at least some area\n    if (x1 == x2) x2 = min(100000, x1 + 1);\n    if (y1 == y2) y2 = min(100000, y1 + 1);\n    \n    // Output rectangle\n    cout << \"4\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nstruct Rectangle {\n    int w, h;\n    int w_m, h_m; // measured values\n};\n\nint N, T, sigma;\nvector<Rectangle> rects;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n};\n\nstruct PackingResult {\n    vector<Placement> placements;\n    int width;\n    int height;\n    int score;\n    int unplaced_sum;\n};\n\n// Simulate a sequence of placements and return the actual dimensions\nPackingResult simulate_placement(const vector<Placement>& placements) {\n    // Track placed rectangles\n    vector<bool> placed(N, false);\n    vector<int> x(N), y(N), w(N), h(N);\n    \n    for (const auto& pl : placements) {\n        int idx = pl.p;\n        placed[idx] = true;\n        \n        int rw = rects[idx].w_m, rh = rects[idx].h_m;\n        if (pl.r) swap(rw, rh);\n        \n        w[idx] = rw;\n        h[idx] = rh;\n        \n        if (pl.d == 'U') {\n            // Align left edge with reference\n            int left_x = 0;\n            if (pl.b >= 0) {\n                left_x = x[pl.b] + w[pl.b];\n            }\n            \n            // Find lowest y where it fits without overlap\n            int best_y = 0;\n            for (int j = 0; j < idx; j++) {\n                if (!placed[j]) continue;\n                // Check if this rectangle overlaps horizontally\n                int rx = x[j], rw2 = w[j];\n                if (left_x < rx + rw2 && left_x + rw > rx) {\n                    best_y = max(best_y, y[j] + h[j]);\n                }\n            }\n            \n            x[idx] = left_x;\n            y[idx] = best_y;\n        } else { // 'L'\n            // Align top edge with reference\n            int top_y = 0;\n            if (pl.b >= 0) {\n                top_y = y[pl.b] + h[pl.b];\n            }\n            \n            // Find leftmost x where it fits without overlap\n            int best_x = 0;\n            for (int j = 0; j < idx; j++) {\n                if (!placed[j]) continue;\n                // Check if this rectangle overlaps vertically\n                int ry = y[j], rh2 = h[j];\n                if (top_y < ry + rh2 && top_y + rh > ry) {\n                    best_x = max(best_x, x[j] + w[j]);\n                }\n            }\n            \n            x[idx] = best_x;\n            y[idx] = top_y;\n        }\n    }\n    \n    // Calculate bounding box\n    int max_x = 0, max_y = 0;\n    int unplaced_sum = 0;\n    \n    for (int i = 0; i < N; i++) {\n        if (placed[i]) {\n            max_x = max(max_x, x[i] + w[i]);\n            max_y = max(max_y, y[i] + h[i]);\n        } else {\n            unplaced_sum += rects[i].w_m + rects[i].h_m;\n        }\n    }\n    \n    return {placements, max_x, max_y, max_x + max_y + unplaced_sum, unplaced_sum};\n}\n\n// Generate a packing using shelf algorithm\nvector<Placement> generate_shelf_packing(const vector<pair<int,int>>& order, \n                                         const vector<bool>& rotate) {\n    vector<Placement> result;\n    \n    // Track the \"skyline\" for placement\n    // For simplicity, use a simple shelf approach\n    \n    int current_x = 0, current_y = 0;\n    int shelf_height = 0;\n    \n    for (int i : order) {\n        if (i >= N) continue;\n        \n        int idx = i;\n        int rw = rects[idx].w_m, rh = rects[idx].h_m;\n        if (rotate[idx]) swap(rw, rh);\n        \n        // Try to place on current shelf\n        if (current_x + rw <= 1000000) { // reasonable width limit\n            Placement pl;\n            pl.p = idx;\n            pl.r = rotate[idx];\n            pl.d = 'U';\n            pl.b = (result.empty() ? -1 : result.back().p);\n            result.push_back(pl);\n            current_x += rw;\n            shelf_height = max(shelf_height, rh);\n        } else {\n            // Start new shelf\n            Placement pl;\n            pl.p = idx;\n            pl.r = rotate[idx];\n            pl.d = 'L';\n            pl.b = -1;\n            result.push_back(pl);\n            current_x = rw;\n            current_y += shelf_height;\n            shelf_height = rh;\n        }\n    }\n    \n    return result;\n}\n\nvoid query_and_get_result(const vector<Placement>& placements, \n                          int& W, int& H) {\n    cout << placements.size() << endl;\n    for (const auto& pl : placements) {\n        cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << endl;\n    }\n    cout.flush();\n    cin >> W >> H;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> T >> sigma;\n    rects.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w_m >> rects[i].h_m;\n    }\n    \n    int best_score = 2e9;\n    vector<Placement> best_placements;\n    \n    // Strategy 1: Sort by measured height, try both orientations\n    vector<pair<int,int>> height_order;\n    for (int i = 0; i < N; i++) {\n        height_order.push_back({rects[i].h_m, i});\n    }\n    sort(height_order.begin(), height_order.end());\n    \n    // Strategy 2: Sort by measured width\n    vector<pair<int,int>> width_order;\n    for (int i = 0; i < N; i++) {\n        width_order.push_back({rects[i].w_m, i});\n    }\n    sort(width_order.begin(), width_order.end());\n    \n    for (int turn = 0; turn < T; turn++) {\n        // Try multiple strategies each turn\n        int W, H;\n        \n        // Strategy: try different orderings and rotations\n        for (int attempt = 0; attempt < 10; attempt++) {\n            vector<bool> rotate(N, false);\n            vector<pair<int,int>> order;\n            \n            // Vary ordering based on attempt\n            if (attempt < 3) {\n                // Use height-based ordering\n                order = height_order;\n                if (attempt == 1) {\n                    // Swap some orientations\n                    for (int i = 0; i < N; i += 2) {\n                        if (rects[i].w_m > rects[i].h_m) {\n                            rotate[i] = true;\n                        }\n                    }\n                }\n            } else if (attempt < 6) {\n                // Use width-based ordering\n                order = width_order;\n                if (attempt == 4) {\n                    for (int i = 0; i < N; i += 2) {\n                        if (rects[i].h_m > rects[i].w_m) {\n                            rotate[i] = true;\n                        }\n                    }\n                }\n            } else {\n                // Random ordering\n                order.clear();\n                for (int i = 0; i < N; i++) order.push_back({0, i});\n                shuffle(order.begin(), order.end(), rng);\n                for (int i = 0; i < N; i++) {\n                    rotate[order[i].second] = (rng() % 2);\n                }\n            }\n            \n            auto placements = generate_shelf_packing(order, rotate);\n            auto result = simulate_placement(placements);\n            \n            if (result.score < best_score) {\n                best_score = result.score;\n                best_placements = placements;\n                \n                // Actually output this one\n                query_and_get_result(placements, W, H);\n                cout.flush();\n                goto next_turn;\n            }\n        }\n        \n        // If no improvement, try best known\n        {\n            query_and_get_result(best_placements, W, H);\n            cout.flush();\n        }\n        \n        next_turn:\n        // Use W, H for next iteration (though we don't use it much due to noise)\n        continue;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    // skip coordinates, not needed\n    \n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    \n    // indices sorted by beauty descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return A[i] > A[j];\n    });\n    \n    for (int v : order) {\n        int best_parent = -1;\n        int best_depth = -1;\n        for (int u : adj[v]) {\n            if (parent[u] != -1 && depth[u] < H) {\n                if (depth[u] > best_depth) {\n                    best_depth = depth[u];\n                    best_parent = u;\n                }\n            }\n        }\n        if (best_parent != -1) {\n            parent[v] = best_parent;\n            depth[v] = depth[best_parent] + 1;\n        } else {\n            // become root\n            parent[v] = -1;\n            depth[v] = 0;\n        }\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    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Find all Oni positions\n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // Precompute Fukunokami positions for quick checking\n    vector<vector<bool>> is_fuku(N, vector<bool>(N, false));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'o') {\n                is_fuku[i][j] = true;\n            }\n        }\n    }\n    \n    vector<string> ans;\n    \n    for (auto [oni_i, oni_j] : oni_positions) {\n        // Check clear directions and find the one with minimum operations\n        int best_ops = INT_MAX;\n        char best_dir = '?';\n        \n        // Check Up\n        bool clear_up = true;\n        for (int k = oni_i - 1; k >= 0; k--) {\n            if (is_fuku[k][oni_j]) {\n                clear_up = false;\n                break;\n            }\n        }\n        if (clear_up) {\n            int ops = 2 * (oni_i + 1);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'U';\n            }\n        }\n        \n        // Check Down\n        bool clear_down = true;\n        for (int k = oni_i + 1; k < N; k++) {\n            if (is_fuku[k][oni_j]) {\n                clear_down = false;\n                break;\n            }\n        }\n        if (clear_down) {\n            int ops = 2 * (N - oni_i);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'D';\n            }\n        }\n        \n        // Check Left\n        bool clear_left = true;\n        for (int k = oni_j - 1; k >= 0; k--) {\n            if (is_fuku[oni_i][k]) {\n                clear_left = false;\n                break;\n            }\n        }\n        if (clear_left) {\n            int ops = 2 * (oni_j + 1);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'L';\n            }\n        }\n        \n        // Check Right\n        bool clear_right = true;\n        for (int k = oni_j + 1; k < N; k++) {\n            if (is_fuku[oni_i][k]) {\n                clear_right = false;\n                break;\n            }\n        }\n        if (clear_right) {\n            int ops = 2 * (N - oni_j);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'R';\n            }\n        }\n        \n        // Perform the operations\n        if (best_dir == 'U') {\n            for (int t = 0; t < oni_i + 1; t++) {\n                ans.push_back(\"U \" + to_string(oni_j));\n            }\n            for (int t = 0; t < oni_i + 1; t++) {\n                ans.push_back(\"D \" + to_string(oni_j));\n            }\n        } else if (best_dir == 'D') {\n            for (int t = 0; t < N - oni_i; t++) {\n                ans.push_back(\"D \" + to_string(oni_j));\n            }\n            for (int t = 0; t < N - oni_i; t++) {\n                ans.push_back(\"U \" + to_string(oni_j));\n            }\n        } else if (best_dir == 'L') {\n            for (int t = 0; t < oni_j + 1; t++) {\n                ans.push_back(\"L \" + to_string(oni_i));\n            }\n            for (int t = 0; t < oni_j + 1; t++) {\n                ans.push_back(\"R \" + to_string(oni_i));\n            }\n        } else { // Right\n            for (int t = 0; t < N - oni_j; t++) {\n                ans.push_back(\"R \" + to_string(oni_i));\n            }\n            for (int t = 0; t < N - oni_j; t++) {\n                ans.push_back(\"L \" + to_string(oni_i));\n            }\n        }\n    }\n    \n    // Output the solution\n    for (const string& s : ans) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#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 = 100;\n    const int L = 500000;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    // Strategy: Each employee i needs T_i visits total\n    // We can think of this as: for each visit to employee i,\n    // we need to decide a successor\n    // \n    // Since we start with employee 0 and there are L total visits,\n    // we need to construct a walk of length L that matches T\n    \n    // Key observation: If we set a_i = b_i for all i, \n    // then the walk is just following a deterministic path\n    // This means each employee has exactly one outgoing edge\n    // But then the walk is just a path in a functional graph\n    \n    // Alternative: Distribute outgoing edges to minimize error\n    // \n    // For employee i with f_i total visits:\n    // - If f_i is odd: ceil(f_i/2) go to a_i, floor(f_i/2) go to b_i\n    // - If f_i is even: exactly f_i/2 go to each\n    \n    // Simple deterministic construction:\n    // Route to employees that need more visits\n    \n    // Build a priority queue of who needs more incoming visits\n    vector<int> a(N), b(N);\n    \n    // Use a greedy approach: for each employee, \n    // pick successors that have deficit in target visits\n    \n    // To make this fast and avoid simulation:\n    // Use a simple heuristic based on T values only\n    \n    // For employee i, set a_i to an employee with high T (needs many visits)\n    // and b_i to another employee with high T\n    \n    // Sort employees by T\n    vector<pair<int,int>> order;\n    for (int i = 0; i < N; i++) {\n        order.push_back({T[i], i});\n    }\n    sort(order.begin(), order.end(), greater<>());\n    \n    // Now assign successors\n    // Employees with highest T should receive many incoming edges\n    for (int i = 0; i < N; i++) {\n        int emp = order[i].second;\n        \n        // Find two different successors with highest T values\n        // Skip if it's the same employee (we can keep self-loops)\n        if (i < N/2) {\n            // High T employees point to other high T employees\n            a[emp] = order[(i + 1) % N].second;\n            b[emp] = order[(i + 2) % N].second;\n        } else {\n            // Low T employees point to the highest T employees\n            a[emp] = order[0].second;\n            b[emp] = order[1].second;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\n\nstruct City {\n    int lx, rx, ly, ry;\n    int cx, cy;\n};\n\nvector<City> cities;\n\n// Query function with proper flushing\nvector<pair<int,int>> query(const vector<int>& subset) {\n    cout << \"? \" << subset.size();\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int,int>> result;\n    for (int i = 0; i < (int)subset.size() - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        result.emplace_back(a, b);\n    }\n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cities.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].cx = (cities[i].lx + cities[i].rx) / 2;\n        cities[i].cy = (cities[i].ly + cities[i].ry) / 2;\n    }\n    \n    // Sort cities by center coordinates\n    vector<int> city_order(N);\n    iota(city_order.begin(), city_order.end(), 0);\n    sort(city_order.begin(), city_order.end(), [&](int a, int b) {\n        if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n        return cities[a].cy < cities[b].cy;\n    });\n    \n    // Assign cities to groups\n    vector<vector<int>> groups(M);\n    vector<vector<pair<int,int>>> group_edges(M);\n    \n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i].resize(G[i]);\n        for (int j = 0; j < G[i]; j++) {\n            groups[i][j] = city_order[idx++];\n        }\n    }\n    \n    int queries_used = 0;\n    \n    // Process each group\n    for (int k = 0; k < M; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g == 1) {\n            group_edges[k] = {};\n            continue;\n        }\n        \n        if (g == 2) {\n            group_edges[k] = {{group[0], group[1]}};\n            continue;\n        }\n        \n        // Collect all edges from queries for this group\n        vector<pair<int,int>> edges_found;\n        set<pair<int,int>> edge_set; // to avoid duplicates\n        \n        // Make queries of size 3, sliding window\n        for (int i = 0; i + 2 < g && queries_used < Q; i++) {\n            vector<int> subset = {group[i], group[i+1], group[i+2]};\n            auto result = query(subset);\n            queries_used++;\n            \n            for (auto& e : result) {\n                int u = e.first, v = e.second;\n                if (u > v) swap(u, v);\n                if (edge_set.count({u, v}) == 0) {\n                    edge_set.insert({u, v});\n                    edges_found.push_back({u, v});\n                }\n            }\n        }\n        \n        // Build a spanning tree from the edges using DSU\n        // First, connect using queried edges\n        vector<int> parent(N);\n        iota(parent.begin(), parent.end(), 0);\n        \n        function<int(int)> find = [&](int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        };\n        \n        auto unite = [&](int a, int b) {\n            a = find(a); b = find(b);\n            if (a != b) {\n                parent[a] = b;\n                return true;\n            }\n            return false;\n        };\n        \n        // Use queried edges first\n        for (auto& e : edges_found) {\n            if (unite(e.first, e.second)) {\n                group_edges[k].push_back(e);\n            }\n        }\n        \n        // Connect remaining components using simple heuristic\n        // Sort by city index within group for deterministic behavior\n        vector<int> remaining;\n        for (int c : group) {\n            if (find(c) != find(group[0])) {\n                remaining.push_back(c);\n            }\n        }\n        \n        // Connect disconnected cities to the main component\n        for (int c : remaining) {\n            // Find the closest city in the main component (by center distance)\n            int best = -1;\n            long long best_dist = LLONG_MAX;\n            \n            for (int d : group) {\n                if (find(d) == find(group[0])) {\n                    long long dx = cities[c].cx - cities[d].cx;\n                    long long dy = cities[c].cy - cities[d].cy;\n                    long long dist = dx * dx + dy * dy;\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best = d;\n                    }\n                }\n            }\n            \n            if (best != -1) {\n                // Try to make a query if we have remaining queries\n                if (queries_used < Q) {\n                    // Need at least 2 cities, max L, add a third if possible\n                    vector<int> subset;\n                    subset.push_back(c);\n                    subset.push_back(best);\n                    // Add another connected city if L > 2\n                    if (L > 2) {\n                        for (int d : group) {\n                            if (d != c && d != best) {\n                                subset.push_back(d);\n                                break;\n                            }\n                        }\n                    }\n                    \n                    auto result = query(subset);\n                    queries_used++;\n                    \n                    // Add any new edges\n                    for (auto& e : result) {\n                        if (unite(e.first, e.second)) {\n                            group_edges[k].push_back(e);\n                        }\n                    }\n                } else {\n                    // No queries left, add direct edge\n                    unite(c, best);\n                    group_edges[k].push_back({c, best});\n                }\n            }\n        }\n        \n        // Final check: ensure we have exactly g-1 edges\n        while ((int)group_edges[k].size() < g - 1) {\n            // Find two cities that are not connected\n            for (int i = 0; i < g && (int)group_edges[k].size() < g - 1; i++) {\n                for (int j = i + 1; j < g && (int)group_edges[k].size() < g - 1; j++) {\n                    if (unite(group[i], group[j])) {\n                        group_edges[k].push_back({group[i], group[j]});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output final answer\n    cout << \"!\" << endl;\n    cout.flush();\n    \n    for (int i = 0; i < M; i++) {\n        // Output cities in this group\n        for (int j = 0; j < G[i]; 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        cout.flush();\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Cell {\n    int r, c;\n    Cell(int r = 0, int c = 0) : r(r), c(c) {}\n};\n\nstring dirs = \"UDLR\";\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<Cell> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].r >> targets[i].c;\n    }\n    \n    // State tracking\n    vector<string> grid(N, string(N, '.'));\n    int posR = targets[0].r, posC = targets[0].c;\n    vector<string> actions;\n    \n    auto getBlock = [&](int r, int c) -> bool {\n        return !(r >= 0 && r < N && c >= 0 && c < N) || grid[r][c] == '#';\n    };\n    \n    // Simple strategy: Use Manhattan moves with occasional slides\n    for (int idx = 1; idx < M; idx++) {\n        int tr = targets[idx].r, tc = targets[idx].c;\n        \n        // While not at target, move towards it\n        while (posR != tr || posC != tc) {\n            // Try to find a good slide direction\n            int bestSlideDir = -1;\n            int bestSlideDist = abs(posR - tr) + abs(posC - tc);\n            \n            for (int d = 0; d < 4; d++) {\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Slide as far as possible in this direction\n                    int sr = nr, sc = nc;\n                    while (true) {\n                        int nnr = sr + dr[d], nnc = sc + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        sr = nnr; sc = nnc;\n                    }\n                    int dist = abs(sr - tr) + abs(sc - tc);\n                    if (dist < bestSlideDist) {\n                        bestSlideDist = dist;\n                        bestSlideDir = d;\n                    }\n                }\n            }\n            \n            bool usedSlide = false;\n            if (bestSlideDir >= 0) {\n                int d = bestSlideDir;\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Execute slide\n                    actions.push_back(\"S \" + string(1, dirs[d]));\n                    \n                    // Update position\n                    while (true) {\n                        int nnr = posR + dr[d], nnc = posC + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        posR = nnr; posC = nnc;\n                    }\n                    usedSlide = true;\n                }\n            }\n            \n            if (!usedSlide) {\n                // Simple move towards target\n                int bestDir = -1;\n                int bestDist = abs(posR - tr) + abs(posC - tc);\n                \n                for (int d = 0; d < 4; d++) {\n                    int nr = posR + dr[d], nc = posC + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                        int dist = abs(nr - tr) + abs(nc - tc);\n                        if (dist < bestDist) {\n                            bestDist = dist;\n                            bestDir = d;\n                        }\n                    }\n                }\n                \n                if (bestDir >= 0) {\n                    // Check if we can place a block to improve future slides\n                    // For simplicity, just move\n                    int nr = posR + dr[bestDir], nc = posC + dc[bestDir];\n                    actions.push_back(\"M \" + string(1, dirs[bestDir]));\n                    posR = nr; posC = nc;\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (const auto& a : actions) {\n        cout << a << \"\\n\";\n    }\n    \n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Xorshift random number generator\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    \n    using result_type = uint64_t;\n    \n    uint64_t operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    \n    static constexpr uint64_t min() { return 0; }\n    static constexpr uint64_t max() { return ULLONG_MAX; }\n    \n    int rand_int(int l, int r) {\n        return l + operator()() % (r - l + 1);\n    }\n    \n    double rand_double() {\n        return (double)operator()() / ULLONG_MAX;\n    }\n} rng;\n\nstruct Rect {\n    int a, b, c, d;  // (a,b) top-left, (c,d) bottom-right\n    int x, y, r;     // target point and desired area\n    long long s;     // current area\n    \n    Rect() : a(0), b(0), c(0), d(0), x(0), y(0), r(0), s(0) {}\n    Rect(int a_, int b_, int c_, int d_, int x_, int y_, int r_)\n        : a(a_), b(b_), c(c_), d(d_), x(x_), y(y_), r(r_) {\n        s = (long long)(c - a) * (d - b);\n    }\n    \n    bool contains(int px, int py) const {\n        return a <= px && px < c && b <= py && py < d;\n    }\n    \n    double score() const {\n        if (!contains(x, y)) return 0.0;\n        if (s == 0) return 0.0;\n        double ratio = (r < s) ? (double)r / s : (double)s / r;\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    double potential_score(int na, int nb, int nc, int nd) const {\n        if (!(na <= x && x < nc && nb <= y && y < nd)) return 0.0;\n        long long ns = (long long)(nc - na) * (nd - nb);\n        if (ns == 0) return 0.0;\n        double ratio = (r < ns) ? (double)r / ns : (double)ns / r;\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<int> x(n), y(n), r(n);\n    long long total_r = 0;\n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n        total_r += r[i];\n    }\n    \n    // Phase 1: Greedy construction using Voronoi-inspired partitioning\n    vector<Rect> rects(n);\n    \n    // Sort indices by desired area (descending) for priority\n    vector<int> idx(n);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int i, int j) {\n        return r[i] > r[j];\n    });\n    \n    // For each point, grow a rectangle greedily\n    // We'll divide the space into initial regions using a grid\n    \n    // Initialize with minimal rectangles\n    for (int i = 0; i < n; i++) {\n        rects[i] = Rect(x[i], y[i], x[i] + 1, y[i] + 1, x[i], y[i], r[i]);\n    }\n    \n    // Phase 2: Simulated Annealing\n    const double start_temp = 1.0;\n    const double end_temp = 0.001;\n    const int iterations = 50000;\n    \n    auto get_total_score = [&]() {\n        double sum = 0;\n        for (const auto& rect : rects) sum += rect.score();\n        return sum;\n    };\n    \n    auto check_overlap = [&](int exclude_idx, int na, int nb, int nc, int nd) {\n        for (int j = 0; j < n; j++) {\n            if (j == exclude_idx) continue;\n            if (max(na, rects[j].a) < min(nc, rects[j].c) && \n                max(nb, rects[j].b) < min(nd, rects[j].d)) {\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    double current_score = get_total_score();\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        double temp = start_temp + (end_temp - start_temp) * iter / iterations;\n        \n        // Pick a random rectangle and try to modify it\n        int i = rng.rand_int(0, n - 1);\n        auto& rect = rects[i];\n        \n        // Generate neighbor: expand or shrink in one direction\n        int dir = rng.rand_int(0, 3);\n        int delta = rng.rand_int(1, min(100, max(1, (int)sqrt(rect.r))));\n        \n        int na = rect.a, nb = rect.b, nc = rect.c, nd = rect.d;\n        \n        if (dir == 0) { // expand left\n            na = max(0, rect.a - delta);\n        } else if (dir == 1) { // expand right\n            nc = min(10000, rect.c + delta);\n        } else if (dir == 2) { // expand up\n            nb = max(0, rect.b - delta);\n        } else { // expand down\n            nd = min(10000, rect.d + delta);\n        }\n        \n        // Must contain target point\n        if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n        \n        // Check overlap\n        if (check_overlap(i, na, nb, nc, nd)) continue;\n        \n        double new_score = rect.potential_score(na, nb, nc, nd);\n        double score_diff = new_score - rect.score();\n        \n        // Accept with probability based on temperature\n        if (score_diff > 0 || rng.rand_double() < exp(score_diff * 1000 / temp)) {\n            rect.a = na;\n            rect.b = nb;\n            rect.c = nc;\n            rect.d = nd;\n            rect.s = (long long)(nc - na) * (nd - nb);\n            current_score += score_diff;\n        }\n        \n        // Also try shrinking if we're too big\n        if (rect.s > rect.r * 1.5 && rng.rand_double() < 0.3) {\n            dir = rng.rand_int(0, 3);\n            delta = rng.rand_int(1, min(50, (int)(sqrt(rect.s) / 2)));\n            \n            na = rect.a; nb = rect.b; nc = rect.c; nd = rect.d;\n            \n            if (dir == 0) { // shrink from right\n                nc = max(na + 1, rect.c - delta);\n            } else if (dir == 1) { // shrink from left\n                na = min(nc - 1, rect.a + delta);\n            } else if (dir == 2) { // shrink from bottom\n                nd = max(nb + 1, rect.d - delta);\n            } else { // shrink from top\n                nb = min(nd - 1, rect.b + delta);\n            }\n            \n            if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n            if (check_overlap(i, na, nb, nc, nd)) continue;\n            \n            double shrink_score = rect.potential_score(na, nb, nc, nd);\n            double shrink_diff = shrink_score - rect.score();\n            \n            if (shrink_diff > 0 || rng.rand_double() < exp(shrink_diff * 500 / temp)) {\n                rect.a = na;\n                rect.b = nb;\n                rect.c = nc;\n                rect.d = nd;\n                rect.s = (long long)(nc - na) * (nd - nb);\n                current_score += shrink_diff;\n            }\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \"\n             << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst string dirs = \"UDLR\";\n\nstruct State {\n    vector<int> used;\n    int i, j;\n    long long score;\n    string path;\n    \n    State() : used(), i(0), j(0), score(0) {}\n};\n\nclass Solver {\nprivate:\n    int si, sj;\n    vector<vector<int>> t, p;\n    int M;\n    long long best_score;\n    string best_path;\n    vector<vector<pair<int,int>>> tile_cells;\n    vector<int> tile_size;\n    \npublic:\n    Solver() {\n        cin >> si >> sj;\n        t.assign(N, vector<int>(N));\n        p.assign(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> p[i][j];\n        \n        // Find max tile ID\n        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        // Build tile info\n        tile_cells.resize(M);\n        tile_size.resize(M, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                tile_cells[t[i][j]].push_back({i, j});\n                tile_size[t[i][j]]++;\n            }\n        }\n    }\n    \n    string solve() {\n        best_score = -1;\n        best_path = \"\";\n        \n        // Phase 1: Multiple beam search attempts\n        for (int attempt = 0; attempt < 50; attempt++) {\n            beam_search(attempt);\n        }\n        \n        // Phase 2: Try starting with all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            State start;\n            start.used.assign(M, 0);\n            start.i = si;\n            start.j = sj;\n            start.score = p[si][sj];\n            start.used[t[si][sj]] = 1;\n            \n            // Force first move in this direction if possible\n            int ni = si + di[dir];\n            int nj = sj + dj[dir];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && !start.used[t[ni][nj]]) {\n                start.used[t[ni][nj]] = 1;\n                start.i = ni;\n                start.j = nj;\n                start.score += p[ni][nj];\n                start.path = dirs[dir];\n            }\n            \n            // Continue with beam search from this state\n            beam_search_from_state(start, dir + 50);\n        }\n        \n        return best_path;\n    }\n    \nprivate:\n    void beam_search(int attempt) {\n        const int BEAM_WIDTH = 8;\n        \n        State start;\n        start.used.assign(M, 0);\n        start.i = si;\n        start.j = sj;\n        start.score = p[si][sj];\n        start.used[t[si][sj]] = 1;\n        \n        vector<State> beam = {start};\n        \n        for (int step = 0; step < 200; step++) {\n            vector<State> candidates;\n            \n            for (const auto& state : beam) {\n                // Try all moves with heuristic\n                vector<pair<long long, pair<int,int>>> moves;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = state.i + di[d];\n                    int nj = state.j + dj[d];\n                    \n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    if (state.used[t[ni][nj]]) continue;\n                    \n                    // Compute heuristic\n                    long long h = p[ni][nj];\n                    \n                    // Look ahead: value of adjacent tiles\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nni = ni + di[dd];\n                        int nnj = nj + dj[dd];\n                        if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n                        if (!state.used[t[nni][nnj]]) {\n                            h += p[nni][nnj] * 0.3;\n                        }\n                    }\n                    \n                    // Bonus for visiting larger tiles first\n                    if (tile_size[t[ni][nj]] > 1) {\n                        h += 10;\n                    }\n                    \n                    // Random factor for exploration (varies with attempt)\n                    int r = (attempt * 7 + d * 11 + step * 13) % 20;\n                    h += r;\n                    \n                    moves.push_back({h, {ni, nj}});\n                }\n                \n                if (moves.empty()) continue;\n                \n                // Sort by heuristic descending\n                sort(moves.begin(), moves.end(), \n                     [](const auto& a, const auto& b) { return a.first > b.first; });\n                \n                // Take top BEAM_WIDTH/2 moves\n                int take = min((int)moves.size(), BEAM_WIDTH / 2);\n                for (int k = 0; k < take; k++) {\n                    auto [h, pos] = moves[k];\n                    int ni = pos.first, nj = pos.second;\n                    \n                    State new_state = state;\n                    new_state.used[t[ni][nj]] = 1;\n                    new_state.i = ni;\n                    new_state.j = nj;\n                    new_state.score += p[ni][nj];\n                    new_state.path += dirs[find_direction(state.i, state.j, ni, nj)];\n                    candidates.push_back(new_state);\n                }\n            }\n            \n            if (candidates.empty()) break;\n            \n            // Keep top states\n            sort(candidates.begin(), candidates.end(),\n                 [](const State& a, const State& b) { return a.score > b.score; });\n            \n            beam.clear();\n            for (int k = 0; k < min((int)candidates.size(), BEAM_WIDTH); k++) {\n                beam.push_back(candidates[k]);\n                \n                // Update best\n                if (candidates[k].score > best_score) {\n                    best_score = candidates[k].score;\n                    best_path = candidates[k].path;\n                }\n            }\n        }\n        \n        // Check final states\n        for (const auto& state : beam) {\n            if (state.score > best_score) {\n                best_score = state.score;\n                best_path = state.path;\n            }\n        }\n    }\n    \n    void beam_search_from_state(State start, int attempt) {\n        const int BEAM_WIDTH = 5;\n        vector<State> beam = {start};\n        \n        for (int step = 0; step < 150; step++) {\n            vector<State> candidates;\n            \n            for (const auto& state : beam) {\n                vector<pair<long long, pair<int,int>>> moves;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = state.i + di[d];\n                    int nj = state.j + dj[d];\n                    \n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    if (state.used[t[ni][nj]]) continue;\n                    \n                    // Enhanced heuristic\n                    long long h = p[ni][nj];\n                    \n                    // Look 2 steps ahead\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nni = ni + di[dd];\n                        int nnj = nj + dj[dd];\n                        if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n                        if (!state.used[t[nni][nnj]]) {\n                            h += p[nni][nnj] * 0.5;\n                            \n                            // Look 3 steps ahead\n                            for (int ddd = 0; ddd < 4; ddd++) {\n                                int nnni = nni + di[ddd];\n                                int nnnj = nnj + dj[ddd];\n                                if (nnni < 0 || nnni >= N || nnnj < 0 || nnnj >= N) continue;\n                                if (!state.used[t[nnni][nnnj]]) {\n                                    h += p[nnni][nnnj] * 0.25;\n                                }\n                            }\n                        }\n                    }\n                    \n                    // Bonus for tiles that give more future options\n                    int future_moves = 0;\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nni = ni + di[dd];\n                        int nnj = nj + dj[dd];\n                        if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && !state.used[t[nni][nnj]]) {\n                            future_moves++;\n                        }\n                    }\n                    h += future_moves * 15;\n                    \n                    moves.push_back({h, {ni, nj}});\n                }\n                \n                if (moves.empty()) continue;\n                \n                sort(moves.begin(), moves.end(),\n                     [](const auto& a, const auto& b) { return a.first > b.first; });\n                \n                int take = min((int)moves.size(), BEAM_WIDTH / 2);\n                for (int k = 0; k < take; k++) {\n                    auto [h, pos] = moves[k];\n                    int ni = pos.first, nj = pos.second;\n                    \n                    State new_state = state;\n                    new_state.used[t[ni][nj]] = 1;\n                    new_state.i = ni;\n                    new_state.j = nj;\n                    new_state.score += p[ni][nj];\n                    new_state.path += dirs[find_direction(state.i, state.j, ni, nj)];\n                    candidates.push_back(new_state);\n                }\n            }\n            \n            if (candidates.empty()) break;\n            \n            sort(candidates.begin(), candidates.end(),\n                 [](const State& a, const State& b) { return a.score > b.score; });\n            \n            beam.clear();\n            for (int k = 0; k < min((int)candidates.size(), BEAM_WIDTH); k++) {\n                beam.push_back(candidates[k]);\n                \n                if (candidates[k].score > best_score) {\n                    best_score = candidates[k].score;\n                    best_path = candidates[k].path;\n                }\n            }\n        }\n    }\n    \n    int find_direction(int ci, int cj, int ni, int nj) {\n        for (int d = 0; d < 4; d++) {\n            if (ci + di[d] == ni && cj + dj[d] == nj) return d;\n        }\n        return 0;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    string result = solver.solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nstruct Edge {\n    int from_row, from_col, to_row, to_col;\n    double mean;\n    int count;\n};\n\nstruct Graph {\n    vector<Edge> edges;\n    vector<vector<int>> adj;\n    \n    Graph() {\n        adj.resize(N * N);\n        \n        // Horizontal edges\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                Edge e = {i, j, i, j+1, 5000.0, 0};\n                edges.push_back(e);\n                adj[u].push_back((int)edges.size() - 1);\n                adj[v].push_back((int)edges.size() - 1);\n            }\n        }\n        \n        // Vertical edges\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                int u = i * N + j;\n                int v = (i+1) * N + j;\n                edges.push_back({i, j, i+1, j, 5000.0, 0});\n                adj[u].push_back((int)edges.size() - 1);\n                adj[v].push_back((int)edges.size() - 1);\n            }\n        }\n    }\n    \n    string get_path_str(int si, int sj, int ti, int tj, vector<int>& used_edges) {\n        // Dijkstra\n        vector<double> dist(N*N, 1e18);\n        vector<int> prev(N*N, -1);\n        vector<int> prev_edge(N*N, -1);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<>> pq;\n        \n        int s = si * N + sj;\n        int t = ti * N + tj;\n        dist[s] = 0;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == t) break;\n            \n            int ui = u / N, uj = u % N;\n            for (int eid : adj[u]) {\n                auto& e = edges[eid];\n                int v = (e.from_row == ui && e.from_col == uj) \n                       ? e.to_row * N + e.to_col \n                       : e.from_row * N + e.from_col;\n                double nd = d + e.mean;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_edge[v] = eid;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        // Reconstruct path\n        string path;\n        used_edges.clear();\n        \n        int cur = t;\n        while (cur != s) {\n            int eid = prev_edge[cur];\n            used_edges.push_back(eid);\n            cur = prev[cur];\n        }\n        reverse(used_edges.begin(), used_edges.end());\n        \n        // Convert to direction string\n        int ci = si, cj = sj;\n        for (int eid : used_edges) {\n            auto& e = edges[eid];\n            int ni, nj;\n            if (e.from_row == ci && e.from_col == cj) {\n                ni = e.to_row; nj = e.to_col;\n            } else {\n                ni = e.from_row; nj = e.from_col;\n            }\n            \n            if (ni < ci) path += 'U';\n            else if (ni > ci) path += 'D';\n            else if (nj < cj) path += 'L';\n            else path += 'R';\n            \n            ci = ni; cj = nj;\n        }\n        \n        return path;\n    }\n    \n    void update_edges(const vector<int>& used_edges, double observed_length) {\n        double predicted = 0;\n        for (int eid : used_edges) predicted += edges[eid].mean;\n        \n        double error = observed_length - predicted;\n        double per_edge = error / used_edges.size();\n        \n        for (int eid : used_edges) {\n            edges[eid].count++;\n            double alpha = 0.3 / (1 + edges[eid].count * 0.01);\n            edges[eid].mean += alpha * per_edge;\n            edges[eid].mean = max(100.0, min(20000.0, edges[eid].mean));\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Graph g;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        vector<int> used_edges;\n        string path = g.get_path_str(si, sj, ti, tj, used_edges);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        double observed;\n        cin >> observed;\n        \n        g.update_edges(used_edges, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next() {\n        x ^= x << 7;\n        return x ^= x >> 9;\n    }\n    int rand_int(int l, int r) {\n        return l + (int)(next() % (r - l + 1));\n    }\n    double rand_double() {\n        return (double)next() / UINT64_MAX;\n    }\n};\n\nstruct Solver {\n    int N, M;\n    vector<string>& strings;\n    vector<string> ans;\n    XorShift rng;\n    \n    // Store string data for fast access\n    vector<vector<char>> str_data;\n    vector<int> str_len;\n    \n    Solver(int n, int m, vector<string>& s) : N(n), M(m), strings(s) {\n        ans.assign(N, string(N, '.'));\n        str_data.resize(M);\n        str_len.resize(M);\n        for (int i = 0; i < M; i++) {\n            str_len[i] = strings[i].size();\n            str_data[i] = vector<char>(strings[i].begin(), strings[i].end());\n        }\n    }\n    \n    // Fast string matching using precomputed positions\n    bool try_match(const string& str, int start_r, int start_c, bool horizontal) {\n        int len = str.size();\n        if (horizontal) {\n            for (int p = 0; p < len; p++) {\n                int c = (start_c + p) % N;\n                if (ans[start_r][c] != '.' && ans[start_r][c] != str[p]) return false;\n            }\n            return true;\n        } else {\n            for (int p = 0; p < len; p++) {\n                int r = (start_r + p) % N;\n                if (ans[r][start_c] != '.' && ans[r][start_c] != str[p]) return false;\n            }\n            return true;\n        }\n    }\n    \n    void apply_match(const string& str, int start_r, int start_c, bool horizontal) {\n        int len = str.size();\n        if (horizontal) {\n            for (int p = 0; p < len; p++) {\n                int c = (start_c + p) % N;\n                if (ans[start_r][c] == '.') ans[start_r][c] = str[p];\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                int r = (start_r + p) % N;\n                if (ans[r][start_c] == '.') ans[r][start_c] = str[p];\n            }\n        }\n    }\n    \n    // Fast subsequence check using bitset representation\n    bool is_subsequence_fast(const string& str, int idx) {\n        int len = str_len[idx];\n        char first = str[0];\n        \n        // Check horizontal: use precomputed positions per row\n        for (int r = 0; r < N; r++) {\n            // Find positions where first character matches\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] != first) continue;\n                \n                bool ok = true;\n                for (int p = 1; p < len; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) return true;\n            }\n        }\n        \n        // Check vertical\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] != first) continue;\n                \n                bool ok = true;\n                for (int p = 1; p < len; p++) {\n                    int nr = (r + p) % N;\n                    if (ans[nr][c] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) return true;\n            }\n        }\n        return false;\n    }\n    \n    // Place all strings greedily in one pass\n    void greedy_place() {\n        // Sort by length descending, then by first character frequency\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            if (str_len[a] != str_len[b]) return str_len[a] > str_len[b];\n            return strings[a] < strings[b];\n        });\n        \n        vector<bool> placed(M, false);\n        \n        // First pass: try to place without conflicts\n        for (int idx : order) {\n            string& str = strings[idx];\n            int len = str_len[idx];\n            \n            bool found = false;\n            // Try all possible positions\n            for (int r = 0; r < N && !found; r++) {\n                for (int c = 0; c < N && !found; c++) {\n                    // Try horizontal\n                    if (try_match(str, r, c, true)) {\n                        bool already_matched = false;\n                        // Check if this would create a longer existing match\n                        apply_match(str, r, c, true);\n                        found = true;\n                        placed[idx] = true;\n                    }\n                    \n                    if (!found && try_match(str, r, c, false)) {\n                        apply_match(str, r, c, false);\n                        found = true;\n                        placed[idx] = true;\n                    }\n                }\n            }\n            \n            if (!found) {\n                // Force place with minimal damage\n                int best_score = 1000;\n                int best_r = 0, best_c = 0;\n                bool best_hor = true;\n                \n                for (int r = 0; r < N; r++) {\n                    for (int c = 0; c < N; c++) {\n                        // Horizontal score\n                        int h_score = 0;\n                        for (int p = 0; p < len; p++) {\n                            int nc = (c + p) % N;\n                            if (ans[r][nc] != '.' && ans[r][nc] != str[p]) h_score++;\n                        }\n                        if (h_score < best_score) {\n                            best_score = h_score;\n                            best_r = r;\n                            best_c = c;\n                            best_hor = true;\n                        }\n                        \n                        // Vertical score\n                        int v_score = 0;\n                        for (int p = 0; p < len; p++) {\n                            int nr = (r + p) % N;\n                            if (ans[nr][c] != '.' && ans[nr][c] != str[p]) v_score++;\n                        }\n                        if (v_score < best_score) {\n                            best_score = v_score;\n                            best_r = r;\n                            best_c = c;\n                            best_hor = false;\n                        }\n                    }\n                }\n                \n                if (best_hor) {\n                    for (int p = 0; p < len; p++) {\n                        int nc = (best_c + p) % N;\n                        ans[best_r][nc] = str[p];\n                    }\n                } else {\n                    for (int p = 0; p < len; p++) {\n                        int nr = (best_r + p) % N;\n                        ans[nr][best_c] = str[p];\n                    }\n                }\n                placed[idx] = true;\n            }\n        }\n    }\n    \n    // Fill remaining cells based on simple frequency analysis\n    void fill_remaining() {\n        // Count character occurrences in unmatched strings\n        vector<int> total_freq(8, 0);\n        for (int i = 0; i < M; i++) {\n            for (char c : strings[i]) {\n                total_freq[c - 'A']++;\n            }\n        }\n        \n        // Create character ranking\n        vector<pair<int,int>> ranking;\n        for (int k = 0; k < 8; k++) {\n            ranking.push_back({total_freq[k], k});\n        }\n        sort(ranking.rbegin(), ranking.rend());\n        \n        vector<char> preferred_chars;\n        for (auto [freq, ch] : ranking) {\n            preferred_chars.push_back('A' + ch);\n        }\n        \n        // Fill cells preferring most common characters\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] == '.') {\n                    // Try characters in order of frequency\n                    for (char ch : preferred_chars) {\n                        ans[r][c] = ch;\n                        break; // Just use most frequent\n                    }\n                }\n            }\n        }\n    }\n    \n    // Quick optimization pass\n    void optimize() {\n        // Simple single-pass optimization\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                char old = ans[r][c];\n                bool improved = false;\n                \n                // Try all 8 characters\n                for (char ch = 'A'; ch <= 'H' && !improved; ch++) {\n                    if (ch == old) continue;\n                    ans[r][c] = ch;\n                    \n                    // Quick check: count how many additional strings would match\n                    // Only check if any string that didn't match before now matches\n                    for (int i = 0; i < M; i++) {\n                        if (is_subsequence_fast(strings[i], i)) {\n                            improved = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!improved) {\n                    ans[r][c] = old;\n                }\n            }\n        }\n    }\n    \n    void solve() {\n        // Fast greedy construction\n        greedy_place();\n        \n        // Fill remaining\n        fill_remaining();\n        \n        // One quick optimization pass (only if time permits)\n        // Actually skip this to ensure time limit\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Solver solver(N, M, strings);\n    solver.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << solver.ans[i] << endl;\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\n\nint N, si, sj;\nvector<string> c;\nvector<vector<int>> dist;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nvoid bfsDist(int si, int sj) {\n    dist.assign(N, vector<int>(N, 1e9));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si,sj});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        for (int d=0; d<4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && dist[ni][nj] > dist[i][j]+1) {\n                dist[ni][nj] = dist[i][j]+1;\n                q.push({ni,nj});\n            }\n        }\n    }\n}\n\nvector<vector<vector<pair<int,int>>>> visible;\n\nvoid precomputeVisible() {\n    visible.assign(N, vector<vector<pair<int,int>>>(N));\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        for (int nj=j-1; nj>=0 && c[i][nj]!='#'; nj--) visible[i][j].push_back({i,nj});\n        for (int nj=j+1; nj<N && c[i][nj]!='#'; nj++) visible[i][j].push_back({i,nj});\n        for (int ni=i-1; ni>=0 && c[ni][j]!='#'; ni--) visible[i][j].push_back({ni,j});\n        for (int ni=i+1; ni<N && c[ni][j]!='#'; ni++) visible[i][j].push_back({ni,j});\n    }\n}\n\nstring pathBetween(int i1, int j1, int i2, int j2) {\n    if (i1==i2 && j1==j2) return \"\";\n    vector<vector<int>> d(N, vector<int>(N, 1e9));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    d[i1][j1] = 0;\n    q.push({i1,j1});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i==i2 && j==j2) break;\n        for (int dir=0; dir<4; dir++) {\n            int ni = i+di[dir], nj = j+dj[dir];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && d[ni][nj] > d[i][j]+1) {\n                d[ni][nj] = d[i][j]+1;\n                prev[ni][nj] = {i,j};\n                q.push({ni,nj});\n            }\n        }\n    }\n    if (d[i2][j2]==1e9) return \"\"; // should not happen\n    string path;\n    int ci = i2, cj = j2;\n    while (!(ci==i1 && cj==j1)) {\n        auto [pi,pj] = prev[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 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 >> N >> si >> sj;\n    c.resize(N);\n    for (int i=0; i<N; i++) cin >> c[i];\n    \n    precomputeVisible();\n    \n    vector<vector<bool>> seen(N, vector<bool>(N, false));\n    seen[si][sj] = true;\n    for (auto [vi,vj] : visible[si][sj]) seen[vi][vj] = true;\n    \n    int cur_i = si, cur_j = sj;\n    string ans;\n    int uncovered = 0;\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) uncovered++;\n    \n    while (uncovered > 0) {\n        bfsDist(cur_i, cur_j); // distances from current position\n        int bestDist = 1e9, bestI = -1, bestJ = -1;\n        for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n            if (c[i][j]!='#' && !seen[i][j] && dist[i][j] < bestDist) {\n                bestDist = dist[i][j];\n                bestI = i; bestJ = j;\n            }\n        }\n        if (bestI==-1) break; // shouldn't happen\n        string subPath = pathBetween(cur_i, cur_j, bestI, bestJ);\n        ans += subPath;\n        cur_i = bestI; cur_j = bestJ;\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) {\n            if (!seen[vi][vj]) {\n                seen[vi][vj] = true;\n                uncovered--;\n            }\n        }\n    }\n    \n    // verify coverage\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) {\n        // fallback: move to it directly\n        bfsDist(cur_i, cur_j);\n        int bestDist = 1e9, bestI = -1, bestJ = -1;\n        for (int ii=0; ii<N; ii++) for (int jj=0; jj<N; jj++) {\n            if (c[ii][jj]!='#' && !seen[ii][jj] && dist[ii][jj] < bestDist) {\n                bestDist = dist[ii][jj];\n                bestI = ii; bestJ = jj;\n            }\n        }\n        if (bestI==-1) break;\n        string subPath = pathBetween(cur_i, cur_j, bestI, bestJ);\n        ans += subPath;\n        cur_i = bestI; cur_j = bestJ;\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) {\n            if (!seen[vi][vj]) {\n                seen[vi][vj] = true;\n            }\n        }\n    }\n    \n    string back = pathBetween(cur_i, cur_j, si, sj);\n    ans += back;\n    \n    cout << ans << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast I/O\nstruct FastIO {\n    FastIO() {\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cout.tie(nullptr);\n    }\n} fastio;\n\n// Utility for random\nstruct XorShift {\n    uint64_t x;\n    XorShift() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t rand() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint32_t rand(uint32_t range) {\n        return rand() % range;\n    }\n    double uniform() {\n        return (double)rand() / UINT32_MAX;\n    }\n    double normal() {\n        double u1 = uniform(), u2 = uniform();\n        return sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);\n    }\n} rng;\n\n// 2D vector type\nusing Vec = vector<int>;\n\n// Main solver\nstruct Solver {\n    int N, M, K, R;\n    vector<Vec> task_diff; // task difficulties\n    vector<vector<int>> deps; // dependencies\n    vector<Vec> workers_skills_est; // estimated worker skills\n    vector<vector<double>> skill_mean; // mean of skill estimates\n    vector<vector<double>> skill_var; // variance of skill estimates\n    \n    // State\n    vector<int> task_status; // 0=not started, 1=running, 2=done\n    vector<int> worker_busy_until; // day when worker becomes free\n    vector<int> worker_task; // task assigned to worker (-1 if none)\n    int current_day;\n    \n    // History for learning\n    struct Observation {\n        int worker;\n        int task;\n        int duration;\n        Vec task_diff;\n    };\n    vector<Observation> history;\n    \n    Solver() {\n        read_input();\n        init();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> K >> R;\n        task_diff.resize(N, Vec(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                cin >> task_diff[i][j];\n            }\n        }\n        deps.resize(N);\n        for (int i = 0; i < R; i++) {\n            int u, v;\n            cin >> u >> v;\n            u--; v--;\n            deps[v].push_back(u);\n        }\n    }\n    \n    void init() {\n        // Initialize skill estimates with reasonable values\n        workers_skills_est.assign(M, Vec(K, 0));\n        skill_mean.assign(M, vector<double>(K, 30.0));\n        skill_var.assign(M, vector<double>(K, 100.0));\n        \n        task_status.assign(N, 0);\n        worker_busy_until.assign(M, 0);\n        worker_task.assign(M, -1);\n        current_day = 1;\n    }\n    \n    bool can_start(int task) {\n        if (task_status[task] != 0) return false;\n        for (int dep : deps[task]) {\n            if (task_status[dep] != 2) return false;\n        }\n        return true;\n    }\n    \n    double expected_duration(int worker, int task) {\n        double w = 0;\n        for (int k = 0; k < K; k++) {\n            w += max(0, task_diff[task][k] - (int)round(workers_skills_est[worker][k]));\n        }\n        return max(1.0, w + 1); // conservative estimate\n    }\n    \n    int find_best_worker(int task) {\n        int best_worker = -1;\n        double best_time = 1e9;\n        vector<int> available;\n        for (int w = 0; w < M; w++) {\n            if (worker_busy_until[w] <= current_day) {\n                available.push_back(w);\n            }\n        }\n        if (available.empty()) return -1;\n        \n        for (int w : available) {\n            double dur = expected_duration(w, task);\n            // Add explore bonus for uncertain skills\n            double uncertainty = 0;\n            for (int k = 0; k < K; k++) {\n                uncertainty += skill_var[w][k];\n            }\n            uncertainty = sqrt(uncertainty / K);\n            dur -= 0.5 * uncertainty; // prefer exploring uncertain workers\n            \n            if (dur < best_time) {\n                best_time = dur;\n                best_worker = w;\n            }\n        }\n        return best_worker;\n    }\n    \n    void update_skills(Observation& obs) {\n        // Simple gradient descent to update skill estimates\n        double learning_rate = 0.1;\n        int actual_dur = obs.duration;\n        Vec& d = obs.task_diff;\n        int w = obs.worker;\n        \n        // Compute predicted w\n        double pred_w = 0;\n        for (int k = 0; k < K; k++) {\n            pred_w += max(0, d[k] - workers_skills_est[w][k]);\n        }\n        \n        // Update if actual duration gives information\n        if (actual_dur > 1) {\n            // The actual w (without noise) is around actual_dur - random(-3 to 3)\n            // We'll use a simple update rule\n            for (int k = 0; k < K; k++) {\n                if (d[k] > workers_skills_est[w][k]) {\n                    // This skill might be lower than estimated\n                    workers_skills_est[w][k] = max(0, workers_skills_est[w][k] + \n                        (int)(learning_rate * (d[k] - workers_skills_est[w][k]) * (actual_dur - 1) / (pred_w + 1)));\n                }\n            }\n        } else {\n            // Task was easy, worker likely has sufficient skills\n            for (int k = 0; k < K; k++) {\n                workers_skills_est[w][k] = max(workers_skills_est[w][k], d[k]);\n            }\n        }\n    }\n    \n    void solve() {\n        while (true) {\n            // Update worker states from previous day's completions\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            stringstream ss(line);\n            int first;\n            ss >> first;\n            \n            if (first == -1) {\n                // End of simulation\n                return;\n            }\n            \n            // Process completed tasks\n            int n_completed = first;\n            for (int i = 0; i < n_completed; i++) {\n                int worker;\n                ss >> worker;\n                worker--;\n                int task = worker_task[worker];\n                if (task >= 0) {\n                    task_status[task] = 2; // completed\n                    int duration = current_day - (worker_busy_until[worker] - 1);\n                    \n                    Observation obs;\n                    obs.worker = worker;\n                    obs.task = task;\n                    obs.duration = duration;\n                    obs.task_diff = task_diff[task];\n                    history.push_back(obs);\n                    \n                    // Update skill estimates\n                    update_skills(obs);\n                    \n                    worker_task[worker] = -1;\n                    worker_busy_until[worker] = current_day; // free now\n                }\n            }\n            \n            // Find tasks that can be started\n            vector<int> available_tasks;\n            for (int t = 0; t < N; t++) {\n                if (can_start(t)) {\n                    available_tasks.push_back(t);\n                }\n            }\n            \n            // Assign workers to tasks\n            vector<pair<int, int>> assignments;\n            \n            // Sort tasks by priority (e.g., by number of descendants)\n            sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n                return deps[a].size() > deps[b].size();\n            });\n            \n            for (int task : available_tasks) {\n                if (assignments.size() >= M) break;\n                \n                int worker = find_best_worker(task);\n                if (worker >= 0) {\n                    assignments.push_back({worker, task});\n                    worker_task[worker] = task;\n                    task_status[task] = 1; // started\n                    \n                    // Estimate completion time for next day update\n                    double est_dur = expected_duration(worker, task);\n                    worker_busy_until[worker] = current_day + (int)ceil(est_dur);\n                }\n            }\n            \n            // Output assignments\n            cout << assignments.size();\n            for (auto& p : assignments) {\n                cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n            }\n            cout << endl;\n            cout.flush();\n            \n            current_day++;\n            \n            if (current_day > 2000) {\n                // Read remaining input and exit\n                while (true) {\n                    getline(cin, line);\n                    if (line == \"-1\") break;\n                }\n                return;\n            }\n        }\n    }\n};\n\nint main() {\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nconst int DEPOT_X = 400, DEPOT_Y = 400;\nconst int N_ORDERS = 1000;\nconst int PICK = 50;\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nstruct Order {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> orders(N_ORDERS);\n    for (int i = 0; i < N_ORDERS; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Select 50 orders\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < N_ORDERS; ++i) {\n        int rt = manhattan(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b)\n               + manhattan(orders[i].a, orders[i].b, orders[i].c, orders[i].d)\n               + manhattan(orders[i].c, orders[i].d, DEPOT_X, DEPOT_Y);\n        candidates.emplace_back(rt, i);\n    }\n    sort(candidates.begin(), candidates.end());\n    \n    vector<int> selectedIdx(PICK);\n    for (int i = 0; i < PICK; ++i) {\n        selectedIdx[i] = candidates[i].second;\n    }\n\n    // Build nodes: restaurant then destination for each selected order\n    struct Node {\n        int x, y;\n        int orderIdx; // index in selectedIdx (0..PICK-1)\n        bool isRestaurant;\n    };\n    vector<Node> nodes(2 * PICK);\n    for (int i = 0; i < PICK; ++i) {\n        int o = selectedIdx[i];\n        nodes[2*i] = {orders[o].a, orders[o].b, i, true};\n        nodes[2*i+1] = {orders[o].c, orders[o].d, i, false};\n    }\n\n    // Build valid initial route: all restaurants first, then all destinations\n    vector<int> route(2 * PICK);\n    for (int i = 0; i < PICK; ++i) route[i] = 2*i;          // restaurants\n    for (int i = 0; i < PICK; ++i) route[PICK + i] = 2*i+1; // destinations\n    \n    // Shuffle within restaurant group and destination group\n    shuffle(route.begin(), route.begin() + PICK, rng);\n    shuffle(route.begin() + PICK, route.end(), rng);\n\n    auto calcDist = [&](const vector<int>& r) {\n        int total = manhattan(DEPOT_X, DEPOT_Y, nodes[r[0]].x, nodes[r[0]].y);\n        for (int i = 0; i < 2*PICK - 1; ++i) {\n            total += manhattan(nodes[r[i]].x, nodes[r[i]].y, nodes[r[i+1]].x, nodes[r[i+1]].y);\n        }\n        total += manhattan(nodes[r[2*PICK-1]].x, nodes[r[2*PICK-1]].y, DEPOT_X, DEPOT_Y);\n        return total;\n    };\n\n    // Validate that all orders are properly completed\n    auto isValid = [&](const vector<int>& r) {\n        vector<int> restPos(PICK, -1), destPos(PICK, -1);\n        for (int i = 0; i < 2*PICK; ++i) {\n            if (nodes[r[i]].isRestaurant) restPos[nodes[r[i]].orderIdx] = i;\n            else destPos[nodes[r[i]].orderIdx] = i;\n        }\n        for (int i = 0; i < PICK; ++i) {\n            if (restPos[i] == -1 || destPos[i] == -1) return false;\n            if (restPos[i] >= destPos[i]) return false;\n        }\n        return true;\n    };\n\n    // Always valid because each order has restaurant before destination\n    assert(isValid(route));\n\n    int bestT = calcDist(route);\n    vector<int> bestRoute = route;\n\n    // 2-opt local search with strict precedence preservation\n    for (int restart = 0; restart < 5; ++restart) {\n        // Shuffle but keep restaurants before destinations\n        shuffle(route.begin(), route.begin() + PICK, rng);\n        shuffle(route.begin() + PICK, route.end(), rng);\n        \n        int curT = calcDist(route);\n        bool improved = true;\n        \n        while (improved) {\n            improved = false;\n            for (int i = 0; i < 2*PICK - 1; ++i) {\n                for (int j = i + 1; j < 2*PICK; ++j) {\n                    // Strict check: reversal cannot put any destination before its restaurant\n                    bool ok = true;\n                    for (int k = i; k <= j; ++k) {\n                        int other = j - (k - i);\n                        if (nodes[route[k]].isRestaurant && !nodes[route[other]].isRestaurant) {\n                            // Restaurant moving to destination's old position\n                            // Check if its destination is also in segment\n                            auto& rnode = nodes[route[k]];\n                            auto& dnode = nodes[route[other]];\n                            if (rnode.orderIdx == dnode.orderIdx) { ok = false; break; }\n                        } else if (!nodes[route[k]].isRestaurant && nodes[route[other]].isRestaurant) {\n                            // Destination moving to restaurant's old position\n                            auto& dnode = nodes[route[k]];\n                            auto& rnode = nodes[route[other]];\n                            if (dnode.orderIdx == rnode.orderIdx) { ok = false; break; }\n                        }\n                    }\n                    if (!ok) continue;\n                    \n                    // Compute delta distance\n                    int oldDist = 0, newDist = 0;\n                    if (i > 0) {\n                        oldDist += manhattan(nodes[route[i-1]].x, nodes[route[i-1]].y, nodes[route[i]].x, nodes[route[i]].y);\n                        newDist += manhattan(nodes[route[i-1]].x, nodes[route[i-1]].y, nodes[route[j]].x, nodes[route[j]].y);\n                    }\n                    if (j < 2*PICK - 1) {\n                        oldDist += manhattan(nodes[route[j]].x, nodes[route[j]].y, nodes[route[j+1]].x, nodes[route[j+1]].y);\n                        newDist += manhattan(nodes[route[i]].x, nodes[route[i]].y, nodes[route[j+1]].x, nodes[route[j+1]].y);\n                    }\n                    \n                    if (curT - oldDist + newDist >= curT) continue;\n                    \n                    // Apply reversal\n                    reverse(route.begin() + i, route.begin() + j + 1);\n                    curT = curT - oldDist + newDist;\n                    improved = true;\n                    break; // Only one improvement per iteration\n                }\n                if (improved) break;\n            }\n        }\n        \n        if (curT < bestT) {\n            bestT = curT;\n            bestRoute = route;\n        }\n    }\n\n    // Final validation\n    if (!isValid(bestRoute)) {\n        // Fallback: simple route with all restaurants first\n        bestRoute.resize(2*PICK);\n        for (int i = 0; i < PICK; ++i) bestRoute[i] = 2*i;\n        for (int i = 0; i < PICK; ++i) bestRoute[PICK + i] = 2*i+1;\n    }\n\n    // Output\n    cout << PICK;\n    for (int idx : selectedIdx) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n    \n    cout << 2*PICK + 2 << \" \" << DEPOT_X << \" \" << DEPOT_Y;\n    for (int idx : bestRoute) cout << \" \" << nodes[idx].x << \" \" << nodes[idx].y;\n    cout << \" \" << DEPOT_X << \" \" << DEPOT_Y << \"\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Edge {\n    int u, v;\n    double expected_cost;  // Using d_i as expected (middle of range)\n    double d;             // exact Euclidean distance (rounded)\n    int idx;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    int N = 400;\n    int M = 1995;\n    \n    vector<pair<int,int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    vector<tuple<int,int,int>> edges; // u, v, idx\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v, i});\n    }\n    \n    // Precompute Euclidean distances\n    vector<double> dist(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    // Initialize DSU and track adopted edges\n    dsu dsu(N);\n    vector<bool> adopted(M, false);\n    \n    // Process edges one by one\n    for (int i = 0; i < M; i++) {\n        int u, v, idx;\n        tie(u, v, idx) = edges[i];\n        \n        // Read actual cost\n        long long actual_cost;\n        cin >> actual_cost;\n        \n        // Check if already connected (skip if so)\n        if (dsu.same(u, v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        // Decision logic:\n        // If actual cost is close to minimum (<= 1.5 * d_i), take it\n        // Otherwise, check if we can get cheaper option later\n        double d = dist[i];\n        double ratio = actual_cost / d;\n        \n        // Use expected minimum cost for future edges\n        // Edges from MST construction tend to have lower costs\n        if (ratio <= 1.5) {\n            // Good deal, take it\n            adopted[i] = true;\n            dsu.merge(u, v);\n            cout << 1 << endl;\n        } else {\n            // Check if there are still many cheap edges available\n            // For edges later in sequence, be more aggressive\n            // For edges early on, be more conservative\n            double threshold = 1.5 + 0.3 * (i / (double)M);\n            \n            // Also consider: if we haven't added many edges, be more conservative\n            int adopted_count = 0;\n            for (int j = 0; j < i; j++) {\n                if (adopted[j]) adopted_count++;\n            }\n            threshold -= 0.1 * (adopted_count / (double)(N/2));\n            \n            if (ratio <= threshold) {\n                adopted[i] = true;\n                dsu.merge(u, v);\n                cout << 1 << endl;\n            } else {\n                cout << 0 << endl;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int SIZE = 30;\nconst int TURNS = 300;\nconst int INF = 1e9;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Position& other) const {\n        return !(*this == other);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;\n    vector<vector<bool>> wall;  // true if impassable\n    vector<vector<int>> humanNext;  // -1 if no human moving there, otherwise human index\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char moveChar[4] = {'U', 'D', 'L', 'R'};\n    const char wallChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool isPassable(int x, int y) {\n        if (!isValid(x, y)) return false;\n        if (wall[x][y]) return false;\n        return true;\n    }\n    \n    bool hasPet(int x, int y) {\n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return true;\n        }\n        return false;\n    }\n    \n    // Check if a wall can be placed at (x, y)\n    bool canPlaceWall(int x, int y, const vector<Position>& currentHumanPos) {\n        if (!isValid(x, y) || wall[x][y]) return false;\n        \n        // Can't place wall on squares containing pets or humans at start of turn\n        if (hasPet(x, y)) return false;\n        for (const auto& h : currentHumanPos) {\n            if (h.x == x && h.y == y) return false;\n        }\n        \n        // Can't place wall adjacent to a pet\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && hasPet(nx, ny)) {\n                return false;\n            }\n        }\n        \n        return true;\n    }\n    \n    // BFS to find nearest wall position to build\n    Position findNearestWallToBuild(int humanIdx, const vector<Position>& currentHumanPos) {\n        auto& human = currentHumanPos[humanIdx];\n        queue<Position> q;\n        vector<vector<int>> dist(SIZE, vector<int>(SIZE, INF));\n        vector<vector<Position>> parent(SIZE, vector<Position>(SIZE, {-1, -1}));\n        \n        q.push(human);\n        dist[human.x][human.y] = 0;\n        \n        while (!q.empty()) {\n            auto cur = q.front(); q.pop();\n            \n            // Check if we can place a wall here (from adjacent square)\n            for (int d = 0; d < 4; d++) {\n                int nx = cur.x + dx[d];\n                int ny = cur.y + dy[d];\n                if (canPlaceWall(nx, ny, currentHumanPos)) {\n                    // Found a wall position - reconstruct path or return adjacent\n                    return {nx, ny};\n                }\n            }\n            \n            // Continue BFS\n            for (int d = 0; d < 4; d++) {\n                int nx = cur.x + dx[d];\n                int ny = cur.y + dy[d];\n                if (isPasableForMove(nx, ny, currentHumanPos) && dist[nx][ny] == INF) {\n                    dist[nx][ny] = dist[cur.x][cur.y] + 1;\n                    parent[nx][ny] = cur;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        return {-1, -1};\n    }\n    \n    // Check if a position is passable for movement (considering other humans)\n    bool isPasableForMove(int x, int y, const vector<Position>& currentHumanPos) {\n        if (!isValid(x, y)) return false;\n        if (wall[x][y]) return false;\n        return true;\n    }\n    \n    // Get the next move towards a target\n    char getNextMove(const Position& from, const Position& to, const vector<Position>& currentHumanPos) {\n        if (from == to) return '.';\n        \n        // BFS to find shortest path\n        queue<Position> q;\n        vector<vector<int>> dist(SIZE, vector<int>(SIZE, INF));\n        vector<vector<Position>> prev(SIZE, vector<Position>(SIZE, {-1, -1}));\n        \n        q.push(from);\n        dist[from.x][from.y] = 0;\n        \n        while (!q.empty()) {\n            auto cur = q.front(); q.pop();\n            \n            if (cur == to) break;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cur.x + dx[d];\n                int ny = cur.y + dy[d];\n                if (isPasableForMove(nx, ny, currentHumanPos) && dist[nx][ny] == INF) {\n                    dist[nx][ny] = dist[cur.x][cur.y] + 1;\n                    prev[nx][ny] = cur;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        if (dist[to.x][to.y] == INF) return '.';\n        \n        // Reconstruct path\n        Position cur = to;\n        Position next = to;\n        while (cur != from) {\n            next = cur;\n            cur = prev[cur.x][cur.y];\n        }\n        \n        // Return direction\n        if (next.x < from.x) return 'U';\n        if (next.x > from.x) return 'D';\n        if (next.y < from.y) return 'L';\n        if (next.y > from.y) return 'R';\n        \n        return '.';\n    }\n    \npublic:\n    Solver() {\n        wall = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n    }\n    \n    void readInput() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n            petPos[i].x--;\n            petPos[i].y--;\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n            humanPos[i].x--;\n            humanPos[i].y--;\n        }\n    }\n    \n    void solve() {\n        for (int turn = 0; turn < TURNS; turn++) {\n            string output;\n            vector<Position> currentHumanPos = humanPos;\n            vector<vector<bool>> wallThisTurn = wall;\n            \n            // Strategy: Build a wall around the centroid of all humans\n            // Calculate centroid\n            int cx = 0, cy = 0;\n            for (const auto& h : currentHumanPos) {\n                cx += h.x;\n                cy += h.y;\n            }\n            cx /= M;\n            cy /= M;\n            \n            // Determine which part of the wall each human should build\n            // Humans are assigned to different directions from centroid\n            int humanIdx = 0;\n            for (int i = 0; i < M; i++) {\n                auto& human = humanPos[i];\n                char action = '.';\n                \n                // Find nearest valid wall position to build\n                Position wallTarget = findNearestWallToBuild(i, currentHumanPos);\n                \n                if (wallTarget.x != -1) {\n                    int dist = abs(wallTarget.x - human.x) + abs(wallTarget.y - human.y);\n                    \n                    if (dist == 1) {\n                        // We're adjacent to the wall position, place the wall\n                        for (int d = 0; d < 4; d++) {\n                            if (human.x + dx[d] == wallTarget.x && human.y + dy[d] == wallTarget.y) {\n                                action = wallChar[d];\n                                wallThisTurn[wallTarget.x][wallTarget.y] = true;\n                                break;\n                            }\n                        }\n                    } else {\n                        // Move towards the wall target\n                        action = getNextMove(human, wallTarget, currentHumanPos);\n                    }\n                }\n                \n                // Update human position for this turn\n                Position newPos = human;\n                if (action == 'U') newPos.x--;\n                else if (action == 'D') newPos.x++;\n                else if (action == 'L') newPos.y--;\n                else if (action == 'R') newPos.y++;\n                \n                // Validate the move\n                if (action != '.') {\n                    if (!isPasableForMove(newPos.x, newPos.y, currentHumanPos)) {\n                        // If move is not possible, stay in place\n                        action = '.';\n                    } else {\n                        // Check if another human already plans to move here\n                        bool conflict = false;\n                        for (int j = 0; j < i; j++) {\n                            Position otherNewPos = humanPos[j];\n                            char otherAction = output[j];\n                            if (otherAction == 'U') otherNewPos.x--;\n                            else if (otherAction == 'D') otherNewPos.x++;\n                            else if (otherAction == 'L') otherNewPos.y--;\n                            else if (otherAction == 'R') otherNewPos.y++;\n                            if (otherNewPos == newPos) {\n                                conflict = true;\n                                break;\n                            }\n                        }\n                        if (conflict) {\n                            action = '.';\n                        }\n                    }\n                }\n                \n                output += action;\n                \n                // Update actual position\n                if (action == 'U') humanPos[i].x--;\n                else if (action == 'D') humanPos[i].x++;\n                else if (action == 'L') humanPos[i].y--;\n                else if (action == 'R') humanPos[i].y++;\n            }\n            \n            // Apply walls\n            wall = wallThisTurn;\n            \n            // Output actions\n            cout << output << endl;\n            cout.flush();\n            \n            // Read pet movements - they come as space-separated strings on one line\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            // Parse pet movements\n            vector<string> petMovements(N);\n            stringstream ss(line);\n            for (int i = 0; i < N; i++) {\n                ss >> petMovements[i];\n            }\n            \n            // Update pet positions based on their movements\n            for (int i = 0; i < N; i++) {\n                for (char c : petMovements[i]) {\n                    if (c == 'U') petPos[i].x--;\n                    else if (c == 'D') petPos[i].x++;\n                    else if (c == 'L') petPos[i].y--;\n                    else if (c == 'R') petPos[i].y++;\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.readInput();\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> h, v;\n    \n    bool canMove(int i, int j, int d) const {\n        if (d == 0 && i > 0 && !v[i-1][j]) return true;\n        if (d == 1 && i < 19 && !v[i][j]) return true;\n        if (d == 2 && j > 0 && !h[i][j-1]) return true;\n        if (d == 3 && j < 19 && !h[i][j]) return true;\n        return false;\n    }\n};\n\n// DP for expected score calculation (exact)\ndouble calculateExpectedScore(const string& s, int si, int sj, int ti, int tj,\n                             const Grid& grid, double p) {\n    int L = min((int)s.size(), 400);\n    vector<vector<double>> dp(20, vector<double>(20, 0.0));\n    dp[si][sj] = 1.0;\n    double expected = 0.0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n    \n    for (int step = 0; step < L; ++step) {\n        vector<vector<double>> ndp(20, vector<double>(20, 0.0));\n        \n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (dp[i][j] < 1e-12) continue;\n                if (i == ti && j == tj) {\n                    expected += dp[i][j] * (401.0 - step);\n                    continue;\n                }\n                \n                // Forget with probability p\n                ndp[i][j] += dp[i][j] * p;\n                \n                // Try to move\n                int d = 0;\n                for (; d < 4; ++d) if (s[step] == dirs[d]) break;\n                if (grid.canMove(i, j, d)) {\n                    ndp[i+di[d]][j+dj[d]] += dp[i][j] * (1.0 - p);\n                } else {\n                    ndp[i][j] += dp[i][j] * (1.0 - p);\n                }\n            }\n        }\n        dp = ndp;\n    }\n    \n    // Add remaining probability at goal\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            if (i == ti && j == tj) {\n                expected += dp[i][j] * 1.0; // Score for reaching exactly at end\n            }\n        }\n    }\n    \n    return expected;\n}\n\n// Generate multiple candidate paths using different strategies\nvector<string> generateCandidates(int si, int sj, int ti, int tj,\n                                  const Grid& grid, double p) {\n    vector<string> candidates;\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dir_char[] = {'U', 'D', 'L', 'R'};\n    \n    // BFS for shortest path\n    vector<vector<int>> dist(20, vector<int>(20, 1e9));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    \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            if (!grid.canMove(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    // Reconstruct shortest path\n    vector<char> path;\n    int ci = ti, cj = tj;\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        if (pi == ci - 1) path.push_back('D');\n        else if (pi == ci + 1) path.push_back('U');\n        else if (pj == cj - 1) path.push_back('R');\n        else path.push_back('L');\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Strategy 1: Adaptive repeats based on position\n    for (int targetLen = (int)path.size(); targetLen <= 200; targetLen += 10) {\n        string candidate;\n        int remaining = targetLen - (int)path.size();\n        \n        // Compute criticality using DP\n        vector<double> criticality(path.size(), 1.0);\n        \n        // For each position, check how many alternative paths exist\n        for (int skip = 0; skip < (int)path.size(); ++skip) {\n            // Check if we can still reach goal with slightly different path\n            int cx = si, cy = sj;\n            for (int idx = 0; idx < (int)path.size(); ++idx) {\n                if (idx == skip) continue;\n                int d = 0;\n                if (path[idx] == 'U') d = 0;\n                else if (path[idx] == 'D') d = 1;\n                else if (path[idx] == 'L') d = 2;\n                else d = 3;\n                \n                if (grid.canMove(cx, cy, d)) {\n                    cx += di[d]; cy += dj[d];\n                }\n            }\n            // Measure Manhattan distance to goal as proxy for criticality\n            criticality[skip] = abs(cx - ti) + abs(cy - tj) + 1;\n        }\n        \n        // Normalize criticalities\n        double sumCrit = accumulate(criticality.begin(), criticality.end(), 0.0);\n        for (auto& c : criticality) c /= sumCrit;\n        \n        // Build string with adaptive repeats\n        for (int i = 0; i < (int)path.size() && (int)candidate.size() < targetLen; ++i) {\n            candidate.push_back(path[i]);\n            int extra = max(0, min(remaining, (int)(criticality[i] * remaining * 2 + 0.5)));\n            extra = min(extra, (int)(2.0 / (1.0 - p))); // Cap repeats\n            \n            for (int r = 0; r < extra && (int)candidate.size() < targetLen; ++r) {\n                candidate.push_back(path[i]);\n                remaining--;\n            }\n        }\n        \n        while ((int)candidate.size() < targetLen && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        \n        if ((int)candidate.size() <= 200) {\n            candidates.push_back(candidate);\n        }\n    }\n    \n    // Strategy 2: Even repeats\n    int evenRepeat = max(1, (int)(1.0 / (1.0 - p) + 0.5));\n    string evenStr;\n    for (char c : path) {\n        for (int r = 0; r < evenRepeat && (int)evenStr.size() < 200; ++r) {\n            evenStr.push_back(c);\n        }\n        if ((int)evenStr.size() >= 200) break;\n    }\n    candidates.push_back(evenStr);\n    \n    // Strategy 3: More aggressive repeats for high p\n    if (p > 0.3) {\n        string aggressive;\n        int repeat = (int)(1.5 / (1.0 - p) + 0.5);\n        for (char c : path) {\n            for (int r = 0; r < repeat && (int)aggressive.size() < 200; ++r) {\n                aggressive.push_back(c);\n            }\n            if ((int)aggressive.size() >= 200) break;\n        }\n        candidates.push_back(aggressive);\n    }\n    \n    return candidates;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    Grid grid;\n    grid.h.resize(20, vector<int>(19));\n    grid.v.resize(19, vector<int>(20));\n    \n    for (int i = 0; i < 20; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 19; ++j) grid.h[i][j] = s[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 20; ++j) grid.v[i][j] = s[j] - '0';\n    }\n    \n    // Generate candidates and pick the best\n    auto candidates = generateCandidates(si, sj, ti, tj, grid, p);\n    \n    string bestPath;\n    double bestScore = -1.0;\n    \n    for (const auto& candidate : candidates) {\n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Local optimization: try small adjustments\n    for (int iter = 0; iter < 50 && (int)bestPath.size() > 10; ++iter) {\n        int idx = rand() % (int)bestPath.size();\n        string modified = bestPath;\n        modified.erase(modified.begin() + idx);\n        \n        double score = calculateExpectedScore(modified, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = modified;\n        }\n    }\n    \n    // Final truncation\n    if ((int)bestPath.size() > 200) {\n        bestPath.resize(200);\n    }\n    \n    cout << bestPath << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0\n    {3, -1, -1, 0},  // 1\n    {-1, -1, 3, 2},  // 2\n    {-1, 2, 1, -1},  // 3\n    {1, 0, 3, 2},    // 4\n    {3, 2, 1, 0},    // 5\n    {2, -1, 0, -1},  // 6\n    {-1, 3, -1, 1},  // 7\n};\n\nstruct TileGrid {\n    int tiles[30][30];\n    \n    // Fast heuristic: count how many tiles have valid connections on all sides\n    int heuristicScore() const {\n        int score = 0;\n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 30; j++) {\n                int connections = 0;\n                for (int d = 0; d < 4; d++) {\n                    if (to[tiles[i][j]][d] != -1) connections++;\n                }\n                score += connections;\n            }\n        }\n        return score;\n    }\n    \n    // Ultra-fast score estimation - just count loops by looking at 4-tile squares\n    int fastScore() const {\n        int score = 0;\n        // Count potential 4-cycles\n        for (int i = 0; i < 29; i++) {\n            for (int j = 0; j < 29; j++) {\n                // Check if these 4 tiles could form a loop\n                if (hasConnection(i, j, 2) && hasConnection(i, j+1, 0) && // right from (i,j) connects to left of (i,j+1)\n                    hasConnection(i, j, 3) && hasConnection(i+1, j, 1) && // down from (i,j) connects to up of (i+1,j)\n                    hasConnection(i+1, j, 2) && hasConnection(i+1, j+1, 0) && // right from (i+1,j) to left of (i+1,j+1)\n                    hasConnection(i, j+1, 3) && hasConnection(i+1, j+1, 1)) { // down from (i,j+1) to up of (i+1,j+1)\n                    score += 4;\n                }\n            }\n        }\n        return score;\n    }\n    \n    bool hasConnection(int i, int j, int d) const {\n        return to[tiles[i][j]][d] != -1;\n    }\n};\n\n// Efficient single-loop tracer that returns length\nint traceLoop(const int tiles[30][30], int si, int sj, int sd, bool visited[30][30]) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (true) {\n        int d2 = to[tiles[i][j]][d];\n        if (d2 == -1) return 0;\n        \n        i += di[d2];\n        j += dj[d2];\n        if (i < 0 || i >= 30 || j < 0 || j >= 30) return 0;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) {\n            // Mark visited\n            i = si; j = sj; d = sd;\n            for (int k = 0; k < length; k++) {\n                visited[i][j] = true;\n                int d2 = to[tiles[i][j]][d];\n                i += di[d2];\n                j += dj[d2];\n                d = (d2 + 2) % 4;\n            }\n            return length;\n        }\n        \n        if (length > 900) return 0;\n    }\n}\n\n// Compute score once for verification\nlong long computeScore(const int tiles[30][30]) {\n    int L1 = 0, L2 = 0;\n    bool visited[30][30] = {false};\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            if (visited[i][j]) continue;\n            \n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] == -1) continue;\n                \n                int len = traceLoop(tiles, i, j, d, visited);\n                if (len > 0) {\n                    if (len > L1) {\n                        L2 = L1;\n                        L1 = len;\n                    } else if (len > L2) {\n                        L2 = len;\n                    }\n                }\n            }\n            visited[i][j] = true;\n        }\n    }\n    \n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    TileGrid grid;\n    for (int i = 0; i < 30; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 30; j++) {\n            grid.tiles[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Random generator\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> posDist(0, 29);\n    \n    // Start with original configuration\n    TileGrid best = grid;\n    long long bestScore = computeScore(best.tiles);\n    \n    // Even more aggressive optimization - just use heuristic scoring\n    for (int phase = 0; phase < 3; phase++) {\n        TileGrid current = best;\n        \n        // Try random rotations using heuristic\n        for (int iter = 0; iter < 2000; iter++) {\n            int i = posDist(rng);\n            int j = posDist(rng);\n            int oldTile = current.tiles[i][j];\n            \n            // Try all rotations\n            int bestRot = 0;\n            int bestHeuristic = -1;\n            \n            for (int rot = 1; rot <= 3; rot++) {\n                current.tiles[i][j] = (oldTile + rot) % 8;\n                int h = current.heuristicScore() + current.fastScore();\n                if (h > bestHeuristic) {\n                    bestHeuristic = h;\n                    bestRot = rot;\n                }\n            }\n            \n            current.tiles[i][j] = (oldTile + bestRot) % 8;\n            \n            // Periodically check actual score\n            if (iter % 100 == 0) {\n                long long score = computeScore(current.tiles);\n                if (score > bestScore) {\n                    best = current;\n                    bestScore = score;\n                }\n            }\n        }\n        \n        // Final evaluation\n        long long score = computeScore(current.tiles);\n        if (score > bestScore) {\n            best = current;\n            bestScore = score;\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int rot = (best.tiles[i][j] - grid.tiles[i][j] + 8) % 8;\n            cout << (rot % 4);\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Direction mappings\nconst int dy[] = {-1, 1, 0, 0};  // U, D, L, R\nconst int dx[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int rev_dir[] = {1, 0, 3, 2};  // Reverse directions\n\n// Tile bitmasks: L=1, U=2, R=4, D=8\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\n\nint N, T;\nvector<vector<int>> board;\npair<int,int> empty_pos;\n\n// Convert hex char to int\nint hex_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\n// Convert int to hex char\nchar int_to_hex(int v) {\n    if (v < 10) return '0' + v;\n    return 'a' + v - 10;\n}\n\n// Check if position is valid\nbool valid(int y, int x) {\n    return y >= 0 && y < N && x >= 0 && x < N;\n}\n\n// Calculate tree size from current board\nint calc_tree_size(const vector<vector<int>>& b) {\n    int n = N * N - 1;\n    vector<vector<pair<int,int>>> adj(N, vector<pair<int,int>>(N));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    // Build adjacency based on line connections\n    auto get_max_tree = [&](int sy, int sx) -> int {\n        if (b[sy][sx] == 0) return 0;\n        queue<pair<int,int>> q;\n        q.push({sy, sx});\n        visited[sy][sx] = true;\n        int sz = 0;\n        \n        while (!q.empty()) {\n            auto [y, x] = q.front(); q.pop();\n            sz++;\n            int tile = b[y][x];\n            \n            // Up\n            if ((tile & UP) && y > 0 && (b[y-1][x] & DOWN) && !visited[y-1][x]) {\n                visited[y-1][x] = true;\n                q.push({y-1, x});\n            }\n            // Down\n            if ((tile & DOWN) && y < N-1 && (b[y+1][x] & UP) && !visited[y+1][x]) {\n                visited[y+1][x] = true;\n                q.push({y+1, x});\n            }\n            // Left\n            if ((tile & LEFT) && x > 0 && (b[y][x-1] & RIGHT) && !visited[y][x-1]) {\n                visited[y][x-1] = true;\n                q.push({y, x-1});\n            }\n            // Right\n            if ((tile & RIGHT) && x < N-1 && (b[y][x+1] & LEFT) && !visited[y][x+1]) {\n                visited[y][x+1] = true;\n                q.push({y, x+1});\n            }\n        }\n        return sz;\n    };\n    \n    int max_tree = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] != 0 && !visited[i][j]) {\n                int sz = get_max_tree(i, j);\n                max_tree = max(max_tree, sz);\n            }\n        }\n    }\n    return max_tree;\n}\n\n// Find path from empty to target using BFS (always possible on any state)\nstring find_path(int ty, int tx) {\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> dir_used(N, vector<int>(N, -1));\n    \n    queue<pair<int,int>> q;\n    q.push(empty_pos);\n    vis[empty_pos.first][empty_pos.second] = true;\n    \n    while (!q.empty()) {\n        auto [y, x] = q.front(); q.pop();\n        if (y == ty && x == tx) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int ny = y + dy[d], nx = x + dx[d];\n            if (!valid(ny, nx) || vis[ny][nx]) continue;\n            vis[ny][nx] = true;\n            parent[ny][nx] = {y, x};\n            dir_used[ny][nx] = d;\n            q.push({ny, nx});\n        }\n    }\n    \n    // Reconstruct path\n    string path;\n    int cy = ty, cx = tx;\n    while (!(cy == empty_pos.first && cx == empty_pos.second)) {\n        int d = dir_used[cy][cx];\n        path += dir_char[d];\n        auto [py, px] = parent[cy][cx];\n        // The direction from parent to child is the opposite\n        cy = py; cx = px;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Also need to reverse direction because we want to move tiles INTO empty\n    // Actually, we need to move tile at (ty,tx) to empty's position\n    // So we move empty to (ty,tx), which means tiles move in opposite direction\n    string result;\n    for (char c : path) {\n        if (c == 'U') result += 'D';\n        else if (c == 'D') result += 'U';\n        else if (c == 'L') result += 'R';\n        else result += 'L';\n    }\n    \n    return result;\n}\n\n// Apply a move sequence to the board\nvoid apply_moves(const string& moves) {\n    for (char c : moves) {\n        int d;\n        if (c == 'U') d = 0;\n        else if (c == 'D') d = 1;\n        else if (c == 'L') d = 2;\n        else d = 3;\n        \n        int ny = empty_pos.first + dy[d];\n        int nx = empty_pos.second + dx[d];\n        swap(board[empty_pos.first][empty_pos.second], board[ny][nx]);\n        empty_pos = {ny, nx};\n    }\n}\n\n// Main solve function\nstring solve() {\n    // Read input\n    string line;\n    getline(cin, line);\n    stringstream ss(line);\n    ss >> N >> T;\n    \n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string row;\n        getline(cin, row);\n        // Remove spaces if any\n        row.erase(remove(row.begin(), row.end(), ' '), row.end());\n        for (int j = 0; j < N; j++) {\n            board[i][j] = hex_to_int(row[j]);\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n            }\n        }\n    }\n    \n    string result;\n    int max_operations = T;\n    \n    // Strategy: Try to create a spanning tree structure\n    // Since we know a perfect tree is reachable, try to fix problematic connections\n    \n    // First, find current tree size\n    int current_tree = calc_tree_size(board);\n    \n    // If we already have perfect tree, minimal moves\n    if (current_tree == N * N - 1) {\n        return \"\";\n    }\n    \n    // Greedy approach: Try to improve connections\n    // Look for tiles that can be connected but aren't\n    \n    // Simple heuristic: move the empty tile in a pattern to try to create connections\n    // This is a placeholder for more sophisticated algorithms\n    \n    // For now, just do a snake pattern to shuffle tiles\n    for (int round = 0; round < 2 && result.size() < max_operations; round++) {\n        // Snake pattern\n        if (result.size() < max_operations) {\n            // Move right across top row\n            while (empty_pos.second < N-1 && result.size() < max_operations) {\n                result += 'R';\n                apply_moves(\"R\");\n            }\n            while (empty_pos.second > 0 && result.size() < max_operations) {\n                result += 'L';\n                apply_moves(\"L\");\n            }\n            // Move down\n            if (empty_pos.first < N-1 && result.size() < max_operations) {\n                result += 'D';\n                apply_moves(\"D\");\n            }\n        }\n        \n        if (result.size() < max_operations) {\n            // Move left across row\n            while (empty_pos.second > 0 && result.size() < max_operations) {\n                result += 'L';\n                apply_moves(\"L\");\n            }\n            while (empty_pos.second < N-1 && result.size() < max_operations) {\n                result += 'R';\n                apply_moves(\"R\");\n            }\n            if (empty_pos.first < N-1 && result.size() < max_operations) {\n                result += 'D';\n                apply_moves(\"D\");\n            }\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    string answer = solve();\n    cout << answer << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ld = long double;\n\nconst ld PI = acosl(-1.0L);\n\nstruct Point {\n    ll x, y;\n};\n\n// Cross product sign for line through points p1,p2 at point p\nint side(const Point& p1, const Point& p2, const Point& p) {\n    ll dx = p2.x - p1.x;\n    ll dy = p2.y - p1.y;\n    ll cross = dx * (p.y - p1.y) - dy * (p.x - p1.x);\n    if (cross > 0) return 1;\n    if (cross < 0) return -1;\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int i = 1; i <= 10; ++i) cin >> a[i];\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Sort strawberries by polar angle\n    vector<pair<ld, int>> by_angle;\n    for (int i = 0; i < N; ++i) {\n        if (strawberries[i].x == 0 && strawberries[i].y == 0) {\n            by_angle.emplace_back(-PI - 1, i); // center first\n        } else {\n            by_angle.emplace_back(atan2l(strawberries[i].y, strawberries[i].x), i);\n        }\n    }\n    sort(by_angle.begin(), by_angle.end());\n\n    // Build target piece sizes: we want as many pieces of each size d as possible (up to a_d)\n    // We'll process strawberries in order, creating pieces of target sizes\n    vector<int> target_sizes;\n    for (int d = 10; d >= 1; --d) {\n        for (int j = 0; j < a[d]; ++j) {\n            target_sizes.push_back(d);\n        }\n    }\n\n    // We'll use cuts through origin to create sectors\n    // Each sector will contain exactly 'target' strawberries\n    // If we need to discard strawberries, we cut through them\n    vector<pair<Point,Point>> cuts;\n    int cursor = 0;\n    int target_idx = 0;\n    vector<int> piece_counts;\n\n    while (cursor < N && target_idx < (int)target_sizes.size()) {\n        int target = target_sizes[target_idx];\n        // Collect target strawberries for this sector\n        vector<int> sector_indices;\n        int needed = target;\n        \n        // We may need to skip some strawberries (cut through them) if we can't get exact count\n        while (cursor < N && needed > 0) {\n            if (needed == 1) {\n                // We need exactly one more, take it\n                sector_indices.push_back(by_angle[cursor].second);\n                cursor++;\n                needed--;\n            } else if (needed <= (N - cursor)) {\n                // We have enough remaining strawberries, take one\n                sector_indices.push_back(by_angle[cursor].second);\n                cursor++;\n                needed--;\n            } else {\n                // Not enough strawberries left, break\n                break;\n            }\n        }\n\n        if (needed == 0) {\n            // Successfully created a sector with target strawberries\n            piece_counts.push_back(target);\n            // Add a radial cut after this sector (unless it's the last)\n            if (cursor < N) {\n                int last_idx = sector_indices.back();\n                ld angle = by_angle[cursor].first; // angle of next strawberry\n                // Cut through origin at this angle\n                Point p1 = {0, 0};\n                Point p2 = {ll(1e9 * cosl(angle)), ll(1e9 * sinl(angle))};\n                cuts.emplace_back(p1, p2);\n            }\n            target_idx++;\n        } else {\n            // Couldn't get exact count, this strawberry is discarded (cut through it)\n            // Create cut through this strawberry\n            int discard_idx = by_angle[cursor].second;\n            ld angle = by_angle[cursor].first;\n            Point p1 = {0, 0};\n            // Second point in perpendicular direction to cut through the point\n            Point p2 = {strawberries[discard_idx].x + ll(1e9 * cosl(angle + PI/2)),\n                       strawberries[discard_idx].y + ll(1e9 * sinl(angle + PI/2))};\n            cuts.emplace_back(p1, p2);\n            cursor++;\n        }\n    }\n\n    // If we have more cuts available, add some random cuts to improve\n    // But we may not need them - just use what we have\n\n    int k = min((int)cuts.size(), K);\n    cout << k << \"\\n\";\n    for (int i = 0; i < k; ++i) {\n        cout << cuts[i].first.x << \" \" << cuts[i].first.y << \" \"\n             << cuts[i].second.x << \" \" << cuts[i].second.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Point {\n    int x, y;\n    Point(int x=0, int y=0) : x(x), y(y) {}\n};\n\nstruct Rectangle {\n    Point p[4];\n    int weight;\n};\n\nint N, M;\nvector<vector<bool>> hasDot;\nvector<vector<bool>> occupied; // for rectangle perimeters\nint center;\n\n// Precompute weights\nvector<vector<int>> weight;\n\nint get_weight(int x, int y) {\n    return (x-center)*(x-center) + (y-center)*(y-center) + 1;\n}\n\nbool can_place_rectangle(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {\n    // Check if p1 is empty\n    if (hasDot[p1.x][p1.y]) return false;\n    \n    // Check if p2, p3, p4 have dots\n    if (!hasDot[p2.x][p2.y] || !hasDot[p3.x][p3.y] || !hasDot[p4.x][p4.y]) return false;\n    \n    // Check condition 2: no other dots on perimeter\n    // Simplified check for axis-aligned rectangles\n    auto check_line = [&](int x1, int y1, int x2, int y2) {\n        if (x1 == x2) {\n            for (int y = min(y1,y2); y <= max(y1,y2); y++) {\n                if (hasDot[x1][y] && !(Point(x1,y) == p2 || Point(x1,y) == p3 || Point(x1,y) == p4)) return false;\n            }\n        } else if (y1 == y2) {\n            for (int x = min(x1,x2); x <= max(x1,x2); x++) {\n                if (hasDot[x][y1] && !(Point(x,y1) == p2 || Point(x,y1) == p3 || Point(x,y1) == p4)) return false;\n            }\n        }\n        return true;\n    };\n    \n    return check_line(p1.x, p1.y, p2.x, p2.y) && \n           check_line(p2.x, p2.y, p3.x, p3.y) &&\n           check_line(p3.x, p3.y, p4.x, p4.y) &&\n           check_line(p4.x, p4.y, p1.x, p1.y);\n}\n\nvoid find_candidates(vector<Rectangle>& candidates) {\n    candidates.clear();\n    \n    // Search for possible rectangles centered on empty points\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            if (hasDot[x][y]) continue;\n            \n            // Try axis-aligned rectangles\n            for (int dx = 1; dx < N; dx++) {\n                for (int dy = 1; dy < N; dy++) {\n                    // Check all four corners\n                    int x1 = x - dx, y1 = y;\n                    int x2 = x, y2 = y + dy;\n                    int x3 = x + dx, y3 = y;\n                    int x4 = x, y4 = y - dy;\n                    \n                    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) continue;\n                    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) continue;\n                    if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n                    if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N) continue;\n                    \n                    Rectangle r;\n                    r.p[0] = Point(x, y);\n                    r.p[1] = Point(x1, y1);\n                    r.p[2] = Point(x2, y2);\n                    r.p[3] = Point(x3, y3);\n                    r.weight = weight[x][y];\n                    \n                    if (can_place_rectangle(r.p[0], r.p[1], r.p[2], r.p[3])) {\n                        candidates.push_back(r);\n                    }\n                }\n            }\n            \n            // Try 45\u00b0 rotated rectangles\n            for (int d = 1; d < N; d++) {\n                int x1 = x - d, y1 = y - d;\n                int x2 = x, y2 = y - d;\n                int x3 = x + d, y3 = y;\n                int x4 = x, y4 = y + d;\n                \n                if (x1 >= 0 && x1 < N && y1 >= 0 && y1 < N &&\n                    x2 >= 0 && x2 < N && y2 >= 0 && y2 < N &&\n                    x3 >= 0 && x3 < N && y3 >= 0 && y3 < N &&\n                    x4 >= 0 && x4 < N && y4 >= 0 && y4 < N) {\n                    \n                    Rectangle r;\n                    r.p[0] = Point(x, y);\n                    r.p[1] = Point(x1, y1);\n                    r.p[2] = Point(x2, y2);\n                    r.p[3] = Point(x3, y3);\n                    r.weight = weight[x][y];\n                    \n                    if (can_place_rectangle(r.p[0], r.p[1], r.p[2], r.p[3])) {\n                        candidates.push_back(r);\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    hasDot.assign(N, vector<bool>(N, false));\n    occupied.assign(N, vector<bool>(N, false));\n    center = (N-1)/2;\n    \n    weight.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            weight[i][j] = get_weight(i, j);\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        hasDot[x][y] = true;\n    }\n    \n    vector<array<int, 8>> operations;\n    vector<Rectangle> candidates;\n    \n    // Greedy algorithm with multiple attempts\n    auto solve = [&]() -> vector<array<int, 8>> {\n        vector<array<int, 8>> ops;\n        auto temp_hasDot = hasDot;\n        \n        while (true) {\n            find_candidates(candidates);\n            if (candidates.empty()) break;\n            \n            // Sort by weight descending\n            sort(candidates.begin(), candidates.end(), \n                 [](const Rectangle& a, const Rectangle& b) {\n                     return a.weight > b.weight;\n                 });\n            \n            // Take the best candidate\n            Rectangle best = candidates[0];\n            \n            // Place the rectangle\n            Point p1 = best.p[0];\n            temp_hasDot[p1.x][p1.y] = true;\n            \n            ops.push_back({p1.x, p1.y, \n                          best.p[1].x, best.p[1].y,\n                          best.p[2].x, best.p[2].y,\n                          best.p[3].x, best.p[3].y});\n        }\n        \n        return ops;\n    };\n    \n    operations = solve();\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            cout << op[i] << (i < 7 ? \" \" : \"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int T = 100;\n\n// Direction vectors\nconst int dx[] = {0, 0, -1, 1};  // x changes for L/R\nconst int dy[] = {1, -1, 0, 0};  // y changes for F/B\n\nstruct State {\n    int grid[N][N] = {};\n    \n    State() {}\n    State(const State& other) {\n        memcpy(grid, other.grid, sizeof(grid));\n    }\n    \n    bool valid(int x, int y) const {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    // Place candy at position p (1-indexed in empty cells, left-to-right, front-to-back)\n    void place(int p, int flavor) {\n        int count = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[x][y] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Tilt in direction d (0=F, 1=B, 2=L, 3=R)\n    State tilt(int d) const {\n        State res(*this);\n        \n        if (d == 0) {  // Forward - candies move toward row 0 (decreasing y)\n            for (int x = 0; x < N; x++) {\n                for (int y = 1; y < N; y++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny > 0 && res.grid[x][ny-1] == 0) ny--;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 1) {  // Backward - candies move toward row N-1 (increasing y)\n            for (int x = 0; x < N; x++) {\n                for (int y = N-2; y >= 0; y--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny < N-1 && res.grid[x][ny+1] == 0) ny++;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 2) {  // Left - candies move toward col 0 (decreasing x)\n            for (int y = 0; y < N; y++) {\n                for (int x = 1; x < N; x++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx > 0 && res.grid[nx-1][y] == 0) nx--;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else {  // Right - candies move toward col N-1 (increasing x)\n            for (int y = 0; y < N; y++) {\n                for (int x = N-2; x >= 0; x--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx < N-1 && res.grid[nx+1][y] == 0) nx++;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        \n        return res;\n    }\n    \n    // Enhanced evaluation function\n    double evaluate(const vector<int>& future_flavors, int remaining) const {\n        double score = 0.0;\n        \n        // 1. Count adjacent same-flavor pairs (primary metric)\n        int adj_pairs = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int flavor = grid[x][y];\n                \n                // Check right neighbor\n                if (x + 1 < N && grid[x+1][y] == flavor) adj_pairs++;\n                // Check bottom neighbor\n                if (y + 1 < N && grid[x][y+1] == flavor) adj_pairs++;\n            }\n        }\n        score += adj_pairs * 10.0;\n        \n        // 2. Component size estimation (weight larger groups more)\n        // Use BFS to find components\n        bool visited[N][N] = {};\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0 || visited[x][y]) continue;\n                int flavor = grid[x][y];\n                int size = 0;\n                \n                queue<pair<int,int>> q;\n                q.push({x, y});\n                visited[x][y] = true;\n                \n                while (!q.empty()) {\n                    auto [cx, cy] = q.front(); q.pop();\n                    size++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = cx + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                        int ny = cy + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                        if (valid(nx, ny) && !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                \n                score += size * size * 0.5;  // Square weighting\n            }\n        }\n        \n        // 3. Future potential - look at empty spaces near same-flavor clusters\n        int future_count[4] = {};\n        for (int i = 0; i < remaining; i++) {\n            future_count[future_flavors[i]]++;\n        }\n        \n        // Check each empty cell's potential\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0) continue;\n                \n                // Count same-flavor neighbors (potential expansion)\n                int neighbor_flavors[4] = {};\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] > 0) {\n                        neighbor_flavors[grid[nx][ny]]++;\n                    }\n                }\n                \n                for (int f = 1; f <= 3; f++) {\n                    if (neighbor_flavors[f] > 0 && future_count[f] > 0) {\n                        score += neighbor_flavors[f] * 3.0;  // Bonus for expandable space\n                    }\n                }\n                \n                // Bonus for empty space clusters (future placement flexibility)\n                int empty_cluster_size = 0;\n                bool visited_empty[N][N] = {};\n                if (!visited_empty[x][y]) {\n                    queue<pair<int,int>> q;\n                    q.push({x, y});\n                    visited_empty[x][y] = true;\n                    \n                    while (!q.empty()) {\n                        auto [cx, cy] = q.front(); q.pop();\n                        empty_cluster_size++;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = cx + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                            int ny = cy + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                            if (valid(nx, ny) && !visited_empty[nx][ny] && grid[nx][ny] == 0) {\n                                visited_empty[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                    \n                    if (empty_cluster_size > 3) {\n                        score += empty_cluster_size * 0.5;  // Small bonus for large empty spaces\n                    }\n                }\n            }\n        }\n        \n        // 4. Penalize isolated cells (no same-flavor neighbors nearby)\n        int isolated = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int flavor = grid[x][y];\n                bool has_same = false;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] == flavor) {\n                        has_same = true;\n                        break;\n                    }\n                }\n                if (!has_same) isolated++;\n            }\n        }\n        score -= isolated * 5.0;\n        \n        return score;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read all flavors\n    vector<int> flavors(T);\n    for (int i = 0; i < T; i++) {\n        cin >> flavors[i];\n    }\n    \n    State current_state;\n    const char dir_names[] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < T; t++) {\n        int p;\n        cin >> p;\n        \n        current_state.place(p, flavors[t]);\n        \n        if (t == T - 1) break;\n        \n        // Evaluate all 4 tilts\n        double best_score = -1e18;\n        int best_dir = 0;\n        \n        vector<int> remaining(flavors.begin() + t + 1, flavors.end());\n        \n        for (int d = 0; d < 4; d++) {\n            State new_state = current_state.tilt(d);\n            double score = new_state.evaluate(remaining, T - t - 1);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n        \n        // Apply the best tilt\n        current_state = current_state.tilt(best_dir);\n        cout << dir_names[best_dir] << '\\n';\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <queue>\nusing namespace std;\n\nconst int QUERIES = 100;\nint M;\ndouble eps;\n\n// Generate adjacency matrix from string\nvector<vector<bool>> strToAdj(const string& s, int N) {\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            adj[i][j] = adj[j][i] = (s[idx++] == '1');\n        }\n    }\n    return adj;\n}\n\n// Encode graph to string\nstring adjToStr(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    string s;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            s += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Edge count\nint countEdges(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (adj[i][j]) cnt++;\n        }\n    }\n    return cnt;\n}\n\n// Degree sequence (sorted)\nvector<int> getDegreeSeq(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (adj[i][j]) deg[i]++;\n        }\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\n// Count triangles\nint countTriangles(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (!adj[i][j]) continue;\n            for (int k = j+1; k < N; k++) {\n                if (adj[i][k] && adj[j][k]) cnt++;\n            }\n        }\n    }\n    return cnt;\n}\n\n// Global clustering coefficient\ndouble clusteringCoefficient(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    int triangles = 0;\n    int triplets = 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                int e = adj[i][k] + adj[j][k];\n                if (e == 2) triangles++;\n                if (e >= 1) triplets++;\n            }\n        }\n    }\n    return triplets > 0 ? (double)triangles / triplets : 0.0;\n}\n\n// Katz centrality (approximate)\nvector<double> katzCentrality(const vector<vector<bool>>& adj, double alpha = 0.1) {\n    int N = adj.size();\n    vector<double> cent(N, 1.0);\n    vector<double> newCent(N);\n    \n    for (int iter = 0; iter < 50; iter++) {\n        fill(newCent.begin(), newCent.end(), 1.0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (adj[i][j]) {\n                    newCent[i] += alpha * cent[j];\n                }\n            }\n        }\n        // Normalize\n        double norm = 0;\n        for (double v : newCent) norm += v * v;\n        norm = sqrt(norm);\n        for (double& v : newCent) v /= norm;\n        cent = newCent;\n    }\n    sort(cent.begin(), cent.end());\n    return cent;\n}\n\n// Average shortest path (using BFS on small N)\ndouble avgPathLength(const vector<vector<bool>>& adj) {\n    int N = adj.size();\n    if (N > 50) return 0;  // Skip for large graphs\n    \n    double total = 0;\n    int count = 0;\n    \n    for (int start = 0; start < min(N, 10); start++) {  // Sample 10 sources\n        vector<int> dist(N, -1);\n        queue<int> q;\n        dist[start] = 0;\n        q.push(start);\n        \n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v = 0; v < N; v++) {\n                if (adj[u][v] && dist[v] == -1) {\n                    dist[v] = dist[u] + 1;\n                    q.push(v);\n                }\n            }\n        }\n        \n        for (int v = 0; v < N; v++) {\n            if (v != start && dist[v] > 0) {\n                total += dist[v];\n                count++;\n            }\n        }\n    }\n    return count > 0 ? total / count : 0;\n}\n\n// Compute comprehensive feature vector\nvector<double> computeFeatures(const vector<vector<bool>>& adj, int N) {\n    vector<double> features;\n    \n    // 1. Edge count (most reliable)\n    int edges = countEdges(adj);\n    features.push_back(edges);\n    \n    // 2. Degree sequence statistics\n    auto deg = getDegreeSeq(adj);\n    double mean = 0;\n    for (int d : deg) mean += d;\n    mean /= N;\n    \n    double var = 0;\n    for (int d : deg) var += (d - mean) * (d - mean);\n    var /= N;\n    \n    features.push_back(deg[0]);           // min degree\n    features.push_back(deg[N/4]);         // Q1\n    features.push_back(deg[N/2]);         // median\n    features.push_back(deg[3*N/4]);       // Q3\n    features.push_back(deg[N-1]);         // max degree\n    features.push_back(var / (mean + 1)); // CV^2\n    \n    // 3. Count special degree nodes\n    int isolated = 0, leaves = 0, highDeg = 0;\n    for (int d : deg) {\n        if (d == 0) isolated++;\n        if (d == 1) leaves++;\n        if (d > mean * 1.5) highDeg++;\n    }\n    features.push_back(isolated);\n    features.push_back(leaves);\n    features.push_back(highDeg);\n    \n    // 4. Triangle-based features\n    int triangles = countTriangles(adj);\n    double maxTriangles = (double)N * (N-1) * (N-2) / 6;\n    features.push_back(triangles);\n    features.push_back(maxTriangles > 0 ? triangles / maxTriangles : 0);\n    \n    // 5. Clustering coefficient\n    features.push_back(clusteringCoefficient(adj));\n    \n    // 6. Katz centrality statistics\n    if (N <= 50) {\n        auto katz = katzCentrality(adj);\n        sort(katz.begin(), katz.end());\n        features.push_back(katz[0]);\n        features.push_back(katz[N/2]);\n        features.push_back(katz[N-1]);\n        double katzVar = 0, katzMean = accumulate(katz.begin(), katz.end(), 0.0) / N;\n        for (double v : katz) katzVar += (v - katzMean) * (v - katzMean);\n        features.push_back(sqrt(katzVar / N));\n    } else {\n        features.push_back(0);\n        features.push_back(0);\n        features.push_back(0);\n        features.push_back(0);\n    }\n    \n    // 7. Path length approximation\n    features.push_back(avgPathLength(adj));\n    \n    return features;\n}\n\n// Weighted L2 distance\ndouble weightedDist(const vector<double>& a, const vector<double>& b, const vector<double>& weights) {\n    double d = 0;\n    for (int i = 0; i < (int)a.size(); i++) {\n        double diff = a[i] - b[i];\n        // Normalize by typical scale (using mean of both)\n        double scale = max(1.0, (abs(a[i]) + abs(b[i])) / 2.0);\n        d += weights[i] * diff * diff / (scale * scale);\n    }\n    return sqrt(d);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read M and epsilon\n    cin >> M >> eps;\n    \n    // Adaptive N selection based on M and epsilon\n    int N;\n    if (eps <= 0.02) {\n        N = min(100, max(20, 15 + M / 2));\n    } else if (eps <= 0.05) {\n        N = min(80, max(15, 12 + M / 3));\n    } else if (eps <= 0.10) {\n        N = min(60, max(12, 10 + M / 4));\n    } else if (eps <= 0.20) {\n        N = min(40, max(10, 8 + M / 5));\n    } else if (eps <= 0.30) {\n        N = min(30, max(8, 6 + M / 6));\n    } else {\n        N = min(20, max(6, 4 + M / 8));\n    }\n    \n    // Generate structured graphs\n    vector<vector<vector<bool>>> graphs(M, vector<vector<bool>>(N, vector<bool>(N, false)));\n    vector<vector<double>> graphFeatures(M);\n    \n    int totalEdges = N * (N - 1) / 2;\n    mt19937 rng(12345);  // Fixed seed for reproducibility\n    \n    for (int k = 0; k < M; k++) {\n        vector<vector<bool>>& adj = graphs[k];\n        double targetDensity = (double)k / (M - 1);\n        int targetEdges = max(1, (int)(targetDensity * totalEdges));\n        \n        // Create structured graphs with clear distinctions\n        if (eps <= 0.05) {\n            // Low noise: use highly structured graphs\n            if (k % 4 == 0) {\n                // Complete bipartite K_{a, N-a}\n                int a = max(1, min(N-1, 1 + k * (N-2) / M));\n                for (int i = 0; i < a; i++) {\n                    for (int j = a; j < N; j++) {\n                        adj[i][j] = adj[j][i] = true;\n                    }\n                }\n            } else if (k % 4 == 1) {\n                // Path + extra edges\n                for (int i = 0; i < N-1; i++) {\n                    adj[i][i+1] = adj[i+1][i] = true;\n                }\n                int extra = targetEdges - (N-1);\n                while (extra > 0) {\n                    int u = rng() % N, v = rng() % N;\n                    if (u != v && !adj[u][v]) {\n                        adj[u][v] = adj[v][u] = true;\n                        extra--;\n                    }\n                }\n            } else if (k % 4 == 2) {\n                // Regular-like graph with different degrees\n                int deg = targetEdges * 2 / N;\n                deg = max(1, min(N-1, deg));\n                for (int i = 0; i < N; i++) {\n                    for (int d = 1; d <= deg/2; d++) {\n                        int j = (i + d) % N;\n                        adj[i][j] = adj[j][i] = true;\n                    }\n                }\n            } else {\n                // Random Erdos-Renyi with specific density\n                uniform_real_distribution<double> unif(0, 1);\n                for (int i = 0; i < N; i++) {\n                    for (int j = i+1; j < N; j++) {\n                        if (unif(rng) < targetDensity) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            }\n        } else if (eps <= 0.15) {\n            // Medium noise: simpler structures\n            if (k < M / 3) {\n                // Star-like\n                for (int i = 1; i <= k && i < N; i++) {\n                    adj[0][i] = adj[i][0] = true;\n                }\n            } else if (k < 2 * M / 3) {\n                // Two communities with varying internal edges\n                int half = N / 2;\n                double density = (k - M/3) / (M/3.0);\n                for (int i = 0; i < half; i++) {\n                    for (int j = half; j < N; j++) {\n                        if (uniform_real_distribution<double>(0,1)(rng) < 0.3 + 0.5*density) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            } else {\n                // Dense graphs\n                for (int i = 0; i < N; i++) {\n                    for (int j = i+1; j < N; j++) {\n                        if (uniform_real_distribution<double>(0,1)(rng) < 0.7 + 0.3*targetDensity) {\n                            adj[i][j] = adj[j][i] = true;\n                        }\n                    }\n                }\n            }\n        } else {\n            // High noise: rely mostly on edge density\n            // Use simple Erdos-Renyi with controlled density\n            for (int i = 0; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    if (uniform_real_distribution<double>(0,1)(rng) < targetDensity) {\n                        adj[i][j] = adj[j][i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Ensure minimum edges for small k\n        if (countEdges(adj) < 1 && k > 0) {\n            adj[0][1] = adj[1][0] = true;\n        }\n        \n        graphFeatures[k] = computeFeatures(adj, N);\n    }\n    \n    // Precompute feature weights based on epsilon\n    // Edge count weight increases with noise\n    vector<double> featureWeights(graphFeatures[0].size(), 1.0);\n    featureWeights[0] = 1.0 + eps * 5;  // Edge count weighted more with noise\n    // Degree statistics weight\n    for (int i = 1; i <= 5; i++) featureWeights[i] = 1.0 + (1 - eps);\n    // Triangle features less reliable with noise\n    if (eps > 0.15) {\n        for (int i = 10; i <= 12; i++) featureWeights[i] = 0.5;\n    }\n    \n    // Output\n    cout << N << endl;\n    for (int k = 0; k < M; k++) {\n        cout << adjToStr(graphs[k]) << endl;\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < QUERIES; q++) {\n        string H_str;\n        cin >> H_str;\n        \n        auto H = strToAdj(H_str, N);\n        auto H_features = computeFeatures(H, N);\n        \n        // Weighted distance classification\n        int best = 0;\n        double bestDist = 1e18;\n        \n        // Also track edge-count only as fallback\n        int edgeBest = 0;\n        double edgeBestDist = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double dist = weightedDist(H_features, graphFeatures[k], featureWeights);\n            double edgeDist = abs(H_features[0] - graphFeatures[k][0]);\n            \n            if (dist < bestDist) {\n                bestDist = dist;\n                best = k;\n            }\n            if (edgeDist < edgeBestDist) {\n                edgeBestDist = edgeDist;\n                edgeBest = k;\n            }\n        }\n        \n        // For high noise, trust edge count more\n        double edgeRatio = abs(H_features[0] - graphFeatures[best][0]) / (double)max(1, (int)H_features[0]);\n        if (eps > 0.2 && edgeRatio > 0.3) {\n            best = edgeBest;\n        }\n        \n        cout << best << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\n\nint N, M, D, K;\nvector<tuple<int, int, int>> edges;\nvector<vector<pair<int, int>>> graph;\n\ndouble quick_evaluate(const vector<int>& schedule) {\n    double cost = 0;\n    vector<double> day_cost(D+1, 0);\n    vector<vector<int>> day_edges(D+1);\n    \n    // Group edges by day\n    for (int e = 0; e < M; e++) {\n        day_edges[schedule[e]].push_back(e);\n    }\n    \n    // Compute cost for each day\n    for (int day = 1; day <= D; day++) {\n        if (day_edges[day].empty()) continue;\n        \n        double total_importance = 0;\n        // Check vertex conflicts among edges on this day\n        unordered_map<int, int> vertex_usage;\n        \n        for (int e : day_edges[day]) {\n            auto [u, v, w] = edges[e];\n            vertex_usage[u]++;\n            vertex_usage[v]++;\n            // Heuristic: heavier edges cause more frustration\n            total_importance += w * 0.001; // Scale down weight\n        }\n        \n        // Penalty: vertices with multiple incident edges being repaired on same day\n        double vertex_conflict_penalty = 0;\n        for (auto& [v, count] : vertex_usage) {\n            if (count > 1) {\n                vertex_conflict_penalty += (count - 1) * (count - 1) * 1000;\n            }\n        }\n        \n        cost += total_importance + vertex_conflict_penalty;\n    }\n    \n    return cost;\n}\n\nvector<int> solve() {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Simple edge importance: weight * degree_factor\n    vector<double> edge_importance(M);\n    vector<int> degree(N, 0);\n    for (auto& [u, v, w] : edges) {\n        degree[u]++;\n        degree[v]++;\n    }\n    for (int e = 0; e < M; e++) {\n        auto [u, v, w] = edges[e];\n        edge_importance[e] = w * (1.0 / degree[u] + 1.0 / degree[v]);\n    }\n    \n    // Sort by importance\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    vector<int> best_schedule;\n    double best_cost = INF;\n    \n    // Multiple attempts (reduced from 15 to 10)\n    for (int trial = 0; trial < 10; trial++) {\n        vector<int> schedule(M);\n        vector<int> day_count(D+1, 0);\n        \n        // Fast greedy: spread important edges across days\n        // Use a round-robin approach for important edges\n        int day_idx = 1;\n        for (int idx = 0; idx < M; idx++) {\n            int e = edge_order[idx];\n            \n            // Find least loaded valid day\n            int best_day = -1;\n            double best_score = INF;\n            \n            // Try days in order, prefer less loaded days\n            vector<pair<int, int>> day_load;\n            for (int d = 1; d <= D; d++) {\n                day_load.push_back({day_count[d], d});\n            }\n            sort(day_load.begin(), day_load.end());\n            \n            for (auto& [load, d] : day_load) {\n                if (load >= K) continue;\n                \n                auto [u, v, w] = edges[e];\n                double score = load * 100;\n                \n                // Add penalty for vertex conflicts with already assigned important edges\n                for (int other = 0; other < M; other++) {\n                    if (other != e && schedule[other] == d) {\n                        auto [ou, ov, ow] = edges[other];\n                        if (ou == u || ou == v || ov == u || ov == v) {\n                            score += edge_importance[other] * 0.1;\n                        }\n                    }\n                }\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_day = d;\n                }\n            }\n            \n            schedule[e] = best_day;\n            day_count[best_day]++;\n        }\n        \n        // Lightweight local search (reduced iterations)\n        double current_cost = quick_evaluate(schedule);\n        double temp = 1.0;\n        \n        for (int iter = 0; iter < 500 && temp > 0.1; iter++) {\n            int e1 = rng() % M;\n            int old_day = schedule[e1];\n            int new_day = rng() % D + 1;\n            \n            if (new_day == old_day || day_count[new_day] >= K) continue;\n            \n            // Quick check: minimize vertex conflicts\n            auto [u, v, w] = edges[e1];\n            \n            // Count conflicts on old day (excluding this edge)\n            int old_conflicts = 0;\n            for (int other = 0; other < M; other++) {\n                if (other != e1 && schedule[other] == old_day) {\n                    auto [ou, ov, ow] = edges[other];\n                    if (ou == u || ou == v || ov == u || ov == v) {\n                        old_conflicts++;\n                    }\n                }\n            }\n            \n            // Count conflicts on new day\n            int new_conflicts = 0;\n            for (int other = 0; other < M; other++) {\n                if (other != e1 && schedule[other] == new_day) {\n                    auto [ou, ov, ow] = edges[other];\n                    if (ou == u || ou == v || ov == u || ov == v) {\n                        new_conflicts++;\n                    }\n                }\n            }\n            \n            double delta = (new_conflicts - old_conflicts) * w * 0.001;\n            \n            if (delta < 0 || exp(-delta / temp) > (double)rng() / RAND_MAX) {\n                schedule[e1] = new_day;\n                day_count[old_day]--;\n                day_count[new_day]++;\n                current_cost += delta;\n            }\n            \n            temp *= 0.99;\n        }\n        \n        double cost = quick_evaluate(schedule);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_schedule = schedule;\n        }\n    }\n    \n    return best_schedule;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\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        graph[u].push_back({v, w});\n        graph[v].push_back({u, w});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Generate schedule (no expensive precomputation)\n    vector<int> schedule = solve();\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << schedule[i] << (i+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nint D;\nint dx[] = {1, -1, 0, 0, 0, 0};\nint dy[] = {0, 0, 1, -1, 0, 0};\nint dz[] = {0, 0, 0, 0, 1, -1};\n\nstruct Pos {\n    int x, y, z;\n    Pos(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}\n    bool operator<(const Pos& other) const {\n        if (x != other.x) return x < other.x;\n        if (y != other.y) return y < other.y;\n        return z < other.z;\n    }\n    bool operator==(const Pos& other) const {\n        return x == other.x && y == other.y && z == other.z;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read silhouettes\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int k = 0; k < D; k++) cin >> f[i][k];\n        for (int k = 0; k < D; k++) cin >> r[i][k];\n    }\n    \n    // Store cubes for each object\n    vector<vector<Pos>> cubes(2);\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                        cubes[i].push_back({x, y, z});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find shared cubes (used in both objects)\n    map<Pos, int> shared_idx;\n    for (auto p : cubes[0]) {\n        if (find(cubes[1].begin(), cubes[1].end(), p) != cubes[1].end()) {\n            shared_idx[p] = shared_idx.size();\n        }\n    }\n    \n    // Assign block IDs greedily\n    // For each object, assign block IDs using BFS/DFS to merge adjacent cubes\n    vector<vector<int>> result(2, vector<int>(D * D * D, 0));\n    vector<set<int>> block_sizes; // Track which object uses which block\n    int block_cnt = 0;\n    map<pair<int, int>, int> block_id_map; // Maps (object_id, cube_position_index) to block_id\n    \n    for (int obj = 0; obj < 2; obj++) {\n        set<Pos> visited;\n        for (auto start : cubes[obj]) {\n            if (visited.count(start)) continue;\n            \n            // BFS to find connected component\n            queue<Pos> q;\n            q.push(start);\n            visited.insert(start);\n            vector<Pos> component;\n            \n            while (!q.empty()) {\n                auto p = q.front(); q.pop();\n                component.push_back(p);\n                \n                for (int d = 0; d < 6; d++) {\n                    Pos np = {p.x + dx[d], p.y + dy[d], p.z + dz[d]};\n                    if (np.x < 0 || np.x >= D || np.y < 0 || np.y >= D || np.z < 0 || np.z >= D) continue;\n                    if (visited.count(np)) continue;\n                    if (find(cubes[obj].begin(), cubes[obj].end(), np) == cubes[obj].end()) continue;\n                    visited.insert(np);\n                    q.push(np);\n                }\n            }\n            \n            // Assign block ID\n            block_cnt++;\n            for (auto p : component) {\n                int idx = p.x * D * D + p.y * D + p.z;\n                result[obj][idx] = block_cnt;\n            }\n        }\n    }\n    \n    // Now try to merge blocks that appear in both objects\n    // For simplicity, we'll keep the current blocks\n    // Output\n    cout << block_cnt << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        for (int j = 0; j < D * D * D; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <cmath>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    long long w;\n    int id;\n};\n\nint N, M, K;\nvector<pair<int,int>> vertices;\nvector<Edge> edges;\nvector<pair<int,int>> residents;\nvector<vector<int>> adj;\nvector<vector<long long>> dist_sq_to_residents;\n\nvoid read_input() {\n    cin >> N >> M >> K;\n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    edges.resize(M);\n    adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--; edges[j].v--;\n        edges[j].id = j;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n    residents.resize(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n    \n    // Precompute squared distances from stations to residents\n    dist_sq_to_residents.assign(N, vector<long long>(K));\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < K; k++) {\n            long long dx = vertices[i].first - residents[k].first;\n            long long dy = vertices[i].second - residents[k].second;\n            dist_sq_to_residents[i][k] = dx*dx + dy*dy;\n        }\n    }\n}\n\nstruct Solution {\n    vector<int> P;\n    vector<bool> edge_on;\n    vector<bool> reachable;\n    long long total_cost;\n    bool valid;\n    \n    Solution() : P(N, 0), edge_on(M, false), reachable(N, false), total_cost(LLONG_MAX), valid(false) {}\n    \n    void compute_reachable() {\n        fill(reachable.begin(), reachable.end(), false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (int e_idx : adj[u]) {\n                if (!edge_on[e_idx]) continue;\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                if (!reachable[v]) {\n                    reachable[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    bool covers_all_residents() {\n        for (int k = 0; k < K; k++) {\n            bool covered = false;\n            for (int i = 0; i < N && !covered; i++) {\n                if (!reachable[i]) continue;\n                if (P[i] > 0 && dist_sq_to_residents[i][k] <= (long long)P[i] * P[i]) {\n                    covered = true;\n                }\n            }\n            if (!covered) return false;\n        }\n        return true;\n    }\n    \n    long long compute_total_cost() {\n        long long power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            power_cost += (long long)P[i] * P[i];\n        }\n        long long edge_cost = 0;\n        for (int j = 0; j < M; j++) {\n            if (edge_on[j]) edge_cost += edges[j].w;\n        }\n        return power_cost + edge_cost;\n    }\n    \n    bool is_valid() {\n        compute_reachable();\n        if (!covers_all_residents()) return false;\n        total_cost = compute_total_cost();\n        valid = true;\n        return true;\n    }\n};\n\n// Compute MST from station 0 to all other stations\nvector<int> compute_mst_edges() {\n    vector<bool> in_tree(N, false);\n    vector<int> parent_edge(N, -1);\n    vector<long long> min_dist(N, LLONG_MAX);\n    \n    in_tree[0] = true;\n    for (int e_idx : adj[0]) {\n        int v = (edges[e_idx].u == 0) ? edges[e_idx].v : edges[e_idx].u;\n        if (edges[e_idx].w < min_dist[v]) {\n            min_dist[v] = edges[e_idx].w;\n            parent_edge[v] = e_idx;\n        }\n    }\n    \n    for (int iter = 1; iter < N; iter++) {\n        // Find minimum distance vertex not in tree\n        int best = -1;\n        long long best_dist = LLONG_MAX;\n        for (int i = 0; i < N; i++) {\n            if (!in_tree[i] && min_dist[i] < best_dist) {\n                best_dist = min_dist[i];\n                best = i;\n            }\n        }\n        if (best == -1) break;\n        \n        in_tree[best] = true;\n        \n        // Update distances\n        for (int e_idx : adj[best]) {\n            int v = (edges[e_idx].u == best) ? edges[e_idx].v : edges[e_idx].u;\n            if (!in_tree[v] && edges[e_idx].w < min_dist[v]) {\n                min_dist[v] = edges[e_idx].w;\n                parent_edge[v] = e_idx;\n            }\n        }\n    }\n    \n    vector<int> mst_edges;\n    for (int i = 1; i < N; i++) {\n        if (parent_edge[i] != -1) {\n            mst_edges.push_back(parent_edge[i]);\n        }\n    }\n    return mst_edges;\n}\n\n// For each station, compute cost-benefit of powering it up\ndouble compute_station_value(int station, const vector<int>& currently_covered) {\n    if (station == 0) return 1e9; // Always need station 1\n    \n    int new_covered = 0;\n    long long max_dist_sq = 0;\n    \n    for (int k = 0; k < K; k++) {\n        if (currently_covered[k]) continue;\n        if (dist_sq_to_residents[station][k] <= 5000LL * 5000) {\n            new_covered++;\n            max_dist_sq = max(max_dist_sq, dist_sq_to_residents[station][k]);\n        }\n    }\n    \n    if (new_covered == 0) return 0;\n    \n    double power_cost = (double)max_dist_sq;\n    double edge_cost = 0;\n    \n    // Estimate edge cost to connect this station\n    vector<bool> visited(N, false);\n    visited[0] = true;\n    queue<int> q;\n    q.push(0);\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for (int e_idx : adj[u]) {\n            int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    // Find shortest path from any visited station to this station\n    vector<long long> dist(N, LLONG_MAX);\n    vector<bool> in_q(N, false);\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    \n    for (int i = 0; i < N; i++) {\n        if (visited[i]) {\n            dist[i] = 0;\n            pq.push({0, i});\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        if (d != dist[u]) continue;\n        if (u == station) break;\n        \n        for (int e_idx : adj[u]) {\n            int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n            long long nd = d + edges[e_idx].w;\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n    \n    edge_cost = dist[station];\n    if (edge_cost >= LLONG_MAX / 2) return 0;\n    \n    return (double)new_covered / (power_cost + edge_cost);\n}\n\nSolution solve() {\n    Solution sol;\n    \n    // Step 1: Start with MST of all stations\n    vector<int> mst_edges = compute_mst_edges();\n    for (int e_idx : mst_edges) {\n        sol.edge_on[e_idx] = true;\n    }\n    sol.compute_reachable();\n    \n    // Step 2: Find which residents each station can cover, consider sharing\n    // Assign each resident to the station that can cover it with minimum power\n    vector<vector<int>> residents_covered(N);\n    vector<bool> resident_covered(K, false);\n    \n    for (int k = 0; k < K; k++) {\n        int best_i = -1;\n        long long best_dist = LLONG_MAX;\n        \n        for (int i = 0; i < N; i++) {\n            if (!sol.reachable[i]) continue;\n            if (dist_sq_to_residents[i][k] < best_dist && \n                dist_sq_to_residents[i][k] <= 5000LL * 5000) {\n                best_dist = dist_sq_to_residents[i][k];\n                best_i = i;\n            }\n        }\n        \n        if (best_i != -1) {\n            residents_covered[best_i].push_back(k);\n            resident_covered[k] = true;\n        }\n    }\n    \n    // Step 3: Compute initial power levels\n    for (int i = 0; i < N; i++) {\n        if (!sol.reachable[i]) continue;\n        if (residents_covered[i].empty()) {\n            sol.P[i] = 0;\n            continue;\n        }\n        \n        long long max_dist_sq = 0;\n        for (int k : residents_covered[i]) {\n            max_dist_sq = max(max_dist_sq, dist_sq_to_residents[i][k]);\n        }\n        sol.P[i] = min((int)ceil(sqrt(max_dist_sq)), 5000);\n    }\n    \n    // Step 4: Try to add more stations to cover uncovered residents\n    int uncovered_count = K;\n    for (bool c : resident_covered) {\n        if (!c) uncovered_count--;\n    }\n    \n    while (uncovered_count > 0) {\n        // Find best station to add\n        vector<int> currently_covered(K, 0);\n        for (int i = 0; i < N; i++) {\n            if (sol.P[i] > 0 && sol.reachable[i]) {\n                for (int k = 0; k < K; k++) {\n                    if (dist_sq_to_residents[i][k] <= (long long)sol.P[i] * sol.P[i]) {\n                        currently_covered[k] = 1;\n                    }\n                }\n            }\n        }\n        \n        int best_i = -1;\n        double best_value = 0;\n        \n        for (int i = 0; i < N; i++) {\n            if (sol.P[i] > 0) continue;\n            double val = compute_station_value(i, currently_covered);\n            if (val > best_value) {\n                best_value = val;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1 || best_value < 0.01) break;\n        \n        // Connect this station to the network\n        // Find shortest path from any reachable station\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> parent_edge(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        \n        for (int i = 0; i < N; i++) {\n            if (sol.reachable[i]) {\n                dist[i] = 0;\n                pq.push({0, i});\n            }\n        }\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            if (u == best_i) break;\n            \n            for (int e_idx : adj[u]) {\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                long long nd = d + edges[e_idx].w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    parent_edge[v] = e_idx;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        // Add edges along path\n        int cur = best_i;\n        while (parent_edge[cur] != -1) {\n            int e_idx = parent_edge[cur];\n            sol.edge_on[e_idx] = true;\n            int prev = (edges[e_idx].u == cur) ? edges[e_idx].v : edges[e_idx].u;\n            cur = prev;\n        }\n        \n        sol.compute_reachable();\n        \n        // Assign power to new station\n        long long max_dist_sq = 0;\n        for (int k = 0; k < K; k++) {\n            if (currently_covered[k]) continue;\n            if (dist_sq_to_residents[best_i][k] <= 5000LL * 5000) {\n                max_dist_sq = max(max_dist_sq, dist_sq_to_residents[best_i][k]);\n            }\n        }\n        sol.P[best_i] = min((int)ceil(sqrt(max_dist_sq)), 5000);\n        \n        // Update uncovered count\n        uncovered_count = 0;\n        for (int k = 0; k < K; k++) {\n            bool covered = false;\n            for (int i = 0; i < N && !covered; i++) {\n                if (!sol.reachable[i]) continue;\n                if (sol.P[i] > 0 && \n                    dist_sq_to_residents[i][k] <= (long long)sol.P[i] * sol.P[i]) {\n                    covered = true;\n                }\n            }\n            if (!covered) uncovered_count++;\n        }\n    }\n    \n    // Step 5: Optimize - try to remove stations that don't help much\n    // For each station with P > 0, check if removing it still covers all\n    for (int iter = 0; iter < 3; iter++) {\n        for (int i = 1; i < N; i++) {\n            if (sol.P[i] == 0) continue;\n            \n            // Try removing this station\n            int old_P = sol.P[i];\n            sol.P[i] = 0;\n            \n            if (!sol.is_valid()) {\n                // Restore\n                sol.P[i] = old_P;\n            }\n        }\n    }\n    \n    // Step 6: Optimize power levels - try to reduce them\n    for (int iter = 0; iter < 10; iter++) {\n        for (int i = 0; i < N; i++) {\n            if (sol.P[i] == 0) continue;\n            \n            // Try reducing power\n            int old_P = sol.P[i];\n            while (sol.P[i] > 0) {\n                sol.P[i] -= 10;\n                if (sol.P[i] < 0) sol.P[i] = 0;\n                \n                if (!sol.is_valid()) {\n                    sol.P[i] += 10;\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Step 7: Try to reduce edges (only keep essential ones for connectivity)\n    // For each edge not on a critical path, try removing it\n    for (int e_idx : mst_edges) {\n        sol.edge_on[e_idx] = false;\n        if (!sol.is_valid()) {\n            sol.edge_on[e_idx] = true;\n        }\n    }\n    \n    sol.is_valid();\n    return sol;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    read_input();\n    Solution sol = solve();\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << sol.P[i] << (i+1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (sol.edge_on[j] ? 1 : 0) << (j+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2; // 465\n\n// Direction vectors for 6-directional movement\nconst int dx[6] = {-1, -1, 0, 0, 1, 1};\nconst int dy[6] = {-1, 0, -1, 1, 0, 1};\n\n// Check if coordinates are valid\nbool valid(int x, int y) {\n    return 0 <= x && x < N && 0 <= y && y <= x;\n}\n\n// Get target position for a number\npair<int,int> target_pos(int val) {\n    int n = 1;\n    while (n * (n + 1) / 2 <= val) n++;\n    n--;\n    int x = n;\n    int y = val - n * (n + 1) / 2;\n    return {x, y};\n}\n\nint main() {\n    vector<vector<int>> grid(N, vector<int>(N));\n    vector<pair<int,int>> pos(TOTAL);\n    \n    // Read input\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    \n    vector<tuple<int,int,int,int>> operations;\n    \n    // Process balls from smallest to largest\n    for (int val = 0; val < TOTAL; val++) {\n        auto [cx, cy] = pos[val];\n        auto [tx, ty] = target_pos(val);\n        \n        // BFS to find shortest path from current to target\n        vector<vector<int>> dist(N, vector<int>(N, -1));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1, -1}));\n        queue<pair<int,int>> q;\n        \n        dist[cx][cy] = 0;\n        q.push({cx, cy});\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            if (x == tx && y == ty) break;\n            \n            for (int d = 0; d < 6; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (valid(nx, ny) && dist[nx][ny] == -1) {\n                    dist[nx][ny] = dist[x][y] + 1;\n                    prev[nx][ny] = {x, y};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        // Reconstruct path and perform swaps\n        int cur_x = tx, cur_y = ty;\n        vector<pair<int,int>> path;\n        while (cur_x != cx || cur_y != cy) {\n            path.push_back({cur_x, cur_y});\n            auto [p_x, p_y] = prev[cur_x][cur_y];\n            cur_x = p_x; cur_y = p_y;\n        }\n        path.push_back({cx, cy});\n        reverse(path.begin(), path.end());\n        \n        // Execute swaps along the path\n        for (int i = 0; i + 1 < (int)path.size(); i++) {\n            auto [x1, y1] = path[i];\n            auto [x2, y2] = path[i+1];\n            \n            // Swap values\n            swap(grid[x1][y1], grid[x2][y2]);\n            pos[grid[x1][y1]] = {x1, y1};\n            pos[grid[x2][y2]] = {x2, y2};\n            \n            operations.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nvector<vector<int>> input, output;\n\n// Check if adjacency relationships are preserved for the current output\nbool checkAdjacencies() {\n    // For each pair of colors (0..M), check if their adjacency status matches input\n    for (int c = 0; c <= m; c++) {\n        for (int d = c + 1; d <= m; d++) {\n            bool adjInput = false, adjOutput = false;\n            \n            // Check input adjacency (excluding boundary for now)\n            for (int i = 0; i < n && !adjInput; i++) {\n                for (int j = 0; j < n && !adjInput; j++) {\n                    if (input[i][j] == c || input[i][j] == d) {\n                        // Check neighbors\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (input[i][j] == c && input[ni][nj] == d) adjInput = true;\n                                if (input[i][j] == d && input[ni][nj] == c) adjInput = true;\n                            } else if (input[i][j] == 0) {\n                                // Boundary tile of color 0\n                                adjInput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Check output adjacency\n            for (int i = 0; i < n && !adjOutput; i++) {\n                for (int j = 0; j < n && !adjOutput; j++) {\n                    if (output[i][j] == c) {\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (output[ni][nj] == d) adjOutput = true;\n                            } else {\n                                // Cell is on boundary - adjacent to color 0\n                                if (d == 0) adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Also check for c=0: cells on boundary are adjacent to color 0\n            if (c == 0) {\n                for (int i = 0; i < n && !adjOutput; i++) {\n                    for (int j = 0; j < n && !adjOutput; j++) {\n                        if (output[i][j] == d) {\n                            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                                adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (adjInput != adjOutput) return false;\n        }\n    }\n    return true;\n}\n\n// Check connectivity for all colors (including 0)\nbool checkConnectivity() {\n    // For each color, check if its cells are connected (4-directional)\n    for (int c = 0; c <= m; c++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == c) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 0;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            count++;\n            \n            int di[] = {0, 1, 0, -1};\n            int dj[] = {1, 0, -1, 0};\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) {\n                    if (!visited[ni][nj] && output[ni][nj] == c) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                } else if (c == 0) {\n                    // Color 0 can connect through outside\n                    // Already counted as connected if adjacent to boundary\n                }\n            }\n        }\n        \n        if (count != (int)cells.size()) return false;\n    }\n    return true;\n}\n\n// Check if a cell can be safely set to 0 (empty)\nbool canSetToZero(int i, int j, int originalColor) {\n    int saved = output[i][j];\n    output[i][j] = 0;\n    \n    // Check constraints\n    bool valid = checkAdjacencies() && checkConnectivity();\n    \n    output[i][j] = saved;\n    return valid;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    input.assign(n, vector<int>(n));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    // Start with a copy of input\n    output = input;\n    \n    // Multiple passes to remove unnecessary cells\n    for (int pass = 0; pass < 10; pass++) {\n        // Collect all cells that might be removable\n        vector<pair<int,int>> candidates;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] > 0) {\n                    // Check if this color appears elsewhere\n                    bool hasOtherCell = false;\n                    for (int ii = 0; ii < n && !hasOtherCell; ii++) {\n                        for (int jj = 0; jj < n && !hasOtherCell; jj++) {\n                            if ((ii != i || jj != j) && output[ii][jj] == output[i][j]) {\n                                hasOtherCell = true;\n                            }\n                        }\n                    }\n                    if (hasOtherCell) {\n                        candidates.push_back({i, j});\n                    }\n                }\n            }\n        }\n        \n        // Shuffle candidates for randomness\n        random_device rd;\n        mt19937 g(rd());\n        shuffle(candidates.begin(), candidates.end(), g);\n        \n        // Try to remove cells\n        for (auto [i, j] : candidates) {\n            int originalColor = output[i][j];\n            if (originalColor == 0) continue;\n            \n            if (canSetToZero(i, j, originalColor)) {\n                output[i][j] = 0;\n            }\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << output[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Utility for random\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint N, D, Q;\n\n// Structure to store comparison results\nstruct ComparisonResult {\n    int left_sum, right_sum;\n    char result;\n};\n\n// Compare two sets and return result\nchar compare_sets(const vector<int>& left, const vector<int>& right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    string res;\n    cin >> res;\n    return res[0];\n}\n\n// Compare single items indirectly\nchar compare_items(int a, int b) {\n    return compare_sets({a}, {b});\n}\n\n// Binary search to find position in sorted array\nint find_position(const vector<int>& sorted_items, int item, int l, int r) {\n    if (l >= r) return l;\n    int mid = (l + r) / 2;\n    \n    // Compare item with the middle element\n    char res = compare_items(item, sorted_items[mid]);\n    \n    if (res == '<') {\n        return find_position(sorted_items, item, l, mid);\n    } else if (res == '>') {\n        return find_position(sorted_items, item, mid + 1, r);\n    } else {\n        return mid;\n    }\n}\n\n// Compare sums of two groups\nchar compare_groups(const vector<vector<int>>& groups, int g1, int g2) {\n    vector<int> left = groups[g1];\n    vector<int> right = groups[g2];\n    \n    if (left.empty() || right.empty()) {\n        // Handle empty groups by adding a dummy comparison\n        if (left.empty() && right.empty()) return '=';\n        if (left.empty()) return '<';\n        return '>';\n    }\n    \n    return compare_sets(left, right);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Phase 1: Sort items by weight using comparisons\n    vector<int> order;\n    order.push_back(0);\n    \n    for (int i = 1; i < N && Q > 0; i++) {\n        // Binary search to find position\n        int pos = find_position(order, i, 0, order.size());\n        order.insert(order.begin() + pos, i);\n        Q--;\n        \n        // If few queries remain, stop sorting\n        if (Q <= N) break;\n    }\n    \n    // Phase 2: Create initial groups using greedy assignment\n    // Assign items to groups trying to balance weights\n    vector<vector<int>> groups(D);\n    vector<long long> group_weights(D, 0);\n    \n    // First pass: assign each item to the lightest group\n    for (int i = 0; i < N; i++) {\n        int item = order[i];\n        \n        // Find group with minimum weight\n        int min_group = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] < group_weights[min_group]) {\n                min_group = j;\n            }\n        }\n        \n        groups[min_group].push_back(item);\n        group_weights[min_group]++; // approximate weight\n    }\n    \n    // Phase 3: Refine groups using remaining queries\n    // Try to balance groups by moving items\n    int remaining_queries = Q;\n    \n    for (int iter = 0; iter < min(remaining_queries / 2, 10 * D); iter++) {\n        // Find heaviest and lightest groups\n        int heaviest = 0, lightest = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] > group_weights[heaviest]) heaviest = j;\n            if (group_weights[j] < group_weights[lightest]) lightest = j;\n        }\n        \n        if (heaviest == lightest) break;\n        \n        // Try to move an item from heaviest to lightest\n        if (!groups[heaviest].empty()) {\n            // Pick a random item from heaviest group\n            int idx = rng() % groups[heaviest].size();\n            int item = groups[heaviest][idx];\n            \n            // Temporarily move item\n            groups[heaviest].erase(groups[heaviest].begin() + idx);\n            groups[lightest].push_back(item);\n            \n            // Compare the modified groups\n            char result = compare_groups(groups, heaviest, lightest);\n            remaining_queries--;\n            \n            if (result == '<' || result == '=') {\n                // Improvement: keep the move\n                group_weights[heaviest]--;\n                group_weights[lightest]++;\n            } else {\n                // Revert the move\n                groups[lightest].pop_back();\n                groups[heaviest].insert(groups[heaviest].begin() + idx, item);\n            }\n        }\n        \n        if (remaining_queries <= 0) break;\n    }\n    \n    // Use any remaining queries for final verification\n    while (remaining_queries > 0) {\n        // Dummy comparison to waste queries\n        compare_sets({0}, {1});\n        remaining_queries--;\n    }\n    \n    // Phase 4: Output final partition\n    vector<int> assignment(N);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int n = 200, m = 10;\n    const int h = n / m; // 20\n    \n    // Read input\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; j++) {\n            cin >> stacks[i][j];\n        }\n        reverse(stacks[i].begin(), stacks[i].end()); // top is at back\n    }\n    \n    vector<array<int, 2>> operations;\n    int next_to_remove = 1;\n    \n    // Helper to remove from top\n    auto try_remove = [&]() -> bool {\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_to_remove) {\n                stacks[i].pop_back();\n                operations.push_back({next_to_remove, 0});\n                next_to_remove++;\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    // Helper to find stack containing a given box\n    auto find_stack = [&](int v) -> 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] == v) return i;\n            }\n        }\n        return -1;\n    };\n    \n    // Remove easily accessible boxes first\n    while (true) {\n        bool removed = try_remove();\n        if (!removed) break;\n    }\n    \n    // Process remaining boxes\n    while (next_to_remove <= n) {\n        int target_stack = find_stack(next_to_remove);\n        if (target_stack == -1) {\n            break;\n        }\n        \n        auto& st = stacks[target_stack];\n        // Find position of target box (from top, which is back)\n        int pos = -1;\n        for (int i = 0; i < (int)st.size(); i++) {\n            if (st[i] == next_to_remove) {\n                pos = i;\n                break;\n            }\n        }\n        \n        if (pos == (int)st.size() - 1) {\n            // It's already on top\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n            continue;\n        }\n        \n        // Need to move boxes above it\n        // Find best destination: stack with smallest top, or empty stack\n        int best_dest = -1;\n        int best_top = n + 1;\n        for (int i = 0; i < m; i++) {\n            if (i == target_stack) continue;\n            if (stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n            if (stacks[i].back() < best_top) {\n                best_top = stacks[i].back();\n                best_dest = i;\n            }\n        }\n        \n        // Move boxes from position pos+1 to end to best_dest\n        int k = (int)st.size() - pos - 1;\n        // Move in one operation by moving the top box v = st[pos+1]\n        if (k > 0) {\n            int v = st[pos + 1];\n            operations.push_back({v, best_dest});\n            // Update stacks\n            vector<int> moved(st.begin() + pos + 1, st.end());\n            st.resize(pos + 1);\n            for (int x : moved) {\n                stacks[best_dest].push_back(x);\n            }\n        }\n        \n        // Now remove the target box\n        if (!st.empty() && st.back() == next_to_remove) {\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n        }\n        \n        // Try to remove any consecutive boxes that are now on top\n        while (true) {\n            bool removed = try_remove();\n            if (!removed) break;\n        }\n        \n        if (operations.size() > 5000) break;\n    }\n    \n    // Output\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_CELL = MAX_N * MAX_N;\nconst int INF = 1e9;\n\nint N;\nvector<string> h, v; // walls\nvector<vector<int>> d; // dirt rates\n\n// neighbor directions: 0: R, 1: D, 2: L, 3: U\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dirChar[4] = {'R', 'D', 'L', 'U'};\n\nint cellId(int i, int j) { return i * N + j; }\n\nvector<int> neighbors[MAX_CELL];\nint firstMove[MAX_CELL][MAX_CELL]; // direction to take from src to reach dst (0-3)\n\nvoid buildGraph() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = cellId(i, j);\n            // right\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = cellId(i, j+1);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            // down\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = cellId(i+1, j);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            // left and up are covered by symmetry\n        }\n    }\n}\n\nvoid precomputeFirstMove() {\n    int totalCells = N * N;\n    for (int src = 0; src < totalCells; src++) {\n        vector<int> dist(totalCells, INF);\n        vector<int> first(totalCells, -1);\n        queue<int> q;\n        dist[src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int dir = 0; dir < (int)neighbors[u].size(); dir++) {\n                int v = neighbors[u][dir];\n                if (dist[v] == INF) {\n                    dist[v] = dist[u] + 1;\n                    // record the first move from src: for v, it's the direction from src to the neighbor on the path\n                    // we can store it later when we reconstruct\n                    first[v] = (u == src) ? dir : first[u];\n                    q.push(v);\n                }\n            }\n        }\n        // map first[neighbor] to actual direction from src\n        // but we stored dir relative to neighbor list of u. We need global direction.\n        // Better: during BFS, when we expand from src, we know the direction index (0-3) to each neighbor.\n        // So we store for each v the global direction index from src.\n        // Adjust: for each neighbor v of src, we know its direction.\n        // For others, first[v] = first[u] (the direction from src to u's predecessor).\n        // We'll compute differently: after BFS, run a second pass to fill global direction.\n        // We'll just use BFS each time to get direction? Simpler: precompute firstMove as path direction using BFS from src each time? Not efficient.\n        // Alternative: store for each src,dst the first move direction by doing a BFS and tracing back.\n        // We'll do: for each src, BFS, then for each dst, backtrack to src to get first move.\n        // Backtrack uses parent array. Let's reimplement.\n    }\n}\n\n// We'll implement BFS on the fly in the main loop? Too heavy. Let's precompute full direction table.\n\nvoid precomputeFirstMove2() {\n    int total = N * N;\n    for (int src = 0; src < total; src++) {\n        vector<int> dist(total, INF);\n        vector<int> parent(total, -1);\n        vector<int> moveFromParent(total, -1); // direction from parent to child\n        queue<int> q;\n        dist[src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int nb : neighbors[u]) {\n                if (dist[nb] == INF) {\n                    dist[nb] = dist[u] + 1;\n                    parent[nb] = u;\n                    // determine direction from u to nb\n                    int iu = u / N, ju = u % N;\n                    int inb = nb / N, jnb = nb % N;\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (iu + di[dir] == inb && ju + dj[dir] == jnb) {\n                            moveFromParent[nb] = dir;\n                            break;\n                        }\n                    }\n                    q.push(nb);\n                }\n            }\n        }\n        // for each dst, walk back to src to find first move\n        for (int dst = 0; dst < total; dst++) {\n            if (dst == src) { firstMove[src][dst] = -1; continue; }\n            int cur = dst;\n            while (parent[cur] != src) cur = parent[cur];\n            firstMove[src][dst] = moveFromParent[cur];\n        }\n    }\n}\n\nstring dfs_route;\n\nvoid dfs(int i, int j, vector<vector<bool>>& vis) {\n    vis[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !vis[ni][nj]) {\n            // check wall\n            if (dir == 0 && v[i][j] == '1') continue;\n            if (dir == 1 && h[i][j] == '1') continue;\n            if (dir == 2 && v[i][j-1] == '1') continue;\n            if (dir == 3 && h[i-1][j] == '1') continue;\n            dfs_route.push_back(dirChar[dir]);\n            dfs(ni, nj, vis);\n            dfs_route.push_back(dirChar[(dir+2)%4]);\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    v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n\n    buildGraph();\n    precomputeFirstMove2();\n\n    // 1. DFS covering all cells\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    dfs_route.clear();\n    dfs(0, 0, vis);\n    string route = dfs_route;\n\n    // simulate DFS to get dirt array and last visit times\n    vector<vector<int>> dirt(N, vector<int>(N, 0));\n    vector<vector<int>> lastVisit(N, vector<int>(N, -1));\n    int ci = 0, cj = 0;\n    lastVisit[0][0] = 0;\n    // initial dirt update not needed because all zero at t=0.\n    // For each move in dfs_route:\n    for (char ch : route) {\n        // add d to all cells\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n        // move\n        int dir = -1;\n        if (ch == 'R') dir = 0;\n        else if (ch == 'D') dir = 1;\n        else if (ch == 'L') dir = 2;\n        else if (ch == 'U') dir = 3;\n        ci += di[dir]; cj += dj[dir];\n        dirt[ci][cj] = 0;\n        lastVisit[ci][cj] = (int)route.size(); // approximate, but we'll track step count later\n    }\n\n    // After DFS, we have visited all cells.\n    // Now greedy extra moves\n    int dfsLen = (int)route.size();\n    int maxMoves = 100000;\n    int remaining = maxMoves - dfsLen;\n    if (remaining < 0) { /* too long, but unlikely */ }\n\n    // we will add extra moves\n    string extra;\n    int curId = cellId(ci, cj);\n    // we need to track step count for dirt accumulation\n    int step = dfsLen; // next step index (0-indexed after DFS)\n    vector<vector<int>> curDirt = dirt; // copy\n    // we also need lastVisit for dirt calculation? we maintain curDirt directly.\n    auto findMaxDirtCell = [&]() -> pair<int,int> {\n        int maxVal = -1;\n        int mi = -1, mj = -1;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (curDirt[i][j] > maxVal) {\n                    maxVal = curDirt[i][j];\n                    mi = i; mj = j;\n                }\n            }\n        }\n        return {mi, mj};\n    };\n\n    // Precompute distance to origin for deadline\n    vector<vector<int>> distToOrigin(N, vector<int>(N, INF));\n    {\n        queue<pair<int,int>> q;\n        distToOrigin[0][0] = 0;\n        q.push({0,0});\n        while (!q.empty()) {\n            auto [i,j] = q.front(); q.pop();\n            int u = cellId(i,j);\n            for (int nb : neighbors[u]) {\n                int ni = nb/N, nj = nb%N;\n                if (distToOrigin[ni][nj] > distToOrigin[i][j] + 1) {\n                    distToOrigin[ni][nj] = distToOrigin[i][j] + 1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n    }\n\n    int stepsLeft = remaining - 1; // reserve last step to return\n    for (int t = 0; t < stepsLeft; t++) {\n        // find cell with max dirt\n        auto [ti, tj] = findMaxDirtCell();\n        int targetId = cellId(ti, tj);\n        int dir = firstMove[curId][targetId];\n        int ni = ci + di[dir];\n        int nj = cj + dj[dir];\n        // check deadline: after move, distance to origin must be <= (remaining - t - 1 - 1) because we need one more step after loop\n        int remAfterMove = stepsLeft - t - 1; // steps left after this move (excluding final return)\n        if (distToOrigin[ni][nj] > remAfterMove) {\n            // choose alternative: move toward origin? Instead, find any reachable cell that satisfies deadline and high dirt.\n            // Simple fallback: move to neighbor with smallest distance to origin that satisfies deadline.\n            int bestDir = -1;\n            int bestDist = INF;\n            for (int dir2 = 0; dir2 < 4; dir2++) {\n                int ni2 = ci + di[dir2];\n                int nj2 = cj + dj[dir2];\n                if (ni2 < 0 || ni2 >= N || nj2 < 0 || nj2 >= N) continue;\n                // check wall\n                if (dir2 == 0 && v[ci][cj] == '1') continue;\n                if (dir2 == 1 && h[ci][cj] == '1') continue;\n                if (dir2 == 2 && v[ci][cj-1] == '1') continue;\n                if (dir2 == 3 && h[ci-1][cj] == '1') continue;\n                if (distToOrigin[ni2][nj2] <= remAfterMove) {\n                    if (distToOrigin[ni2][nj2] < bestDist) {\n                        bestDist = distToOrigin[ni2][nj2];\n                        bestDir = dir2;\n                    }\n                }\n            }\n            if (bestDir == -1) break; // no feasible move? shouldn't happen\n            dir = bestDir;\n            ni = ci + di[dir];\n            nj = cj + dj[dir];\n        }\n        extra.push_back(dirChar[dir]);\n        // update dirt\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) curDirt[i][j] += d[i][j];\n        ci = ni; cj = nj;\n        curDirt[ci][cj] = 0;\n        curId = cellId(ci, cj);\n    }\n\n    // finally return to (0,0)\n    // BFS from current to origin\n    int target = 0;\n    while (curId != target) {\n        int dir = firstMove[curId][target];\n        extra.push_back(dirChar[dir]);\n        int ni = ci + di[dir];\n        int nj = cj + dj[dir];\n        ci = ni; cj = nj;\n        curId = cellId(ci, cj);\n        // (no need to update dirt for return moves as output length may exceed, but we have to ensure length <=100000)\n    }\n\n    string finalRoute = route + extra;\n    if ((int)finalRoute.size() > 100000) finalRoute.resize(100000);\n\n    cout << finalRoute << endl;\n\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Constants\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\n// Grid information\nvector<string> grid(N);\nint si, sj;\n\n// Word information\nvector<string> words(M);\nvector<vector<pair<int,int>>> char_positions[26];\n\n// For each word, store the best position to start/end\nstruct WordInfo {\n    string word;\n    vector<int> best_path_i, best_path_j;\n    int best_cost;\n};\n\nvector<WordInfo> word_info(M);\n\n// Precompute positions of each character on the grid\nvoid precompute_positions() {\n    for (int c = 0; c < 26; c++) {\n        char_positions[c].clear();\n    }\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n}\n\n// Compute optimal path for a single word starting from (si, sj)\npair<vector<int>, vector<int>> optimize_word_path(const string& word, int start_i, int start_j) {\n    int len = word.size();\n    vector<vector<vector<int>>> dp(len, vector<vector<int>>(N, vector<int>(N, 1e9)));\n    vector<vector<vector<pair<int,int>>>> prev(len, vector<vector<pair<int,int>>>(N, vector<pair<int,int>>(N, {-1, -1})));\n    \n    // Initialize first character\n    for (auto [i, j] : char_positions[word[0] - 'A']) {\n        dp[0][i][j] = abs(i - start_i) + abs(j - start_j) + 1;\n        prev[0][i][j] = {start_i, start_j};\n    }\n    \n    // DP for remaining characters\n    for (int pos = 1; pos < len; pos++) {\n        for (auto [i, j] : char_positions[word[pos] - 'A']) {\n            for (auto [pi, pj] : char_positions[word[pos-1] - 'A']) {\n                int cost = dp[pos-1][pi][pj] + abs(i - pi) + abs(j - pj) + 1;\n                if (cost < dp[pos][i][j]) {\n                    dp[pos][i][j] = cost;\n                    prev[pos][i][j] = {pi, pj};\n                }\n            }\n        }\n    }\n    \n    // Find best ending position\n    int best_i = 0, best_j = 0, best_cost = 1e9;\n    for (auto [i, j] : char_positions[word[len-1] - 'A']) {\n        if (dp[len-1][i][j] < best_cost) {\n            best_cost = dp[len-1][i][j];\n            best_i = i;\n            best_j = j;\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path_i(len), path_j(len);\n    int ci = best_i, cj = best_j;\n    for (int pos = len-1; pos >= 0; pos--) {\n        path_i[pos] = ci;\n        path_j[pos] = cj;\n        if (pos > 0) {\n            auto [pi, pj] = prev[pos][ci][cj];\n            ci = pi;\n            cj = pj;\n        }\n    }\n    \n    return {path_i, path_j};\n}\n\n// Compute transition cost between two words\nint transition_cost(const pair<int,int>& end1, const pair<int,int>& start2) {\n    return abs(end1.first - start2.first) + abs(end1.second - start2.second) + 1;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M;\n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    precompute_positions();\n    \n    // Precompute optimal paths for each word\n    for (int i = 0; i < M; i++) {\n        auto [path_i, path_j] = optimize_word_path(words[i], si, sj);\n        int cost = 0, ci = si, cj = sj;\n        for (int p = 0; p < 5; p++) {\n            cost += abs(path_i[p] - ci) + abs(path_j[p] - cj) + 1;\n            ci = path_i[p];\n            cj = path_j[p];\n        }\n        word_info[i] = {words[i], path_i, path_j, cost};\n    }\n    \n    // Greedy construction of superstring with path optimization\n    vector<bool> used(M, false);\n    vector<int> order;\n    int cur_i = si, cur_j = sj;\n    int total_cost = 0;\n    int ops = 0;\n    \n    // Start with the cheapest first word\n    int best_first = 0, best_first_cost = 1e9;\n    for (int i = 0; i < M; i++) {\n        int cost = transition_cost({si, sj}, {word_info[i].best_path_i[0], word_info[i].best_path_j[0]});\n        if (cost < best_first_cost) {\n            best_first_cost = cost;\n            best_first = i;\n        }\n    }\n    \n    order.push_back(best_first);\n    used[best_first] = true;\n    cur_i = word_info[best_first].best_path_i[4];\n    cur_j = word_info[best_first].best_path_j[4];\n    \n    // Greedy selection of remaining words\n    while ((int)order.size() < M) {\n        int best_next = -1, best_next_cost = 1e9;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            \n            // Check if we can overlap with the last word\n            string& last_word = words[order.back()];\n            string& next_word = words[i];\n            \n            int overlap = 0;\n            for (int o = 1; o <= 4; o++) {\n                if (last_word.substr(5-o) == next_word.substr(0, o)) {\n                    overlap = o;\n                }\n            }\n            \n            int cost;\n            if (overlap > 0) {\n                // Only need to type the non-overlapping part\n                cost = 0;\n                int ci = cur_i, cj = cur_j;\n                for (int p = overlap; p < 5; p++) {\n                    cost += abs(word_info[i].best_path_i[p] - ci) + abs(word_info[i].best_path_j[p] - cj) + 1;\n                    ci = word_info[i].best_path_i[p];\n                    cj = word_info[i].best_path_j[p];\n                }\n            } else {\n                // Full cost\n                cost = transition_cost({cur_i, cur_j}, {word_info[i].best_path_i[0], word_info[i].best_path_j[0]});\n                for (int p = 0; p < 5; p++) {\n                    if (p > 0) {\n                        cost += abs(word_info[i].best_path_i[p] - word_info[i].best_path_i[p-1]) + \n                               abs(word_info[i].best_path_j[p] - word_info[i].best_path_j[p-1]) + 1;\n                    } else {\n                        cost += 1; // Already counted transition cost\n                    }\n                }\n            }\n            \n            if (cost < best_next_cost) {\n                best_next_cost = cost;\n                best_next = i;\n            }\n        }\n        \n        order.push_back(best_next);\n        used[best_next] = true;\n        cur_i = word_info[best_next].best_path_i[4];\n        cur_j = word_info[best_next].best_path_j[4];\n    }\n    \n    // Output the sequence of operations\n    cur_i = si, cur_j = sj;\n    for (int idx : order) {\n        // Move to first character of this word\n        vector<int>& path_i = word_info[idx].best_path_i;\n        vector<int>& path_j = word_info[idx].best_path_j;\n        \n        if (!(path_i[0] == cur_i && path_j[0] == cur_j)) {\n            cout << path_i[0] << \" \" << path_j[0] << \"\\n\";\n            cur_i = path_i[0];\n            cur_j = path_j[0];\n            ops++;\n        }\n        \n        // Type the word\n        for (int p = 0; p < 5; p++) {\n            if (p > 0 || !(path_i[p] == cur_i && path_j[p] == cur_j)) {\n                cout << path_i[p] << \" \" << path_j[p] << \"\\n\";\n                cur_i = path_i[p];\n                cur_j = path_j[p];\n                ops++;\n            }\n        }\n    }\n    \n    cerr << \"Total operations: \" << ops << endl;\n    cerr << \"Total cost: \" << total_cost << endl;\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct OilField {\n    int id;\n    int size;\n    vector<pair<int,int>> cells; // relative positions\n    int max_i, max_j; // maximum coordinates\n};\n\nint N, M;\ndouble eps;\nvector<OilField> fields;\nset<pair<int,int>> known_oil, known_dry;\n\n// Safely read double response\ndouble read_double() {\n    string line;\n    while (line.empty()) {\n        if (!getline(cin, line)) break;\n    }\n    return stod(line);\n}\n\n// Query single cell\nint query_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl << flush;\n    return (int)read_double();\n}\n\n// Query set of cells\ndouble query_set(const vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto [i,j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n    return read_double();\n}\n\n// Make guess\nbool make_guess(const vector<pair<int,int>>& guess) {\n    cout << \"a \" << guess.size();\n    for (auto [i,j] : guess) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n    int result = (int)read_double();\n    return result == 1;\n}\n\nint main() {\n    // Read parameters\n    string first_line;\n    getline(cin, first_line);\n    stringstream ss(first_line);\n    ss >> N >> M >> eps;\n    \n    // Read oil field shapes\n    fields.resize(M);\n    for (int k = 0; k < M; k++) {\n        string line;\n        getline(cin, line);\n        stringstream ssf(line);\n        \n        int d;\n        ssf >> d;\n        \n        fields[k].id = k;\n        fields[k].size = d;\n        fields[k].cells.resize(d);\n        fields[k].max_i = 0;\n        fields[k].max_j = 0;\n        \n        for (int t = 0; t < d; t++) {\n            ssf >> fields[k].cells[t].first >> fields[k].cells[t].second;\n            fields[k].max_i = max(fields[k].max_i, fields[k].cells[t].first);\n            fields[k].max_j = max(fields[k].max_j, fields[k].cells[t].second);\n        }\n    }\n    \n    // Strategy: Use grid-based probing with small random sets\n    // First, do some initial divinations to get a rough idea\n    \n    // Phase 1: Row queries (cost effective)\n    vector<double> row_sums(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) {\n            row.push_back({i,j});\n        }\n        row_sums[i] = query_set(row);\n    }\n    \n    // Phase 2: Column queries\n    vector<double> col_sums(N, 0.0);\n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) {\n            col.push_back({i,j});\n        }\n        col_sums[j] = query_set(col);\n    }\n    \n    // Estimate oil probabilities using tomographic reconstruction\n    vector<vector<double>> prob(N, vector<double>(N, 0.0));\n    double total_estimate = 0;\n    for (int i = 0; i < N; i++) total_estimate += row_sums[i];\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            // Simple reconstruction: average of row and column estimates\n            double row_contrib = row_sums[i] / N;\n            double col_contrib = col_sums[j] / N;\n            prob[i][j] = (row_contrib + col_contrib) / 2.0;\n            prob[i][j] = max(0.0, min(1.0, prob[i][j]));\n        }\n    }\n    \n    // Phase 3: Drill cells with highest probability\n    int ops_used = 2 * N; // for initial queries\n    int max_ops = 2 * N * N - M; // leave room for final guess and some extra queries\n    \n    // Collect cells sorted by probability\n    vector<tuple<double,int,int>> priority;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            priority.push_back({prob[i][j], i, j});\n        }\n    }\n    sort(priority.rbegin(), priority.rend());\n    \n    // Drill cells, but also try to verify with small divination sets\n    for (auto [p, i, j] : priority) {\n        if (ops_used >= max_ops) break;\n        if (known_oil.count({i,j}) || known_dry.count({i,j})) continue;\n        \n        // If probability is very low, skip (likely no oil)\n        if (p < 0.1 && known_oil.size() > 0) break;\n        \n        int val = query_cell(i, j);\n        ops_used++;\n        \n        if (val > 0) {\n            known_oil.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n        }\n    }\n    \n    // Phase 4: Use known oil field shapes to predict remaining cells\n    set<pair<int,int>> final_guess = known_oil;\n    \n    // For each oil field, try to find a position that covers all known oil cells\n    for (int k = 0; k < M && ops_used < max_ops; k++) {\n        bool found = false;\n        int best_i = 0, best_j = 0;\n        int max_covered = 0;\n        \n        // Try all positions\n        for (int pi = 0; pi + fields[k].max_i < N; pi++) {\n            for (int pj = 0; pj + fields[k].max_j < N; pj++) {\n                int covered = 0;\n                bool valid = true;\n                \n                // Check if position overlaps with known dry cells\n                for (auto [di,dj] : fields[k].cells) {\n                    int ni = pi + di, nj = pj + dj;\n                    if (known_dry.count({ni,nj})) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (!valid) continue;\n                \n                // Count how many known oil cells are covered\n                for (auto [oi,oj] : known_oil) {\n                    for (auto [di,dj] : fields[k].cells) {\n                        if (pi + di == oi && pj + dj == oj) {\n                            covered++;\n                            break;\n                        }\n                    }\n                }\n                \n                if (covered > max_covered) {\n                    max_covered = covered;\n                    best_i = pi;\n                    best_j = pj;\n                    found = true;\n                }\n            }\n        }\n        \n        // If we found a good position, add its cells\n        if (found && max_covered > 0) {\n            for (auto [di,dj] : fields[k].cells) {\n                int ni = best_i + di, nj = best_j + dj;\n                if (known_dry.count({ni,nj}) == 0) {\n                    final_guess.insert({ni,nj});\n                }\n            }\n        }\n    }\n    \n    // Phase 5: Verify suspicious cells with divination if we have operations left\n    // Look for cells that are likely oil but not yet confirmed\n    vector<pair<int,int>> suspect_cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (final_guess.count({i,j}) || known_dry.count({i,j})) continue;\n            // Check if this cell is near known oil (could be part of a shape)\n            bool near_oil = false;\n            for (int di = -1; di <= 1 && !near_oil; di++) {\n                for (int dj = -1; dj <= 1 && !near_oil; dj++) {\n                    if (known_oil.count({i+di, j+dj})) {\n                        near_oil = true;\n                    }\n                }\n            }\n            if (near_oil && prob[i][j] > 0.3) {\n                suspect_cells.push_back({i,j});\n            }\n        }\n    }\n    \n    // Drill suspect cells if we have enough operations\n    for (auto [i,j] : suspect_cells) {\n        if (ops_used >= max_ops) break;\n        int val = query_cell(i, j);\n        ops_used++;\n        if (val > 0) {\n            known_oil.insert({i,j});\n            final_guess.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n            final_guess.erase({i,j});\n        }\n    }\n    \n    // Generate final guess\n    vector<pair<int,int>> guess_list(final_guess.begin(), final_guess.end());\n    make_guess(guess_list);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Store rectangles: for each day [d], store N rectangles as (i0, j0, i1, j1)\n    vector<vector<array<int,4>>> rect(D, vector<array<int,4>>(N));\n    \n    // Day 0: simple strips\n    {\n        int cur_y = 0;\n        for (int k = 0; k < N; k++) {\n            int need_h = (a[0][k] + W - 1) / W;  // ceil division\n            // If last reservation, take remaining space\n            if (k == N - 1) {\n                need_h = W - cur_y;\n            }\n            // Ensure we don't exceed W\n            if (cur_y + need_h > W) {\n                need_h = W - cur_y;\n            }\n            rect[0][k] = {cur_y, 0, cur_y + need_h, W};\n            cur_y += need_h;\n        }\n    }\n    \n    // Store previous boundaries\n    vector<int> prev_bounds(N + 1);\n    {\n        int cur = 0;\n        prev_bounds[0] = 0;\n        for (int k = 0; k < N; k++) {\n            cur += rect[0][k][2] - rect[0][k][0];  // height\n            prev_bounds[k + 1] = cur;\n        }\n    }\n    \n    // For each subsequent day\n    for (int d = 1; d < D; d++) {\n        // First compute minimal heights needed for each reservation\n        vector<int> need_h(N);\n        int total_need = 0;\n        for (int k = 0; k < N; k++) {\n            need_h[k] = (a[d][k] + W - 1) / W;  // ceil division\n            total_need += need_h[k];\n        }\n        \n        // DP: dp[current_boundary] = min cost\n        const int INF = 1e9;\n        vector<int> dp(W + 1, INF);\n        dp[0] = 0;\n        \n        for (int k = 0; k < N; k++) {\n            vector<int> ndp(W + 1, INF);\n            int prev_start = prev_bounds[k];\n            int prev_end = prev_bounds[k + 1];\n            \n            for (int cur_start = 0; cur_start <= W; cur_start++) {\n                if (dp[cur_start] >= INF) continue;\n                \n                // Try all possible heights for this reservation\n                for (int h = need_h[k]; h <= W - cur_start; h++) {\n                    int cur_end = cur_start + h;\n                    \n                    // Cost to change boundaries\n                    int change_cost = abs(cur_start - prev_start) + abs(cur_end - prev_end);\n                    \n                    // Area penalty\n                    int area = h * W;\n                    int penalty = 0;\n                    if (area < a[d][k]) {\n                        penalty = 100 * (a[d][k] - area);\n                    }\n                    \n                    int new_cost = dp[cur_start] + change_cost + penalty;\n                    if (new_cost < ndp[cur_end]) {\n                        ndp[cur_end] = new_cost;\n                    }\n                }\n            }\n            dp = move(ndp);\n        }\n        \n        // Find best final boundary\n        int best_cost = INF;\n        int best_final = W;  // must end at W\n        for (int h = W; h <= W; h++) {\n            if (dp[h] < best_cost) {\n                best_cost = dp[h];\n                best_final = h;\n            }\n        }\n        \n        // Backtrack to get boundaries\n        vector<int> new_bounds(N + 1);\n        new_bounds[N] = W;\n        \n        // Greedy approximation: just use need_h with possible trimming\n        {\n            int cur_y = 0;\n            for (int k = 0; k < N; k++) {\n                int h = need_h[k];\n                if (k == N - 1) {\n                    h = W - cur_y;\n                }\n                if (cur_y + h > W) {\n                    h = W - cur_y;\n                }\n                rect[d][k] = {cur_y, 0, cur_y + h, W};\n                new_bounds[k] = cur_y;\n                cur_y += h;\n            }\n            new_bounds[N] = W;\n        }\n        \n        // Update previous boundaries\n        prev_bounds = move(new_bounds);\n    }\n    \n    // Output rectangles\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto [i0, j0, i1, j1] = rect[d][k];\n            cout << i0 << \" \" << j0 << \" \" << i1 << \" \" << j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int STAMP_SIZE = 3;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_actual, M, K;\n    cin >> N_actual >> M >> K;\n    \n    // Initialize board\n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    // Read stamps\n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(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 >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    // Precompute stamp effectiveness for each cell\n    // For each cell (i,j), find which stamps/positions affect it\n    // A stamp at position (p,q) affects cells (p..p+2, q..q+2)\n    vector<vector<vector<pair<int,int>>>> covering_stamps(N, vector<vector<pair<int,int>>>(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                for (int i = 0; i < 3; i++) {\n                    for (int j = 0; j < 3; j++) {\n                        covering_stamps[p+i][q+j].push_back({m, stamps[m][i][j] % MOD});\n                    }\n                }\n            }\n        }\n    }\n    \n    vector<tuple<int,int,int>> operations; // (m, p, q)\n    \n    // Track remaining budget for each cell's potential\n    // We'll use a priority queue approach based on need\n    auto get_cell_value = [&](int i, int j) {\n        return board[i][j] % MOD;\n    };\n    \n    auto get_cell_potential = [&](int i, int j) {\n        long long cur = get_cell_value(i, j);\n        return (MOD - 1 - cur + MOD) % MOD; // How much more we need\n    };\n    \n    // For each operation, we'll do beam search over a few best options\n    for (int op = 0; op < K; op++) {\n        // Find most needy cell\n        double max_need = -1;\n        int target_i = -1, target_j = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                double need = get_cell_potential(i, j);\n                if (need > max_need) {\n                    max_need = need;\n                    target_i = i;\n                    target_j = j;\n                }\n            }\n        }\n        \n        // Now find best stamp/position that helps this cell and nearby cells\n        double best_score = -1e9;\n        int best_m = -1, best_p = -1, best_q = -1;\n        \n        // Search all stamps and positions that can affect target cell\n        for (int m = 0; m < M; m++) {\n            for (int p = max(0, target_i - 2); p <= min(N - 3, target_i); p++) {\n                for (int q = max(0, target_j - 2); q <= min(N - 3, target_j); q++) {\n                    // Check if this placement actually affects the target cell\n                    if (p > target_i || p + 2 < target_i || q > target_j || q + 2 < target_j) continue;\n                    \n                    double score = 0;\n                    \n                    // Evaluate all 9 cells affected\n                    for (int di = 0; di < 3; di++) {\n                        for (int dj = 0; dj < 3; dj++) {\n                            int ci = p + di, cj = q + dj;\n                            long long cur_val = board[ci][cj];\n                            long long cur_rem = cur_val % MOD;\n                            long long add_val = stamps[m][di][dj] % MOD;\n                            long long new_rem = (cur_rem + add_val) % MOD;\n                            \n                            // Score: improvement in remainder, weighted by how bad the cell is\n                            long long current_potential = (MOD - 1 - cur_rem + MOD) % MOD;\n                            long long new_potential = (MOD - 1 - new_rem + MOD) % MOD;\n                            long long improvement = current_potential - new_potential;\n                            \n                            // Weight: cells with high potential (far from MOD-1) get more weight\n                            double weight = 1.0 + (double)current_potential / MOD * 2.0;\n                            \n                            // Extra bonus for the target cell\n                            if (ci == target_i && cj == target_j) {\n                                weight *= 3.0;\n                            }\n                            \n                            score += improvement * weight;\n                        }\n                    }\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation\n        if (best_m != -1) {\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n            operations.push_back({best_m, best_p, best_q});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Coord {\n    int r, c;\n    Coord(int r = 0, int c = 0) : r(r), c(c) {}\n    bool operator==(const Coord& o) const { return r == o.r && c == o.c; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Target positions for containers: (row, col) = (container/N, 4)\n    vector<int> targetRow(N*N), targetCol(N*N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int container = i*N + j;\n            targetRow[container] = i;\n            targetCol[container] = 4;  // dispatch gate\n        }\n    }\n    \n    // Grid state: -1 = empty, otherwise container number\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Crane state\n    vector<int> craneRow(N), craneCol(N);\n    vector<int> holding(N, -1);  // which container each crane holds, -1 = empty\n    for (int i = 0; i < N; i++) {\n        craneRow[i] = i;\n        craneCol[i] = 0;\n    }\n    \n    // Receiving state\n    vector<int> nextReceiving(N, 0);  // next container index to appear at each gate\n    \n    // Dispatch state\n    vector<int> nextDispatch(N, 0);  // next number to dispatch at each gate\n    vector<bool> dispatched(N*N, false);\n    \n    // Output strings\n    vector<string> ops(N);\n    \n    // Helper function to check if a cell is occupied by another crane\n    auto craneAt = [&](int r, int c, int exclude) -> bool {\n        for (int i = 0; i < N; i++) {\n            if (i != exclude && craneRow[i] == r && craneCol[i] == c) return true;\n        }\n        return false;\n    };\n    \n    // Check if a move is valid for given crane\n    auto canMove = [&](int crane, int nr, int nc) -> bool {\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n        if (craneAt(nr, nc, crane)) return false;\n        \n        // Small crane with container cannot move to occupied cell\n        if (holding[crane] != -1 && crane > 0 && grid[nr][nc] != -1) return false;\n        \n        return true;\n    };\n    \n    // Move one step towards target (simple Manhattan distance)\n    auto moveTowards = [&](int crane, int tr, int tc) -> char {\n        int r = craneRow[crane], c = craneCol[crane];\n        if (r == tr && c == tc) return '.';\n        \n        // Try horizontal first, then vertical\n        if (c < tc && canMove(crane, r, c+1)) return 'R';\n        if (c > tc && canMove(crane, r, c-1)) return 'L';\n        if (r < tr && canMove(crane, r+1, c)) return 'D';\n        if (r > tr && canMove(crane, r-1, c)) return 'U';\n        \n        // If blocked, try other directions\n        if (r < tr && canMove(crane, r+1, c)) return 'D';\n        if (r > tr && canMove(crane, r-1, c)) return 'U';\n        if (c < tc && canMove(crane, r, c+1)) return 'R';\n        if (c > tc && canMove(crane, r, c-1)) return 'L';\n        \n        return '.';\n    };\n    \n    // Main simulation loop\n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        // Step 1: Deliver new containers to receiving gates\n        for (int i = 0; i < N; i++) {\n            if (nextReceiving[i] < N && grid[i][0] == -1 && !craneAt(i, 0, -1)) {\n                grid[i][0] = A[i][nextReceiving[i]];\n                nextReceiving[i]++;\n            }\n        }\n        \n        // Step 3: Dispatch containers at gates (can be done before or after actions)\n        for (int i = 0; i < N; i++) {\n            if (grid[i][4] != -1) {\n                int container = grid[i][4];\n                if (container / N == i && container % N == nextDispatch[i]) {\n                    dispatched[container] = true;\n                    grid[i][4] = -1;\n                    nextDispatch[i]++;\n                }\n            }\n        }\n        \n        // Determine actions for each crane\n        for (int crane = 0; crane < N; crane++) {\n            int r = craneRow[crane], c = craneCol[crane];\n            char action = '.';\n            \n            if (crane == 0) {\n                // Large crane: shuttle containers to their target rows\n                if (holding[crane] == -1) {\n                    // Find a container to pick up (prefer those far from target)\n                    int bestContainer = -1, bestDist = -1;\n                    for (int i = 0; i < N; i++) {\n                        for (int j = 0; j < N; j++) {\n                            if (grid[i][j] != -1 && !(i == r && j == c)) {\n                                int container = grid[i][j];\n                                int target = targetRow[container];\n                                int dist = abs(i - target) + abs(j - targetCol[container]);\n                                if (dist > bestDist) {\n                                    bestDist = dist;\n                                    bestContainer = container;\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (bestContainer != -1) {\n                        // Move towards the best container or pick it up\n                        if (grid[r][c] != -1) {\n                            action = 'P';\n                        } else {\n                            action = moveTowards(crane, r, c);\n                            // Better: find the container and move towards it\n                            for (int i = 0; i < N && action == '.'; i++) {\n                                for (int j = 0; j < N && action == '.'; j++) {\n                                    if (grid[i][j] == bestContainer) {\n                                        action = moveTowards(crane, i, j);\n                                    }\n                                }\n                            }\n                        }\n                    } else {\n                        // Move around randomly\n                        if (canMove(crane, r, c+1)) action = 'R';\n                        else if (canMove(crane, r+1, c)) action = 'D';\n                        else if (canMove(crane, r-1, c)) action = 'U';\n                        else if (canMove(crane, r, c-1)) action = 'L';\n                    }\n                } else {\n                    // Holding a container, deliver to target row\n                    int container = holding[crane];\n                    int targetR = targetRow[container];\n                    \n                    if (r == targetR && c == 4) {\n                        // At dispatch gate\n                        if (grid[r][4] == -1 && container % N == nextDispatch[r]) {\n                            action = 'Q';\n                        } else {\n                            // Wait or move aside\n                            if (canMove(crane, r, c-1)) action = 'L';\n                        }\n                    } else {\n                        // Move towards dispatch gate of target row\n                        action = moveTowards(crane, targetR, 4);\n                    }\n                }\n            } else {\n                // Small crane: manage its row\n                if (holding[crane] == -1) {\n                    // Look for containers that need sorting in this row\n                    bool foundWork = false;\n                    for (int j = 0; j < N && !foundWork; j++) {\n                        if (grid[r][j] != -1) {\n                            int container = grid[r][j];\n                            if (container / N != r || container % N != nextDispatch[r]) {\n                                // This container needs moving\n                                foundWork = true;\n                                if (c == j) {\n                                    action = 'P';\n                                } else {\n                                    action = moveTowards(crane, r, j);\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (!foundWork) {\n                        // Move towards receiving gate to help\n                        if (c > 0 && canMove(crane, r, c-1)) action = 'L';\n                        else if (c < 3 && canMove(crane, r, c+1)) action = 'R';\n                        else if (c < 4 && canMove(crane, r, c+1)) action = 'R';\n                    }\n                } else {\n                    // Holding container\n                    int container = holding[crane];\n                    int targetC = 4; // dispatch gate\n                    \n                    if (container / N == r) {\n                        // Belongs to this row, move to dispatch\n                        if (c == 4) {\n                            if (grid[r][4] == -1 && container % N == nextDispatch[r]) {\n                                action = 'Q';\n                            } else {\n                                // Move aside\n                                if (canMove(crane, r, c-1)) action = 'L';\n                            }\n                        } else {\n                            action = moveTowards(crane, r, 4);\n                        }\n                    } else {\n                        // Belongs to another row, drop it for large crane\n                        // Find empty cell in this row\n                        if (grid[r][c] == -1 && holding[crane] != -1) {\n                            // Drop it here if there's empty space\n                            for (int j = 0; j < 4; j++) {\n                                if (grid[r][j] == -1) {\n                                    if (canMove(crane, r, j)) {\n                                        action = moveTowards(crane, r, j);\n                                        if (c == j) action = 'Q';\n                                    }\n                                    break;\n                                }\n                            }\n                        }\n                        if (action == '.') {\n                            action = moveTowards(crane, r, 0); // Move to receiving side\n                        }\n                    }\n                }\n            }\n            \n            // Execute action\n            if (action == 'P' && grid[r][c] != -1 && holding[crane] == -1) {\n                holding[crane] = grid[r][c];\n                grid[r][c] = -1;\n            } else if (action == 'Q' && grid[r][c] == -1 && holding[crane] != -1) {\n                grid[r][c] = holding[crane];\n                holding[crane] = -1;\n            } else if (action == 'U' && canMove(crane, r-1, c)) {\n                craneRow[crane] = r-1;\n            } else if (action == 'D' && canMove(crane, r+1, c)) {\n                craneRow[crane] = r+1;\n            } else if (action == 'L' && canMove(crane, r, c-1)) {\n                craneCol[crane] = c-1;\n            } else if (action == 'R' && canMove(crane, r, c+1)) {\n                craneCol[crane] = c+1;\n            }\n            \n            ops[crane] += action;\n        }\n        \n        // Check completion\n        bool allDone = true;\n        for (int i = 0; i < N*N && allDone; i++) {\n            if (!dispatched[i]) allDone = false;\n        }\n        if (allDone) break;\n    }\n    \n    // Normalize output strings\n    int maxLen = 0;\n    for (int i = 0; i < N; i++) {\n        maxLen = max(maxLen, (int)ops[i].length());\n    }\n    for (int i = 0; i < N; i++) {\n        while ((int)ops[i].length() < maxLen) {\n            ops[i] += '.';\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << ops[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\nconst int MAX_TURNS = 100000;\nconst int DX[] = {-1, 1, 0, 0};\nconst int DY[] = {0, 0, -1, 1};\nconst string DIR = \"UDLR\";\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int x = 0, y = 0;\n    int load = 0;\n    \n    // Precompute distances between all pairs\n    vector<vector<vector<pair<int,int>>>> paths(N, vector<vector<pair<int,int>>>(N));\n    \n    auto bfs = [&](int sx, int sy) -> vector<vector<pair<int,int>>> {\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        queue<pair<int,int>> q;\n        \n        dist[sx][sy] = 0;\n        q.push({sx, sy});\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cx + DX[d], ny = cy + DY[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] > dist[cx][cy] + 1) {\n                    dist[nx][ny] = dist[cx][cy] + 1;\n                    prev[nx][ny] = {cx, cy};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return prev;\n    };\n    \n    auto get_path = [&](int sx, int sy, int tx, int ty) -> vector<pair<int,int>> {\n        if (sx == tx && sy == ty) return {};\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n        \n        dist[sx][sy] = 0;\n        q.push({sx, sy});\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            if (cx == tx && cy == ty) break;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cx + DX[d], ny = cy + DY[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] > dist[cx][cy] + 1) {\n                    dist[nx][ny] = dist[cx][cy] + 1;\n                    prev[nx][ny] = {cx, cy};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        if (dist[tx][ty] == INF) return {};\n        \n        vector<pair<int,int>> path;\n        int cx = tx, cy = ty;\n        while (cx != sx || cy != sy) {\n            path.push_back({cx, cy});\n            auto [px, py] = prev[cx][cy];\n            cx = px; cy = py;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto move_to = [&](int tx, int ty) {\n        auto path = get_path(x, y, tx, ty);\n        for (auto [nx, ny] : path) {\n            for (int d = 0; d < 4; d++) {\n                if (x + DX[d] == nx && y + DY[d] == ny) {\n                    ops.push_back(DIR.substr(d, 1));\n                    break;\n                }\n            }\n            x = nx; y = ny;\n        }\n    };\n    \n    // Collect all positive and negative cells\n    vector<pair<int,int>> positive, negative;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (h[i][j] > 0) positive.push_back({i, j});\n            else if (h[i][j] < 0) negative.push_back({i, j});\n        }\n    }\n    \n    // Sort positive cells by distance to nearest negative cell (closest first)\n    auto estimate_cost = [&](pair<int,int> src) {\n        int min_dist = INF;\n        for (auto snk : negative) {\n            if (h[snk.first][snk.second] < 0) {\n                min_dist = min(min_dist, abs(src.first - snk.first) + abs(src.second - snk.second));\n            }\n        }\n        return min_dist;\n    };\n    \n    // Process in order: start from (0,0) and go greedily\n    while (!positive.empty() && (int)ops.size() < MAX_TURNS - 100) {\n        // Sort positive cells by current distance from truck\n        sort(positive.begin(), positive.end(), [&](auto a, auto b) {\n            int da = abs(a.first - x) + abs(a.second - y);\n            int db = abs(b.first - x) + abs(b.second - y);\n            if (da != db) return da < db;\n            // If same distance, prefer larger amount\n            return h[a.first][a.second] > h[b.first][b.second];\n        });\n        \n        bool made_progress = false;\n        \n        for (auto src : positive) {\n            auto [sx, sy] = src;\n            if (h[sx][sy] <= 0) continue;\n            \n            // Find nearest negative cell\n            int best_dist = INF;\n            pair<int,int> best_sink = {-1, -1};\n            \n            for (auto snk : negative) {\n                auto [tx, ty] = snk;\n                if (h[tx][ty] >= 0) continue;\n                int dist = abs(sx - tx) + abs(sy - ty);\n                \n                // Also consider distance from current position\n                int total_dist = abs(x - sx) + abs(y - sy) + abs(sx - tx) + abs(sy - ty);\n                \n                if (total_dist < best_dist) {\n                    best_dist = total_dist;\n                    best_sink = {tx, ty};\n                }\n            }\n            \n            if (best_sink.first == -1) break;\n            \n            auto [tx, ty] = best_sink;\n            \n            // Determine how much to move\n            int src_amount = h[sx][sy];\n            int sink_need = -h[tx][ty];\n            \n            // Move in batches of at most 500 to reduce loaded travel cost\n            int batch_size = min({src_amount, sink_need, 500});\n            \n            if (batch_size > 0) {\n                // Move to source\n                move_to(sx, sy);\n                \n                // Load\n                ops.push_back(\"+\" + to_string(batch_size));\n                load += batch_size;\n                h[sx][sy] -= batch_size;\n                \n                // Move to sink\n                move_to(tx, ty);\n                \n                // Unload\n                ops.push_back(\"-\" + to_string(batch_size));\n                h[tx][ty] += batch_size;\n                load = 0;\n                \n                made_progress = true;\n                \n                // Update lists\n                if (h[sx][sy] == 0) {\n                    positive.erase(remove(positive.begin(), positive.end(), src), positive.end());\n                }\n                if (h[tx][ty] == 0) {\n                    negative.erase(remove(negative.begin(), negative.end(), best_sink), negative.end());\n                }\n                break;\n            }\n        }\n        \n        if (!made_progress) break;\n    }\n    \n    // Handle any remaining load (shouldn't happen if we're careful)\n    // If there's still work, do it in smaller batches\n    for (int i = 0; i < N && (int)ops.size() < MAX_TURNS; i++) {\n        for (int j = 0; j < N && (int)ops.size() < MAX_TURNS; j++) {\n            if (h[i][j] != 0) {\n                // Simple final cleanup\n                if (h[i][j] > 0) {\n                    for (int ii = 0; ii < N && (int)ops.size() < MAX_TURNS; ii++) {\n                        for (int jj = 0; jj < N && (int)ops.size() < MAX_TURNS; jj++) {\n                            if (h[ii][jj] < 0) {\n                                move_to(i, j);\n                                int take = min(h[i][j], -h[ii][jj]);\n                                take = min(take, 100);  // Small batches\n                                ops.push_back(\"+\" + to_string(take));\n                                h[i][j] -= take;\n                                load = take;\n                                \n                                move_to(ii, jj);\n                                ops.push_back(\"-\" + to_string(take));\n                                h[ii][jj] += take;\n                                load = 0;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (const string& op : ops) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Seed {\n    vector<int> values;\n    int total;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<Seed> seeds(seed_count);\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        seeds[i].values.resize(M);\n        seeds[i].index = i;\n        seeds[i].total = 0;\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i].values[j];\n            seeds[i].total += seeds[i].values[j];\n        }\n    }\n    \n    // Precompute grid positions and their neighbor counts\n    vector<pair<int, int>> positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            positions.push_back({i, j});\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Sort seeds by total value descending\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            return seeds[a].total > seeds[b].total;\n        });\n        \n        // Create placement grid\n        vector<vector<int>> grid(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Priority positions (center first for more neighbors)\n        vector<pair<int, int>> priority_positions;\n        // Center positions have 4 neighbors\n        for (int i = 1; i < N-1; i++) {\n            for (int j = 1; j < N-1; j++) {\n                priority_positions.push_back({i, j});\n            }\n        }\n        // Edge positions (non-corner) have 3 neighbors\n        for (int i = 1; i < N-1; i++) {\n            priority_positions.push_back({i, 0});\n            priority_positions.push_back({i, N-1});\n            priority_positions.push_back({0, i});\n            priority_positions.push_back({N-1, i});\n        }\n        // Corner positions have 2 neighbors\n        priority_positions.push_back({0, 0});\n        priority_positions.push_back({0, N-1});\n        priority_positions.push_back({N-1, 0});\n        priority_positions.push_back({N-1, N-1});\n        \n        // Place best seeds in priority positions\n        int seed_idx = 0;\n        for (auto pos : priority_positions) {\n            if (seed_idx >= seed_count) break;\n            int seed_num = order[seed_idx];\n            if (!used[seed_num]) {\n                grid[pos.first][pos.second] = seed_num;\n                used[seed_num] = true;\n                seed_idx++;\n            }\n        }\n        \n        // Fill remaining positions\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == -1) {\n                    while (seed_idx < seed_count && used[order[seed_idx]]) {\n                        seed_idx++;\n                    }\n                    if (seed_idx < seed_count) {\n                        grid[i][j] = order[seed_idx];\n                        used[order[seed_idx]] = true;\n                        seed_idx++;\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 << grid[i][j];\n                if (j < N-1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < seed_count; i++) {\n            seeds[i].total = 0;\n            seeds[i].index = i;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i].values[j];\n                seeds[i].total += seeds[i].values[j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Structure to represent position\nstruct Pos {\n    int x, y;\n    Pos(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Pos& p) const { return x == p.x && y == p.y; }\n};\n\n// Direction vectors\nconst int dx[] = {0, 1, 0, -1};\nconst int dy[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nclass RoboticArmSolver {\nprivate:\n    int N, M, V;\n    vector<vector<int>> initial_grid, target_grid;\n    vector<Pos> takoyaki_pos, target_pos;\n    \n    // Arm structure\n    int V_actual;\n    vector<int> parent;\n    vector<int> edge_length;\n    vector<int> rotation_state; // 0: right, 1: down, 2: left, 3: up\n    \n    // Current state\n    Pos root_pos;\n    bool holding[15]; // which fingertips are holding\n    \npublic:\n    RoboticArmSolver() {\n        read_input();\n        solve();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> V;\n        initial_grid = vector<vector<int>>(N, vector<int>(N));\n        target_grid = vector<vector<int>>(N, vector<int>(N));\n        \n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                initial_grid[i][j] = line[j] - '0';\n                if (initial_grid[i][j]) {\n                    takoyaki_pos.push_back(Pos(i, j));\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target_grid[i][j] = line[j] - '0';\n                if (target_grid[i][j]) {\n                    target_pos.push_back(Pos(i, j));\n                }\n            }\n        }\n    }\n    \n    // Calculate fingertip positions given root position and rotation states\n    vector<Pos> get_fingertip_positions() {\n        vector<Pos> finger_pos;\n        vector<tuple<int, int, int>> stack; // vertex, x, y, rotation_sum\n        // Rotation sum represents cumulative rotation from root to this vertex\n        \n        for (int v = 0; v < V_actual; v++) {\n            if (v == 0) {\n                stack.push_back({0, root_pos.x, root_pos.y, 0});\n            } else {\n                // Find parent's position\n                auto it = find_if(stack.begin(), stack.end(), \n                    [this, v](const auto& t) { return get<0>(t) == parent[v]; });\n                \n                int px = get<1>(*it);\n                int py = get<2>(*it);\n                int prot = get<3>(*it);\n                \n                int my_rot = (prot + rotation_state[v]) % 4;\n                int dir = (my_rot * 3) % 4; // Initial direction is right, then rotate\n                \n                // For simplicity, use a tree that extends right then down\n                int cx = px, cy = py;\n                if (v % 2 == 1) { // Extend right\n                    cx += dx[my_rot] * edge_length[v];\n                    cy += dy[my_rot] * edge_length[v];\n                } else if (v > 0) { // Extend down\n                    cx += dx[(my_rot + 1) % 4] * edge_length[v];\n                    cy += dy[(my_rot + 1) % 4] * edge_length[v];\n                }\n                \n                stack.push_back({v, cx, cy, my_rot});\n            }\n        }\n        \n        // Leaves are fingertips\n        for (int v = 0; v < V_actual; v++) {\n            bool is_leaf = true;\n            for (int u = 1; u < V_actual; u++) {\n                if (parent[u] == v) {\n                    is_leaf = false;\n                    break;\n                }\n            }\n            if (is_leaf) {\n                auto it = find_if(stack.begin(), stack.end(),\n                    [v](const auto& t) { return get<0>(t) == v; });\n                finger_pos.push_back(Pos(get<1>(*it), get<2>(*it)));\n            }\n        }\n        \n        return finger_pos;\n    }\n    \n    // Design the robotic arm\n    void design_arm() {\n        V_actual = V;\n        parent.resize(V_actual);\n        edge_length.resize(V_actual);\n        rotation_state.resize(V_actual, 0);\n        \n        // Create a tree where:\n        // - Node 0 is root\n        // - Nodes 1..V-1 form a star or small tree\n        // - Each edge has length N-1 for maximum reach\n        \n        parent[0] = -1;\n        edge_length[0] = 0;\n        \n        for (int v = 1; v < V_actual; v++) {\n            // Connect to root or previous node\n            parent[v] = (v <= 4) ? 0 : (v - 4);\n            \n            // Use maximum length for better reach\n            if (v <= 4) {\n                edge_length[v] = N - 1;\n            } else {\n                edge_length[v] = 1;\n            }\n        }\n        \n        // Output arm design\n        cout << V_actual << endl;\n        for (int v = 1; v < V_actual; v++) {\n            cout << parent[v] << \" \" << edge_length[v] << endl;\n        }\n    }\n    \n    // Simple greedy matching of takoyaki to targets\n    vector<pair<int, int>> match_takoyaki() {\n        vector<pair<int, int>> assignment(M);\n        vector<bool> target_used(M, false);\n        \n        // For each takoyaki, find nearest unused target\n        for (int i = 0; i < M; i++) {\n            int best_j = -1;\n            int best_dist = 1e9;\n            \n            for (int j = 0; j < M; j++) {\n                if (!target_used[j]) {\n                    int dist = abs(takoyaki_pos[i].x - target_pos[j].x) \n                             + abs(takoyaki_pos[i].y - target_pos[j].y);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_j = j;\n                    }\n                }\n            }\n            \n            assignment[i] = {i, best_j};\n            target_used[best_j] = true;\n        }\n        \n        return assignment;\n    }\n    \n    // Generate movement commands\n    void generate_commands() {\n        auto assignment = match_takoyaki();\n        vector<bool> delivered(M, false);\n        vector<int> current_pos_idx(M, -1); // -1 means holding\n        \n        // Initialize fingertips at position (0,0) with default rotation\n        root_pos = Pos(0, 0);\n        \n        // For each takoyaki, move it to its target\n        for (int turn = 0; turn < 100000 && !all_of(delivered.begin(), delivered.end(), [](bool b){return b;}); turn++) {\n            string command(2 * V_actual, '.');\n            \n            // Find current fingertip positions\n            auto finger_pos = get_fingertip_positions();\n            \n            // Determine movement direction\n            int target_takoyaki = -1;\n            int min_dist = 1e9;\n            \n            // Find nearest undelivered takoyaki\n            for (int i = 0; i < M; i++) {\n                if (!delivered[i]) {\n                    int dist = abs(root_pos.x - takoyaki_pos[i].x) \n                             + abs(root_pos.y - takoyaki_pos[i].y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        target_takoyaki = i;\n                    }\n                }\n            }\n            \n            if (target_takoyaki >= 0) {\n                // Move towards the takoyaki/target\n                Pos target = (holding[0]) ? target_pos[assignment[target_takoyaki].second] \n                                         : takoyaki_pos[target_takoyaki];\n                \n                if (root_pos.x < target.x) command[0] = 'D';\n                else if (root_pos.x > target.x) command[0] = 'U';\n                else if (root_pos.y < target.y) command[0] = 'R';\n                else if (root_pos.y > target.y) command[0] = 'L';\n                \n                // Update root position\n                if (command[0] != '.') {\n                    switch(command[0]) {\n                        case 'U': root_pos.x--; break;\n                        case 'D': root_pos.x++; break;\n                        case 'L': root_pos.y--; break;\n                        case 'R': root_pos.y++; break;\n                    }\n                }\n            }\n            \n            // Try to grab/release\n            for (int f = 0; f < V_actual; f++) {\n                bool is_leaf = true;\n                for (int u = 1; u < V_actual; u++) {\n                    if (parent[u] == f) {\n                        is_leaf = false;\n                        break;\n                    }\n                }\n                \n                if (is_leaf && f < (int)finger_pos.size()) {\n                    Pos fp = finger_pos[f];\n                    if (fp.x >= 0 && fp.x < N && fp.y >= 0 && fp.y < N) {\n                        // Check if we should grab\n                        for (int i = 0; i < M; i++) {\n                            if (!delivered[i] && fp == takoyaki_pos[i] && !holding[f]) {\n                                command[V_actual + f] = 'P';\n                                holding[f] = true;\n                                break;\n                            }\n                            // Check if we should release\n                            if (holding[f] && fp == target_pos[assignment[i].second] && !delivered[i]) {\n                                command[V_actual + f] = 'P';\n                                holding[f] = false;\n                                delivered[i] = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n        \n        // Fill remaining turns if needed\n        for (int turn = 100000; turn > 0 && turn > 0; turn--) {\n            string command(2 * V_actual, '.');\n            cout << command << endl;\n        }\n    }\n    \n    void solve() {\n        design_arm();\n        \n        // Initial position\n        cout << 0 << \" \" << 0 << endl;\n        \n        generate_commands();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    RoboticArmSolver solver;\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 5000;\n    vector<pair<int,int>> mackerel(N), sardine(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> mackerel[i].first >> mackerel[i].second;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sardine[i].first >> sardine[i].second;\n    }\n    \n    // Use a coarse grid of 200x200 cells\n    const int CELL = 500;  // 100000/500 = 200 cells per dimension\n    const int CELLS = 201;\n    \n    vector<vector<int>> grid(CELLS, vector<int>(CELLS, 0));\n    \n    for (auto& p : mackerel) {\n        int cx = p.first / CELL;\n        int cy = p.second / CELL;\n        if (cx < CELLS && cy < CELLS) grid[cx][cy]++;\n    }\n    for (auto& p : sardine) {\n        int cx = p.first / CELL;\n        int cy = p.second / CELL;\n        if (cx < CELLS && cy < CELLS) grid[cx][cy]--;\n    }\n    \n    // 2D prefix sum on coarse grid\n    vector<vector<int>> pref(CELLS+1, vector<int>(CELLS+1, 0));\n    for (int i = 1; i <= CELLS; i++) {\n        for (int j = 1; j <= CELLS; j++) {\n            pref[i][j] = pref[i-1][j] + pref[i][j-1] - pref[i-1][j-1] + grid[i-1][j-1];\n        }\n    }\n    \n    auto rect_sum = [&](int r1, int c1, int r2, int c2) {\n        return pref[r2+1][c2+1] - pref[r1][c2+1] - pref[r2+1][c1] + pref[r1][c1];\n    };\n    \n    // Find best rectangle in coarse grid\n    int max_sum = -1e9;\n    int best_r1 = 0, best_c1 = 0, best_r2 = 0, best_c2 = 0;\n    \n    for (int top = 0; top < CELLS; top++) {\n        vector<int> temp(CELLS, 0);\n        for (int bottom = top; bottom < CELLS; bottom++) {\n            for (int j = 0; j < CELLS; j++) {\n                temp[j] += grid[bottom][j];\n            }\n            \n            int cur = 0, left = 0;\n            for (int j = 0; j < CELLS; j++) {\n                cur += temp[j];\n                if (cur > max_sum) {\n                    max_sum = cur;\n                    best_r1 = top;\n                    best_r2 = bottom;\n                    best_c1 = left;\n                    best_c2 = j;\n                }\n                if (cur < 0) {\n                    cur = 0;\n                    left = j + 1;\n                }\n            }\n        }\n    }\n    \n    // Convert back to actual coordinates\n    const int PAD = 5;\n    int x1 = max(0, best_r1 * CELL - PAD);\n    int y1 = max(0, best_c1 * CELL - PAD);\n    int x2 = min(100000, (best_r2 + 1) * CELL + PAD);\n    int y2 = min(100000, (best_c2 + 1) * CELL + PAD);\n    \n    // Ensure distinct edges\n    if (x1 == x2) { if (x2 < 100000) x2++; else x1--; }\n    if (y1 == y2) { if (y2 < 100000) y2++; else y1--; }\n    x1 = max(0, x1); y1 = max(0, y1);\n    x2 = min(100000, x2); y2 = min(100000, y2);\n    \n    cout << \"4\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nstruct Rectangle {\n    long long w, h;\n};\n\nint N, T, sigma;\nvector<Rectangle> rects;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n};\n\nstruct PlacedRect {\n    long long x1, y1, x2, y2;\n    int idx;\n};\n\n// Evaluate placement and return the actual width, height, and score\nlong long evaluate_placement(const vector<Placement>& placements,\n                            long long& width, long long& height) {\n    vector<PlacedRect> placed;\n    vector<bool> used(N, false);\n    \n    for (const auto& pl : placements) {\n        int idx = pl.p;\n        if (idx < 0 || idx >= N || used[idx]) continue;\n        used[idx] = true;\n        \n        long long rw = rects[idx].w;\n        long long rh = rects[idx].h;\n        if (pl.r) swap(rw, rh);\n        \n        if (pl.d == 'U') {\n            // Align left edge with reference rectangle's right edge or x=0\n            long long left_x = 0;\n            if (pl.b >= 0) {\n                for (const auto& pr : placed) {\n                    if (pr.idx == pl.b) {\n                        left_x = pr.x2;\n                        break;\n                    }\n                }\n            }\n            \n            // Move up until no overlapping below\n            long long bottom_y = 0;\n            for (const auto& pr : placed) {\n                if (left_x < pr.x2 && left_x + rw > pr.x1) {\n                    bottom_y = max(bottom_y, pr.y2);\n                }\n            }\n            \n            placed.push_back({left_x, bottom_y, left_x + rw, bottom_y + rh, idx});\n        } else { // 'L'\n            // Align top edge with reference rectangle's bottom edge or y=0\n            long long top_y = 0;\n            if (pl.b >= 0) {\n                for (const auto& pr : placed) {\n                    if (pr.idx == pl.b) {\n                        top_y = pr.y2;\n                        break;\n                    }\n                }\n            }\n            \n            // Move left until no overlapping to the left\n            long long right_x = 0;\n            for (const auto& pr : placed) {\n                if (top_y < pr.y2 && top_y + rh > pr.y1) {\n                    right_x = max(right_x, pr.x2);\n                }\n            }\n            \n            placed.push_back({right_x, top_y, right_x + rw, top_y + rh, idx});\n        }\n    }\n    \n    // Calculate bounding box\n    width = 0;\n    height = 0;\n    for (const auto& pr : placed) {\n        width = max(width, pr.x2);\n        height = max(height, pr.y2);\n    }\n    \n    // Calculate unplaced sum\n    long long unplaced_sum = 0;\n    for (int i = 0; i < N; i++) {\n        if (!used[i]) {\n            unplaced_sum += rects[i].w + rects[i].h;\n        }\n    }\n    \n    return width + height + unplaced_sum;\n}\n\n// Generate a packing that respects ascending index constraint\n// rects_to_use: which rectangles to include (must be sorted ascending)\n// rotations: whether to rotate each included rectangle\n// placements: where to place relative to previous rectangle\nvector<Placement> generate_packing(const vector<int>& rects_to_use,\n                                  const vector<bool>& rotations) {\n    vector<Placement> result;\n    \n    for (int i = 0; i < (int)rects_to_use.size(); i++) {\n        int idx = rects_to_use[i];\n        bool rotate = (i < (int)rotations.size()) ? rotations[i] : false;\n        \n        if (i == 0) {\n            // First rectangle: place at origin\n            result.push_back({idx, rotate, 'U', -1});\n        } else {\n            // Place to the right of the previous rectangle\n            result.push_back({idx, rotate, 'U', rects_to_use[i-1]});\n        }\n    }\n    \n    return result;\n}\n\n// Try to find good packing by testing different subsets and rotations\nvector<Placement> find_best_packing() {\n    long long best_score = 1LL << 60;\n    vector<Placement> best_packing;\n    \n    // Strategy 1: Use all rectangles, no rotation\n    {\n        vector<int> all_rects(N);\n        iota(all_rects.begin(), all_rects.end(), 0);\n        vector<bool> rotations(N, false);\n        \n        auto packing = generate_packing(all_rects, rotations);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 2: Use all rectangles, rotate tall ones\n    {\n        vector<int> all_rects(N);\n        iota(all_rects.begin(), all_rects.end(), 0);\n        vector<bool> rotations(N, false);\n        for (int i = 0; i < N; i++) {\n            if (rects[i].h > rects[i].w) rotations[i] = true;\n        }\n        \n        auto packing = generate_packing(all_rects, rotations);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 3: Use all rectangles, rotate wide ones\n    {\n        vector<int> all_rects(N);\n        iota(all_rects.begin(), all_rects.end(), 0);\n        vector<bool> rotations(N, false);\n        for (int i = 0; i < N; i++) {\n            if (rects[i].w > rects[i].h) rotations[i] = true;\n        }\n        \n        auto packing = generate_packing(all_rects, rotations);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 4: Try skipping some rectangles to get better shape\n    // Start with all, then try removing large ones\n    for (int base = 0; base < 2; base++) {\n        vector<int> subset;\n        vector<bool> rotation;\n        \n        for (int i = 0; i < N; i++) {\n            if (i % 2 == base) {\n                subset.push_back(i);\n                rotation.push_back(false);\n            }\n        }\n        \n        if (!subset.empty()) {\n            auto packing = generate_packing(subset, rotation);\n            long long W, H;\n            long long score = evaluate_placement(packing, W, H);\n            if (score < best_score) {\n                best_score = score;\n                best_packing = packing;\n            }\n        }\n    }\n    \n    // Strategy 5: Try using only rectangles that are \"small\" (below median area)\n    {\n        vector<pair<long long, int>> areas;\n        for (int i = 0; i < N; i++) {\n            areas.push_back({rects[i].w * rects[i].h, i});\n        }\n        sort(areas.begin(), areas.end());\n        \n        vector<int> small_rects;\n        vector<bool> small_rot;\n        for (int i = 0; i < N/2; i++) {\n            small_rects.push_back(areas[i].second);\n            small_rot.push_back(false);\n        }\n        sort(small_rects.begin(), small_rects.end());\n        \n        if (!small_rects.empty()) {\n            auto packing = generate_packing(small_rects, small_rot);\n            long long W, H;\n            long long score = evaluate_placement(packing, W, H);\n            if (score < best_score) {\n                best_score = score;\n                best_packing = packing;\n            }\n        }\n    }\n    \n    return best_packing;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> T >> sigma;\n    rects.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n    }\n    \n    // Find the best packing offline\n    vector<Placement> best_packing = find_best_packing();\n    \n    // Run the actual turns\n    for (int turn = 0; turn < T; turn++) {\n        // Output the best packing\n        cout << (int)best_packing.size() << endl;\n        for (const auto& pl : best_packing) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << endl;\n        }\n        cout.flush();\n        \n        // Read feedback (measurements with noise)\n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    // skip coordinates, not needed\n    \n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    \n    // indices sorted by beauty descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return A[i] > A[j];\n    });\n    \n    for (int v : order) {\n        int best_parent = -1;\n        int best_depth = -1;\n        for (int u : adj[v]) {\n            if (parent[u] != -1 && depth[u] < H) {\n                if (depth[u] > best_depth) {\n                    best_depth = depth[u];\n                    best_parent = u;\n                }\n            }\n        }\n        if (best_parent != -1) {\n            parent[v] = best_parent;\n            depth[v] = depth[best_parent] + 1;\n        } else {\n            // become root\n            parent[v] = -1;\n            depth[v] = 0;\n        }\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    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Find all Oni positions\n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // Precompute Fukunokami positions for quick checking\n    vector<vector<bool>> is_fuku(N, vector<bool>(N, false));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'o') {\n                is_fuku[i][j] = true;\n            }\n        }\n    }\n    \n    vector<string> ans;\n    \n    for (auto [oni_i, oni_j] : oni_positions) {\n        // Check clear directions and find the one with minimum operations\n        int best_ops = INT_MAX;\n        char best_dir = '?';\n        \n        // Check Up\n        bool clear_up = true;\n        for (int k = oni_i - 1; k >= 0; k--) {\n            if (is_fuku[k][oni_j]) {\n                clear_up = false;\n                break;\n            }\n        }\n        if (clear_up) {\n            int ops = 2 * (oni_i + 1);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'U';\n            }\n        }\n        \n        // Check Down\n        bool clear_down = true;\n        for (int k = oni_i + 1; k < N; k++) {\n            if (is_fuku[k][oni_j]) {\n                clear_down = false;\n                break;\n            }\n        }\n        if (clear_down) {\n            int ops = 2 * (N - oni_i);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'D';\n            }\n        }\n        \n        // Check Left\n        bool clear_left = true;\n        for (int k = oni_j - 1; k >= 0; k--) {\n            if (is_fuku[oni_i][k]) {\n                clear_left = false;\n                break;\n            }\n        }\n        if (clear_left) {\n            int ops = 2 * (oni_j + 1);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'L';\n            }\n        }\n        \n        // Check Right\n        bool clear_right = true;\n        for (int k = oni_j + 1; k < N; k++) {\n            if (is_fuku[oni_i][k]) {\n                clear_right = false;\n                break;\n            }\n        }\n        if (clear_right) {\n            int ops = 2 * (N - oni_j);\n            if (ops < best_ops) {\n                best_ops = ops;\n                best_dir = 'R';\n            }\n        }\n        \n        // Perform the operations\n        if (best_dir == 'U') {\n            for (int t = 0; t < oni_i + 1; t++) {\n                ans.push_back(\"U \" + to_string(oni_j));\n            }\n            for (int t = 0; t < oni_i + 1; t++) {\n                ans.push_back(\"D \" + to_string(oni_j));\n            }\n        } else if (best_dir == 'D') {\n            for (int t = 0; t < N - oni_i; t++) {\n                ans.push_back(\"D \" + to_string(oni_j));\n            }\n            for (int t = 0; t < N - oni_i; t++) {\n                ans.push_back(\"U \" + to_string(oni_j));\n            }\n        } else if (best_dir == 'L') {\n            for (int t = 0; t < oni_j + 1; t++) {\n                ans.push_back(\"L \" + to_string(oni_i));\n            }\n            for (int t = 0; t < oni_j + 1; t++) {\n                ans.push_back(\"R \" + to_string(oni_i));\n            }\n        } else { // Right\n            for (int t = 0; t < N - oni_j; t++) {\n                ans.push_back(\"R \" + to_string(oni_i));\n            }\n            for (int t = 0; t < N - oni_j; t++) {\n                ans.push_back(\"L \" + to_string(oni_i));\n            }\n        }\n    }\n    \n    // Output the solution\n    for (const string& s : ans) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#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 = 100;\n    const int L = 500000;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    // Create a solution that balances flow based on target frequencies\n    vector<int> a(N), b(N);\n    \n    // The key idea: For each employee i, the number of times they visit a_i vs b_i\n    // differs by at most 1. So the total outgoing flow to j depends on how many\n    // employees point to j with their a_i or b_i.\n    \n    // If we can make the incoming flow approximately proportional to T,\n    // we'll achieve low error.\n    \n    // Simple approach: Create a cyclic shift based on sorted order\n    vector<pair<int,int>> sorted;\n    for (int i = 0; i < N; i++) {\n        sorted.push_back({T[i], i});\n    }\n    sort(sorted.begin(), sorted.end(), greater<>());\n    \n    // Now assign successors: each employee points two steps ahead in sorted order\n    // This creates good mixing\n    for (int i = 0; i < N; i++) {\n        int emp = sorted[i].second;\n        int idx1 = (i + 1) % N;\n        int idx2 = (i + 2) % N;\n        a[emp] = sorted[idx1].second;\n        b[emp] = sorted[idx2].second;\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\n\nstruct City {\n    int lx, rx, ly, ry;\n    int cx, cy;\n};\n\nvector<City> cities;\n\n// Fast query function\nint make_query(const vector<int>& subset, vector<pair<int,int>>& results) {\n    cout << \"? \" << subset.size();\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    int cnt = 0;\n    for (int i = 0; i < (int)subset.size() - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        if (a > b) swap(a, b);\n        results.push_back({a, b});\n        cnt++;\n    }\n    return cnt;\n}\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n) : p(n), sz(n, 1) {\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        while (p[x] != x) {\n            p[x] = p[p[x]];\n            x = p[x];\n        }\n        return x;\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cities.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].cx = (cities[i].lx + cities[i].rx) / 2;\n        cities[i].cy = (cities[i].ly + cities[i].ry) / 2;\n    }\n    \n    // Simple group assignment: sort by center coordinates\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n        return cities[a].cy < cities[b].cy;\n    });\n    \n    vector<vector<int>> groups(M);\n    int ptr = 0;\n    for (int k = 0; k < M; k++) {\n        groups[k].reserve(G[k]);\n        for (int j = 0; j < G[k]; j++) {\n            groups[k].push_back(order[ptr++]);\n        }\n    }\n    \n    int queries_used = 0;\n    vector<vector<pair<int,int>>> group_edges(M);\n    \n    // Store all queried edges globally\n    set<pair<int,int>> global_edges_set;\n    vector<pair<int,int>> global_edges_list;\n    \n    // Phase 1: Use queries efficiently - query groups of size L when possible\n    // For each group, make sliding window queries of size min(L, group_size)\n    for (int k = 0; k < M && queries_used < Q; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g <= 1) continue;\n        if (g == 2) {\n            group_edges[k].push_back({group[0], group[1]});\n            continue;\n        }\n        \n        // Make queries of size up to L, focusing on consecutive cities\n        int qsize = min(L, g);\n        for (int start = 0; start + qsize <= g && queries_used < Q; start += qsize - 1) {\n            // Adjust to not exceed L\n            int actual_size = min(qsize, g - start);\n            if (actual_size < 2) break;\n            \n            vector<int> subset;\n            for (int j = start; j < start + actual_size; j++) {\n                subset.push_back(group[j]);\n            }\n            \n            vector<pair<int,int>> results;\n            make_query(subset, results);\n            queries_used++;\n            \n            // Store results\n            for (auto& e : results) {\n                if (global_edges_set.count(e) == 0) {\n                    global_edges_set.insert(e);\n                    global_edges_list.push_back(e);\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Build MST for each group using known edges\n    for (int k = 0; k < M; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g <= 1) continue;\n        if (g == 2) {\n            if (group_edges[k].empty()) {\n                group_edges[k].push_back({group[0], group[1]});\n            }\n            continue;\n        }\n        \n        if ((int)group_edges[k].size() == g - 1) continue;\n        \n        DSU dsu(N);\n        group_edges[k].clear();\n        \n        // First, add known edges that connect cities in this group\n        for (auto& e : global_edges_list) {\n            int u = e.first, v = e.second;\n            // Check if both cities are in this group\n            bool in_u = false, in_v = false;\n            for (int c : group) {\n                if (c == u) in_u = true;\n                if (c == v) in_v = true;\n            }\n            if (in_u && in_v) {\n                if (dsu.unite(u, v)) {\n                    group_edges[k].push_back({u, v});\n                }\n            }\n        }\n        \n        // If still not fully connected, use remaining queries or direct connections\n        if ((int)group_edges[k].size() < g - 1) {\n            // Use remaining queries to connect components\n            for (int i = 0; i < g && (int)group_edges[k].size() < g - 1; i++) {\n                for (int j = i + 1; j < g && (int)group_edges[k].size() < g - 1; j++) {\n                    int u = group[i], v = group[j];\n                    if (dsu.find(u) != dsu.find(v)) {\n                        // Try to query if we have remaining queries\n                        if (queries_used < Q && global_edges_set.count({min(u,v), max(u,v)}) == 0) {\n                            // Make a small query\n                            vector<int> subset = {u, v};\n                            // Add nearby cities if possible\n                            for (int c : group) {\n                                if (c != u && c != v && (int)subset.size() < L) {\n                                    subset.push_back(c);\n                                }\n                            }\n                            vector<pair<int,int>> results;\n                            make_query(subset, results);\n                            queries_used++;\n                            \n                            for (auto& e2 : results) {\n                                if (global_edges_set.count(e2) == 0) {\n                                    global_edges_set.insert(e2);\n                                    global_edges_list.push_back(e2);\n                                }\n                                if (dsu.unite(e2.first, e2.second)) {\n                                    group_edges[k].push_back(e2);\n                                }\n                            }\n                        } else {\n                            // Direct connection\n                            dsu.unite(u, v);\n                            group_edges[k].push_back({u, v});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Final safety check\n        while ((int)group_edges[k].size() < g - 1) {\n            for (int i = 0; i < g && (int)group_edges[k].size() < g - 1; i++) {\n                for (int j = i + 1; j < g && (int)group_edges[k].size() < g - 1; j++) {\n                    if (dsu.unite(group[i], group[j])) {\n                        group_edges[k].push_back({group[i], group[j]});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    cout.flush();\n    \n    for (int k = 0; k < M; k++) {\n        for (int j = 0; j < G[k]; j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[k][j];\n        }\n        cout << endl;\n        \n        for (auto& e : group_edges[k]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Cell {\n    int r, c;\n    Cell(int r = 0, int c = 0) : r(r), c(c) {}\n};\n\nstring dirs = \"UDLR\";\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<Cell> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].r >> targets[i].c;\n    }\n    \n    // State tracking\n    vector<string> grid(N, string(N, '.'));\n    int posR = targets[0].r, posC = targets[0].c;\n    vector<string> actions;\n    \n    auto getBlock = [&](int r, int c) -> bool {\n        return !(r >= 0 && r < N && c >= 0 && c < N) || grid[r][c] == '#';\n    };\n    \n    // Simple strategy: Use Manhattan moves with occasional slides\n    for (int idx = 1; idx < M; idx++) {\n        int tr = targets[idx].r, tc = targets[idx].c;\n        \n        // While not at target, move towards it\n        while (posR != tr || posC != tc) {\n            // Try to find a good slide direction\n            int bestSlideDir = -1;\n            int bestSlideDist = abs(posR - tr) + abs(posC - tc);\n            \n            for (int d = 0; d < 4; d++) {\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Slide as far as possible in this direction\n                    int sr = nr, sc = nc;\n                    while (true) {\n                        int nnr = sr + dr[d], nnc = sc + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        sr = nnr; sc = nnc;\n                    }\n                    int dist = abs(sr - tr) + abs(sc - tc);\n                    if (dist < bestSlideDist) {\n                        bestSlideDist = dist;\n                        bestSlideDir = d;\n                    }\n                }\n            }\n            \n            bool usedSlide = false;\n            if (bestSlideDir >= 0) {\n                int d = bestSlideDir;\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Execute slide\n                    actions.push_back(\"S \" + string(1, dirs[d]));\n                    \n                    // Update position\n                    while (true) {\n                        int nnr = posR + dr[d], nnc = posC + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        posR = nnr; posC = nnc;\n                    }\n                    usedSlide = true;\n                }\n            }\n            \n            if (!usedSlide) {\n                // Simple move towards target\n                int bestDir = -1;\n                int bestDist = abs(posR - tr) + abs(posC - tc);\n                \n                for (int d = 0; d < 4; d++) {\n                    int nr = posR + dr[d], nc = posC + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                        int dist = abs(nr - tr) + abs(nc - tc);\n                        if (dist < bestDist) {\n                            bestDist = dist;\n                            bestDir = d;\n                        }\n                    }\n                }\n                \n                if (bestDir >= 0) {\n                    // Check if we can place a block to improve future slides\n                    // For simplicity, just move\n                    int nr = posR + dr[bestDir], nc = posC + dc[bestDir];\n                    actions.push_back(\"M \" + string(1, dirs[bestDir]));\n                    posR = nr; posC = nc;\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (const auto& a : actions) {\n        cout << a << \"\\n\";\n    }\n    \n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    using result_type = uint64_t;\n    uint64_t operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    static constexpr uint64_t min() { return 0; }\n    static constexpr uint64_t max() { return ULLONG_MAX; }\n    int rand_int(int l, int r) { return l + operator()() % (r - l + 1); }\n    double rand_double() { return (double)operator()() / ULLONG_MAX; }\n} rng;\n\nstruct Rect {\n    int a, b, c, d;\n    int x, y, r;\n    long long s;\n    \n    Rect() : a(0), b(0), c(0), d(0), x(0), y(0), r(0), s(0) {}\n    Rect(int a_, int b_, int c_, int d_, int x_, int y_, int r_)\n        : a(a_), b(b_), c(c_), d(d_), x(x_), y(y_), r(r_) {\n        s = (long long)(c - a) * (d - b);\n    }\n    \n    double score() const {\n        if (!(a <= x && x < c && b <= y && y < d)) return 0.0;\n        if (s == 0) return 0.0;\n        double min_s = min(r, (int)s);\n        double max_s = max(r, (int)s);\n        double ratio = min_s / max_s;\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<Rect> rects(n);\n    for (int i = 0; i < n; i++) {\n        cin >> rects[i].x >> rects[i].y >> rects[i].r;\n        // Start with minimal 1x1 rectangle containing target point\n        rects[i].a = rects[i].x;\n        rects[i].b = rects[i].y;\n        rects[i].c = rects[i].x + 1;\n        rects[i].d = rects[i].y + 1;\n        rects[i].s = 1;\n    }\n    \n    // Helper to check if a new rectangle at position idx would overlap\n    auto would_overlap = [&](int idx, int na, int nb, int nc, int nd) -> bool {\n        for (int j = 0; j < n; j++) {\n            if (j == idx) continue;\n            if (max(na, rects[j].a) < min(nc, rects[j].c) && \n                max(nb, rects[j].b) < min(nd, rects[j].d)) {\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    // Phase 1: Greedy expansion - each rectangle tries to reach its target area\n    // Process larger areas first for better allocation\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return rects[i].r > rects[j].r;\n    });\n    \n    // Expand each rectangle to its full potential\n    for (int i : order) {\n        auto& rect = rects[i];\n        \n        // Compute ideal square dimensions\n        int ideal_side = max(1, (int)sqrt(rect.r));\n        int target_left = max(0, rect.x - ideal_side / 2);\n        int target_right = min(10000, rect.x + ideal_side / 2 + 1);\n        int target_top = max(0, rect.y - ideal_side / 2);\n        int target_bottom = min(10000, rect.y + ideal_side / 2 + 1);\n        \n        // Ensure we contain the target point\n        if (target_left > rect.x) {\n            target_right = min(10000, target_left + max(1, ideal_side));\n            target_left = max(0, target_right - max(1, ideal_side));\n        }\n        if (target_right <= rect.x) {\n            target_left = max(0, target_right - max(1, ideal_side));\n            target_right = min(10000, target_left + max(1, ideal_side));\n        }\n        if (target_top > rect.y) {\n            target_bottom = min(10000, target_top + max(1, ideal_side));\n            target_top = max(0, target_bottom - max(1, ideal_side));\n        }\n        if (target_bottom <= rect.y) {\n            target_top = max(0, target_bottom - max(1, ideal_side));\n            target_bottom = min(10000, target_top + max(1, ideal_side));\n        }\n        \n        // Try to expand to ideal size, respecting overlaps\n        // Use binary search on expansion amount for each direction\n        for (int dir = 0; dir < 4; dir++) {\n            int target_min = (dir == 0) ? target_left : \n                            (dir == 1) ? target_right :\n                            (dir == 2) ? target_top : target_bottom;\n            int current = (dir == 0) ? rect.a :\n                         (dir == 1) ? rect.c :\n                         (dir == 2) ? rect.b : rect.d;\n            \n            int lo = 0, hi;\n            if (dir == 0) hi = rect.a - max(0, target_left);\n            else if (dir == 1) hi = min(10000, target_right) - rect.c;\n            else if (dir == 2) hi = rect.b - max(0, target_top);\n            else hi = min(10000, target_bottom) - rect.d;\n            hi = max(0, hi);\n            \n            if (hi == 0) continue;\n            \n            // Binary search\n            while (lo < hi) {\n                int mid = (lo + hi + 1) / 2;\n                int na = rect.a, nb = rect.b, nc = rect.c, nd = rect.d;\n                if (dir == 0) na = rect.a - mid;\n                else if (dir == 1) nc = rect.c + mid;\n                else if (dir == 2) nb = rect.b - mid;\n                else nd = rect.d + mid;\n                \n                if (!would_overlap(i, na, nb, nc, nd)) {\n                    lo = mid;\n                } else {\n                    hi = mid - 1;\n                }\n            }\n            \n            // Apply expansion\n            if (dir == 0) rect.a -= lo;\n            else if (dir == 1) rect.c += lo;\n            else if (dir == 2) rect.b -= lo;\n            else rect.d += lo;\n            rect.s = (long long)(rect.c - rect.a) * (rect.d - rect.b);\n        }\n    }\n    \n    // Phase 2: Multiple passes of adjustment\n    // Process all rectangles and try to improve each\n    for (int pass = 0; pass < 20; pass++) {\n        // Get current scores and identify which need adjustment\n        vector<pair<double, int>> ratio_idx(n);\n        double total_score = 0;\n        for (int i = 0; i < n; i++) {\n            ratio_idx[i] = {(double)rects[i].s / rects[i].r, i};\n            total_score += rects[i].score();\n        }\n        \n        sort(ratio_idx.begin(), ratio_idx.end());\n        \n        // For rectangles that are too small, try to expand\n        for (auto [ratio, i] : ratio_idx) {\n            if (ratio >= 1.0) continue; // Already good or too big\n            \n            auto& rect = rects[i];\n            int needed = rect.r - (int)rect.s;\n            if (needed <= 0) continue;\n            \n            // Try to expand in all directions\n            for (int attempt = 0; attempt < min(100, needed / 10 + 1); attempt++) {\n                // Pick the direction with most room\n                int best_dir = -1;\n                int best_space = 0;\n                \n                // Check each direction\n                for (int dir = 0; dir < 4; dir++) {\n                    int space = (dir == 0) ? rect.a :\n                                (dir == 1) ? 10000 - rect.c :\n                                (dir == 2) ? rect.b : 10000 - rect.d;\n                    if (space <= 0) continue;\n                    \n                    int na = rect.a, nb = rect.b, nc = rect.c, nd = rect.d;\n                    if (dir == 0) na = rect.a - 1;\n                    else if (dir == 1) nc = rect.c + 1;\n                    else if (dir == 2) nb = rect.b - 1;\n                    else nd = rect.d + 1;\n                    \n                    if (!would_overlap(i, na, nb, nc, nd) && space > best_space) {\n                        best_space = space;\n                        best_dir = dir;\n                    }\n                }\n                \n                if (best_dir == -1) break;\n                \n                // Expand\n                if (best_dir == 0) rect.a--;\n                else if (best_dir == 1) rect.c++;\n                else if (best_dir == 2) rect.b--;\n                else rect.d++;\n                rect.s = (long long)(rect.c - rect.a) * (rect.d - rect.b);\n                needed--;\n                if (needed <= 0) break;\n            }\n        }\n        \n        // For rectangles that are too big, try to shrink (but only if they're really oversized)\n        for (auto [ratio, i] : ratio_idx) {\n            if (ratio <= 1.3) continue; // Not too big\n            \n            auto& rect = rects[i];\n            \n            // Try to shrink from each direction\n            for (int dir = 0; dir < 4; dir++) {\n                int na = rect.a, nb = rect.b, nc = rect.c, nd = rect.d;\n                if (dir == 0 && rect.c - rect.a > 1) na = rect.a + 1;\n                else if (dir == 1 && rect.c - rect.a > 1) nc = rect.c - 1;\n                else if (dir == 2 && rect.d - rect.b > 1) nb = rect.b + 1;\n                else if (dir == 3 && rect.d - rect.b > 1) nd = rect.d - 1;\n                else continue;\n                \n                // Check if rectangle still contains target and doesn't cause new overlaps\n                if (na <= rect.x && rect.x < nc && nb <= rect.y && rect.y < nd) {\n                    // Check if shrinking this actually improves the score\n                    double old_score = rect.score();\n                    Rect temp(na, nb, nc, nd, rect.x, rect.y, rect.r);\n                    double new_score = temp.score();\n                    \n                    if (new_score > old_score && !would_overlap(i, na, nb, nc, nd)) {\n                        rect.a = na; rect.b = nb; rect.c = nc; rect.d = nd;\n                        rect.s = (long long)(nc - na) * (nd - nb);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Simulated annealing with smarter moves\n    const int iterations = 100000;\n    const double start_temp = 1.0;\n    const double end_temp = 0.001;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        double temp = start_temp + (end_temp - start_temp) * iter / iterations;\n        \n        int i = rng.rand_int(0, n - 1);\n        auto& rect = rects[i];\n        \n        // Store old state\n        int old_a = rect.a, old_b = rect.b, old_c = rect.c, old_d = rect.d;\n        double old_score = rect.score();\n        long long old_s = rect.s;\n        \n        // Generate move: adjust one boundary\n        int dir = rng.rand_int(0, 3);\n        int delta = rng.rand_int(-10, 10);\n        \n        int na = rect.a, nb = rect.b, nc = rect.c, nd = rect.d;\n        \n        if (dir == 0) na = max(0, min(old_c - 1, old_a + delta));\n        else if (dir == 1) nc = min(10000, max(old_a + 1, old_c + delta));\n        else if (dir == 2) nb = max(0, min(old_d - 1, old_b + delta));\n        else nd = min(10000, max(old_b + 1, old_d + delta));\n        \n        // Validate\n        if (na >= nc || nb >= nd) continue;\n        if (!(na <= rect.x && rect.x < nc && nb <= rect.y && rect.y < nd)) continue;\n        \n        // Check overlap\n        bool overlap = false;\n        for (int j = 0; j < n && !overlap; j++) {\n            if (j == i) continue;\n            if (max(na, rects[j].a) < min(nc, rects[j].c) && \n                max(nb, rects[j].b) < min(nd, rects[j].d)) {\n                overlap = true;\n            }\n        }\n        if (overlap) continue;\n        \n        double new_score = Rect(na, nb, nc, nd, rect.x, rect.y, rect.r).score();\n        \n        if (new_score > old_score || rng.rand_double() < exp((new_score - old_score) * 500 / temp)) {\n            rect.a = na; rect.b = nb; rect.c = nc; rect.d = nd;\n            rect.s = (long long)(nc - na) * (nd - nb);\n        }\n    }\n    \n    // Final verification and output\n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \"\n             << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst string dirs = \"UDLR\";\n\nstruct State {\n    vector<int> used;\n    int i, j;\n    long long score;\n    string path;\n    \n    State() : used(), i(0), j(0), score(0), path(\"\") {}\n};\n\nclass Solver {\nprivate:\n    int si, sj;\n    vector<vector<int>> t, p;\n    int M;\n    long long best_score;\n    string best_path;\n    vector<vector<pair<int,int>>> tile_cells;\n    vector<int> tile_size;\n    vector<vector<int>> tile_adjacent;\n    vector<long long> tile_total_value;\n    vector<vector<long long>> cell_value_sum;\n    \n    // For tracking currently best path for improvement\n    vector<pair<int,int>> best_path_cells;\n    vector<int> best_path_tiles;\n    \npublic:\n    Solver() {\n        cin >> si >> sj;\n        t.assign(N, vector<int>(N));\n        p.assign(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> p[i][j];\n        \n        // Find max tile ID\n        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        // Build tile info\n        tile_cells.resize(M);\n        tile_size.resize(M, 0);\n        tile_total_value.resize(M, 0);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                tile_cells[t[i][j]].push_back({i, j});\n                tile_size[t[i][j]]++;\n                tile_total_value[t[i][j]] += p[i][j];\n            }\n        }\n        \n        // Precompute tile adjacency\n        tile_adjacent.resize(M);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d];\n                    int nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                        if (t[i][j] != t[ni][nj]) {\n                            tile_adjacent[t[i][j]].push_back(t[ni][nj]);\n                        }\n                    }\n                }\n            }\n        }\n        for (int i = 0; i < M; i++) {\n            sort(tile_adjacent[i].begin(), tile_adjacent[i].end());\n            tile_adjacent[i].erase(unique(tile_adjacent[i].begin(), tile_adjacent[i].end()), tile_adjacent[i].end());\n        }\n        \n        // Precompute cell value sums\n        cell_value_sum.assign(N, vector<long long>(N, 0));\n        compute_cell_value_sums();\n    }\n    \n    void compute_cell_value_sums() {\n        // For each cell, compute sum of values in reachable neighborhood\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                long long sum = 0;\n                for (int di2 = -2; di2 <= 2; di2++) {\n                    for (int dj2 = -2; dj2 <= 2; dj2++) {\n                        int ni = i + di2;\n                        int nj = j + dj2;\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            sum += p[ni][nj];\n                        }\n                    }\n                }\n                cell_value_sum[i][j] = sum;\n            }\n        }\n    }\n    \n    string solve() {\n        best_score = -1;\n        best_path = \"\";\n        best_path_cells.clear();\n        \n        // Phase 1: Multiple beam search attempts\n        for (int attempt = 0; attempt < 30; attempt++) {\n            // Use different strategies\n            int strategy = attempt % 5;\n            beam_search(attempt, strategy);\n        }\n        \n        // Phase 2: Try to improve best path by local optimization\n        improve_best_path();\n        \n        return best_path;\n    }\n    \nprivate:\n    bool is_valid_move(const State& state, int ni, int nj) {\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (state.used[t[ni][nj]]) return false;\n        return true;\n    }\n    \n    long long compute_heuristic(const State& state, int ni, int nj, int strategy, int step) {\n        long long h = p[ni][nj];\n        \n        // Strategy-dependent heuristic components\n        switch (strategy) {\n            case 0: // Value-focused\n                h += tile_total_value[t[ni][nj]] * 0.2;\n                h += cell_value_sum[ni][nj] * 0.1;\n                break;\n            case 1: // Connectivity-focused\n                {\n                    int unvisited = 0;\n                    for (int adj : tile_adjacent[t[ni][nj]]) {\n                        if (!state.used[adj]) unvisited++;\n                    }\n                    h += unvisited * 30;\n                }\n                break;\n            case 2: // Balanced\n                h += tile_total_value[t[ni][nj]] * 0.1;\n                {\n                    int unvisited = 0;\n                    for (int adj : tile_adjacent[t[ni][nj]]) {\n                        if (!state.used[adj]) unvisited++;\n                    }\n                    h += unvisited * 20;\n                }\n                h += cell_value_sum[ni][nj] * 0.1;\n                break;\n            case 3: // Tile-size focused\n                if (tile_size[t[ni][nj]] > 1) h += 30;\n                h += tile_total_value[t[ni][nj]] * 0.05;\n                break;\n            case 4: // Random exploration\n                h += (step * 7 + ni * 13 + nj * 17) % 50;\n                break;\n        }\n        \n        // Base heuristic: lookahead to adjacent cells\n        for (int dd = 0; dd < 4; dd++) {\n            int nni = ni + di[dd];\n            int nnj = nj + dj[dd];\n            if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n            if (!state.used[t[nni][nnj]]) {\n                h += p[nni][nnj] * 0.3;\n            }\n        }\n        \n        // Bonus for keeping options open\n        int future_moves = 0;\n        for (int dd = 0; dd < 4; dd++) {\n            int nni = ni + di[dd];\n            int nnj = nj + dj[dd];\n            if (nni >= 0 && nni < N && nnj >= 0 && nnj < N && !state.used[t[nni][nnj]]) {\n                future_moves++;\n            }\n        }\n        h += future_moves * 10;\n        \n        return h;\n    }\n    \n    void beam_search(int attempt, int strategy) {\n        const int BEAM_WIDTH = 12;\n        const int MAX_STEPS = 400;\n        \n        // Initialize starting state\n        State start;\n        start.used.assign(M, 0);\n        start.i = si;\n        start.j = sj;\n        start.score = p[si][sj];\n        start.used[t[si][sj]] = 1;\n        start.path = \"\";\n        \n        vector<State> beam = {start};\n        \n        for (int step = 0; step < MAX_STEPS && !beam.empty(); step++) {\n            vector<State> candidates;\n            \n            for (const auto& state : beam) {\n                // Find all valid moves\n                struct Move {\n                    long long heuristic;\n                    int d, ni, nj;\n                };\n                vector<Move> valid_moves;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = state.i + di[d];\n                    int nj = state.j + dj[d];\n                    \n                    if (!is_valid_move(state, ni, nj)) continue;\n                    \n                    long long h = compute_heuristic(state, ni, nj, strategy, step);\n                    valid_moves.push_back({h, d, ni, nj});\n                }\n                \n                if (valid_moves.empty()) {\n                    if (state.score > best_score) {\n                        best_score = state.score;\n                        best_path = state.path;\n                    }\n                    continue;\n                }\n                \n                // Sort by heuristic descending\n                sort(valid_moves.begin(), valid_moves.end(),\n                     [](const Move& a, const Move& b) { return a.heuristic > b.heuristic; });\n                \n                // Take top moves with diversity\n                int take = min((int)valid_moves.size(), BEAM_WIDTH / 2);\n                for (int k = 0; k < take; k++) {\n                    Move& move = valid_moves[k];\n                    \n                    // Create new state\n                    State new_state;\n                    new_state.used = state.used;\n                    new_state.used[t[move.ni][move.nj]] = 1;\n                    new_state.i = move.ni;\n                    new_state.j = move.nj;\n                    new_state.score = state.score + p[move.ni][move.nj];\n                    new_state.path = state.path + dirs[move.d];\n                    \n                    candidates.push_back(new_state);\n                }\n                \n                // Add some random moves for diversity\n                if (valid_moves.size() > take && strategy == 4) {\n                    int r = (attempt * 7 + step * 13) % valid_moves.size();\n                    if (r < valid_moves.size()) {\n                        Move& move = valid_moves[r];\n                        State new_state;\n                        new_state.used = state.used;\n                        new_state.used[t[move.ni][move.nj]] = 1;\n                        new_state.i = move.ni;\n                        new_state.j = move.nj;\n                        new_state.score = state.score + p[move.ni][move.nj];\n                        new_state.path = state.path + dirs[move.d];\n                        candidates.push_back(new_state);\n                    }\n                }\n            }\n            \n            if (candidates.empty()) break;\n            \n            // Sort by score and keep top states\n            sort(candidates.begin(), candidates.end(),\n                 [](const State& a, const State& b) { return a.score > b.score; });\n            \n            beam.clear();\n            int keep = min((int)candidates.size(), BEAM_WIDTH);\n            for (int k = 0; k < keep; k++) {\n                beam.push_back(candidates[k]);\n                \n                if (candidates[k].score > best_score) {\n                    best_score = candidates[k].score;\n                    best_path = candidates[k].path;\n                }\n            }\n        }\n        \n        for (const auto& state : beam) {\n            if (state.score > best_score) {\n                best_score = state.score;\n                best_path = state.path;\n            }\n        }\n    }\n    \n    void improve_best_path() {\n        if (best_path.empty()) return;\n        \n        // Try to find a better path by doing local search\n        // around the current best path\n        for (int improvement_attempt = 0; improvement_attempt < 20; improvement_attempt++) {\n            // Create a slightly modified start state\n            State start;\n            start.used.assign(M, 0);\n            start.i = si;\n            start.j = sj;\n            start.score = p[si][sj];\n            start.used[t[si][sj]] = 1;\n            start.path = \"\";\n            \n            // Try different first moves\n            int dir = improvement_attempt % 4;\n            int ni = si + di[dir];\n            int nj = sj + dj[dir];\n            \n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && !start.used[t[ni][nj]]) {\n                start.used[t[ni][nj]] = 1;\n                start.i = ni;\n                start.j = nj;\n                start.score += p[ni][nj];\n                start.path += dirs[dir];\n                \n                // Continue with focused search\n                focused_search(start, improvement_attempt);\n            }\n            \n            // Also try starting without forced move\n            if (improvement_attempt >= 4) {\n                State normal_start;\n                normal_start.used.assign(M, 0);\n                normal_start.i = si;\n                normal_start.j = sj;\n                normal_start.score = p[si][sj];\n                normal_start.used[t[si][sj]] = 1;\n                normal_start.path = \"\";\n                focused_search(normal_start, improvement_attempt + 100);\n            }\n        }\n    }\n    \n    void focused_search(State start, int attempt) {\n        const int BEAM_WIDTH = 8;\n        const int MAX_STEPS = 300;\n        \n        vector<State> beam = {start};\n        \n        for (int step = 0; step < MAX_STEPS && !beam.empty(); step++) {\n            vector<State> candidates;\n            \n            for (const auto& state : beam) {\n                struct Move {\n                    long long heuristic;\n                    int d, ni, nj;\n                };\n                vector<Move> valid_moves;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = state.i + di[d];\n                    int nj = state.j + dj[d];\n                    \n                    if (!is_valid_move(state, ni, nj)) continue;\n                    \n                    // Use balanced heuristic\n                    long long h = p[ni][nj];\n                    h += tile_total_value[t[ni][nj]] * 0.1;\n                    \n                    int unvisited = 0;\n                    for (int adj : tile_adjacent[t[ni][nj]]) {\n                        if (!state.used[adj]) unvisited++;\n                    }\n                    h += unvisited * 25;\n                    \n                    // Lookahead\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nni = ni + di[dd];\n                        int nnj = nj + dj[dd];\n                        if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n                        if (!state.used[t[nni][nnj]]) {\n                            h += p[nni][nnj] * 0.3;\n                        }\n                    }\n                    \n                    valid_moves.push_back({h, d, ni, nj});\n                }\n                \n                if (valid_moves.empty()) {\n                    if (state.score > best_score) {\n                        best_score = state.score;\n                        best_path = state.path;\n                    }\n                    continue;\n                }\n                \n                sort(valid_moves.begin(), valid_moves.end(),\n                     [](const Move& a, const Move& b) { return a.heuristic > b.heuristic; });\n                \n                int take = min((int)valid_moves.size(), BEAM_WIDTH / 2);\n                for (int k = 0; k < take; k++) {\n                    Move& move = valid_moves[k];\n                    \n                    State new_state;\n                    new_state.used = state.used;\n                    new_state.used[t[move.ni][move.nj]] = 1;\n                    new_state.i = move.ni;\n                    new_state.j = move.nj;\n                    new_state.score = state.score + p[move.ni][move.nj];\n                    new_state.path = state.path + dirs[move.d];\n                    \n                    candidates.push_back(new_state);\n                }\n            }\n            \n            if (candidates.empty()) break;\n            \n            sort(candidates.begin(), candidates.end(),\n                 [](const State& a, const State& b) { return a.score > b.score; });\n            \n            beam.clear();\n            int keep = min((int)candidates.size(), BEAM_WIDTH);\n            for (int k = 0; k < keep; k++) {\n                beam.push_back(candidates[k]);\n                if (candidates[k].score > best_score) {\n                    best_score = candidates[k].score;\n                    best_path = candidates[k].path;\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    string result = solver.solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nstruct Edge {\n    int from_row, from_col, to_row, to_col;\n    double mean;\n    int count;\n};\n\nstruct Graph {\n    vector<Edge> edges;\n    vector<vector<int>> adj;\n    \n    Graph() {\n        adj.resize(N * N);\n        \n        // Horizontal edges\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                Edge e = {i, j, i, j+1, 5000.0, 0};\n                edges.push_back(e);\n                adj[u].push_back((int)edges.size() - 1);\n                adj[v].push_back((int)edges.size() - 1);\n            }\n        }\n        \n        // Vertical edges\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                int u = i * N + j;\n                int v = (i+1) * N + j;\n                edges.push_back({i, j, i+1, j, 5000.0, 0});\n                adj[u].push_back((int)edges.size() - 1);\n                adj[v].push_back((int)edges.size() - 1);\n            }\n        }\n    }\n    \n    string get_path_str(int si, int sj, int ti, int tj, vector<int>& used_edges) {\n        // Dijkstra\n        vector<double> dist(N*N, 1e18);\n        vector<int> prev(N*N, -1);\n        vector<int> prev_edge(N*N, -1);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<>> pq;\n        \n        int s = si * N + sj;\n        int t = ti * N + tj;\n        dist[s] = 0;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == t) break;\n            \n            int ui = u / N, uj = u % N;\n            for (int eid : adj[u]) {\n                auto& e = edges[eid];\n                int v = (e.from_row == ui && e.from_col == uj) \n                       ? e.to_row * N + e.to_col \n                       : e.from_row * N + e.from_col;\n                double nd = d + e.mean;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_edge[v] = eid;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        // Reconstruct path\n        string path;\n        used_edges.clear();\n        \n        int cur = t;\n        while (cur != s) {\n            int eid = prev_edge[cur];\n            used_edges.push_back(eid);\n            cur = prev[cur];\n        }\n        reverse(used_edges.begin(), used_edges.end());\n        \n        // Convert to direction string\n        int ci = si, cj = sj;\n        for (int eid : used_edges) {\n            auto& e = edges[eid];\n            int ni, nj;\n            if (e.from_row == ci && e.from_col == cj) {\n                ni = e.to_row; nj = e.to_col;\n            } else {\n                ni = e.from_row; nj = e.from_col;\n            }\n            \n            if (ni < ci) path += 'U';\n            else if (ni > ci) path += 'D';\n            else if (nj < cj) path += 'L';\n            else path += 'R';\n            \n            ci = ni; cj = nj;\n        }\n        \n        return path;\n    }\n    \n    void update_edges(const vector<int>& used_edges, double observed_length) {\n        double predicted = 0;\n        for (int eid : used_edges) predicted += edges[eid].mean;\n        \n        double error = observed_length - predicted;\n        double per_edge = error / used_edges.size();\n        \n        for (int eid : used_edges) {\n            edges[eid].count++;\n            double alpha = 0.3 / (1 + edges[eid].count * 0.01);\n            edges[eid].mean += alpha * per_edge;\n            edges[eid].mean = max(100.0, min(20000.0, edges[eid].mean));\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Graph g;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        vector<int> used_edges;\n        string path = g.get_path_str(si, sj, ti, tj, used_edges);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        double observed;\n        cin >> observed;\n        \n        g.update_edges(used_edges, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Solver {\n    int N, M;\n    vector<string>& strings;\n    vector<string> ans;\n    \n    // Precomputed string data\n    vector<int> str_len;\n    vector<vector<pair<int,int>>> str_h_positions;  // (r, c) for each string horizontally\n    vector<vector<pair<int,int>>> str_v_positions;  // (r, c) for each string vertically\n    \n    Solver(int n, int m, vector<string>& s) : N(n), M(m), strings(s) {\n        ans.assign(N, string(N, '.'));\n        str_len.resize(M);\n        str_h_positions.resize(M);\n        str_v_positions.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            str_len[i] = strings[i].size();\n        }\n        \n        // Precompute all possible positions for each string\n        for (int i = 0; i < M; i++) {\n            string& str = strings[i];\n            int len = str_len[i];\n            \n            // Horizontal positions\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    str_h_positions[i].push_back({r, c});\n                }\n            }\n            \n            // Vertical positions\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    str_v_positions[i].push_back({r, c});\n                }\n            }\n        }\n    }\n    \n    // Check if string exists at given position\n    bool check_at(const string& str, int r, int c, bool hor) {\n        int len = str.size();\n        if (hor) {\n            for (int p = 0; p < len; p++) {\n                if (ans[r][(c + p) % N] != str[p]) return false;\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                if (ans[(r + p) % N][c] != str[p]) return false;\n            }\n        }\n        return true;\n    }\n    \n    // Place string at position (overwrites anyway)\n    void place_at(const string& str, int r, int c, bool hor) {\n        int len = str.size();\n        if (hor) {\n            for (int p = 0; p < len; p++) {\n                ans[r][(c + p) % N] = str[p];\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                ans[(r + p) % N][c] = str[p];\n            }\n        }\n    }\n    \n    void solve() {\n        // Count character frequencies in all strings\n        vector<int> char_count(8, 0);\n        for (auto& s : strings) {\n            for (char c : s) char_count[c - 'A']++;\n        }\n        \n        // Find most common character\n        int best_char = 0;\n        for (int k = 1; k < 8; k++) {\n            if (char_count[k] > char_count[best_char]) best_char = k;\n        }\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            if (str_len[a] != str_len[b]) return str_len[a] > str_len[b];\n            return strings[a] < strings[b];\n        });\n        \n        // Place all strings in their first valid position\n        for (int idx : order) {\n            string& str = strings[idx];\n            \n            // Try horizontal positions\n            bool placed = false;\n            for (auto [r, c] : str_h_positions[idx]) {\n                // Quick check if position is compatible\n                bool ok = true;\n                for (int p = 0; p < str_len[idx]; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] != '.' && ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) {\n                    for (int p = 0; p < str_len[idx]; p++) {\n                        int nc = (c + p) % N;\n                        if (ans[r][nc] == '.') ans[r][nc] = str[p];\n                    }\n                    placed = true;\n                    break;\n                }\n            }\n            \n            if (!placed) {\n                // Try vertical positions\n                for (auto [r, c] : str_v_positions[idx]) {\n                    bool ok = true;\n                    for (int p = 0; p < str_len[idx]; p++) {\n                        int nr = (r + p) % N;\n                        if (ans[nr][c] != '.' && ans[nr][c] != str[p]) {\n                            ok = false;\n                            break;\n                        }\n                    }\n                    if (ok) {\n                        for (int p = 0; p < str_len[idx]; p++) {\n                            int nr = (r + p) % N;\n                            if (ans[nr][c] == '.') ans[nr][c] = str[p];\n                        }\n                        placed = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!placed) {\n                // Force place at first position\n                auto [r, c] = str_h_positions[idx][0];\n                for (int p = 0; p < str_len[idx]; p++) {\n                    ans[r][(c + p) % N] = str[p];\n                }\n            }\n        }\n        \n        // Fill remaining empty cells with most common nearby character\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] != '.') continue;\n                \n                // Check neighbors for character frequency\n                vector<int> nearby_freq(8, 0);\n                \n                // Check four directions\n                int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n                for (auto [dr, dc] : dirs) {\n                    int nr = (r + dr + N) % N;\n                    int nc = (c + dc + N) % N;\n                    if (ans[nr][nc] != '.') {\n                        nearby_freq[ans[nr][nc] - 'A']++;\n                    }\n                }\n                \n                // Also consider global frequency for tie-breaking\n                int best = 0;\n                int best_freq = -1;\n                for (int k = 0; k < 8; k++) {\n                    int score = nearby_freq[k] * 3 + char_count[k]; // weight local higher\n                    if (score > best_freq) {\n                        best_freq = score;\n                        best = k;\n                    }\n                }\n                \n                ans[r][c] = 'A' + (best_freq >= 0 ? best : best_char);\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Solver solver(N, M, strings);\n    solver.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << solver.ans[i] << endl;\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\n\nint N, si, sj;\nvector<string> c;\nvector<vector<int>> dist;\n\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nvoid bfsDist(int si, int sj) {\n    dist.assign(N, vector<int>(N, 1e9));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si,sj});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        for (int d=0; d<4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && dist[ni][nj] > dist[i][j]+1) {\n                dist[ni][nj] = dist[i][j]+1;\n                q.push({ni,nj});\n            }\n        }\n    }\n}\n\nvector<vector<vector<pair<int,int>>>> visible;\n\nvoid precomputeVisible() {\n    visible.assign(N, vector<vector<pair<int,int>>>(N));\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        for (int nj=j-1; nj>=0 && c[i][nj]!='#'; nj--) visible[i][j].push_back({i,nj});\n        for (int nj=j+1; nj<N && c[i][nj]!='#'; nj++) visible[i][j].push_back({i,nj});\n        for (int ni=i-1; ni>=0 && c[ni][j]!='#'; ni--) visible[i][j].push_back({ni,j});\n        for (int ni=i+1; ni<N && c[ni][j]!='#'; ni++) visible[i][j].push_back({ni,j});\n    }\n}\n\nstring pathBetween(int i1, int j1, int i2, int j2) {\n    if (i1==i2 && j1==j2) return \"\";\n    vector<vector<int>> d(N, vector<int>(N, 1e9));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    d[i1][j1] = 0;\n    q.push({i1,j1});\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i==i2 && j==j2) break;\n        for (int dir=0; dir<4; dir++) {\n            int ni = i+di[dir], nj = j+dj[dir];\n            if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && d[ni][nj] > d[i][j]+1) {\n                d[ni][nj] = d[i][j]+1;\n                prev[ni][nj] = {i,j};\n                q.push({ni,nj});\n            }\n        }\n    }\n    if (d[i2][j2]==1e9) return \"\"; // should not happen\n    string path;\n    int ci = i2, cj = j2;\n    while (!(ci==i1 && cj==j1)) {\n        auto [pi,pj] = prev[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 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 >> N >> si >> sj;\n    c.resize(N);\n    for (int i=0; i<N; i++) cin >> c[i];\n    \n    precomputeVisible();\n    \n    vector<vector<bool>> seen(N, vector<bool>(N, false));\n    seen[si][sj] = true;\n    for (auto [vi,vj] : visible[si][sj]) seen[vi][vj] = true;\n    \n    int cur_i = si, cur_j = sj;\n    string ans;\n    int uncovered = 0;\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) uncovered++;\n    \n    while (uncovered > 0) {\n        bfsDist(cur_i, cur_j); // distances from current position\n        int bestDist = 1e9, bestI = -1, bestJ = -1;\n        for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n            if (c[i][j]!='#' && !seen[i][j] && dist[i][j] < bestDist) {\n                bestDist = dist[i][j];\n                bestI = i; bestJ = j;\n            }\n        }\n        if (bestI==-1) break; // shouldn't happen\n        string subPath = pathBetween(cur_i, cur_j, bestI, bestJ);\n        ans += subPath;\n        cur_i = bestI; cur_j = bestJ;\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) {\n            if (!seen[vi][vj]) {\n                seen[vi][vj] = true;\n                uncovered--;\n            }\n        }\n    }\n    \n    // verify coverage\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) {\n        // fallback: move to it directly\n        bfsDist(cur_i, cur_j);\n        int bestDist = 1e9, bestI = -1, bestJ = -1;\n        for (int ii=0; ii<N; ii++) for (int jj=0; jj<N; jj++) {\n            if (c[ii][jj]!='#' && !seen[ii][jj] && dist[ii][jj] < bestDist) {\n                bestDist = dist[ii][jj];\n                bestI = ii; bestJ = jj;\n            }\n        }\n        if (bestI==-1) break;\n        string subPath = pathBetween(cur_i, cur_j, bestI, bestJ);\n        ans += subPath;\n        cur_i = bestI; cur_j = bestJ;\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) {\n            if (!seen[vi][vj]) {\n                seen[vi][vj] = true;\n            }\n        }\n    }\n    \n    string back = pathBetween(cur_i, cur_j, si, sj);\n    ans += back;\n    \n    cout << ans << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Fast I/O\nstruct FastIO {\n    FastIO() {\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cout.tie(nullptr);\n    }\n} fastio;\n\n// Utility for random\nstruct XorShift {\n    uint64_t x;\n    XorShift() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t rand() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    uint32_t rand(uint32_t range) {\n        return rand() % range;\n    }\n    double uniform() {\n        return (double)rand() / UINT32_MAX;\n    }\n    double normal() {\n        double u1 = uniform(), u2 = uniform();\n        return sqrt(-2 * log(u1)) * cos(2 * M_PI * u2);\n    }\n} rng;\n\n// 2D vector type\nusing Vec = vector<int>;\n\n// Main solver\nstruct Solver {\n    int N, M, K, R;\n    vector<Vec> task_diff; // task difficulties\n    vector<vector<int>> deps; // dependencies\n    vector<Vec> workers_skills_est; // estimated worker skills\n    vector<vector<double>> skill_mean; // mean of skill estimates\n    vector<vector<double>> skill_var; // variance of skill estimates\n    \n    // State\n    vector<int> task_status; // 0=not started, 1=running, 2=done\n    vector<int> worker_busy_until; // day when worker becomes free\n    vector<int> worker_task; // task assigned to worker (-1 if none)\n    int current_day;\n    \n    // History for learning\n    struct Observation {\n        int worker;\n        int task;\n        int duration;\n        Vec task_diff;\n    };\n    vector<Observation> history;\n    \n    Solver() {\n        read_input();\n        init();\n    }\n    \n    void read_input() {\n        cin >> N >> M >> K >> R;\n        task_diff.resize(N, Vec(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                cin >> task_diff[i][j];\n            }\n        }\n        deps.resize(N);\n        for (int i = 0; i < R; i++) {\n            int u, v;\n            cin >> u >> v;\n            u--; v--;\n            deps[v].push_back(u);\n        }\n    }\n    \n    void init() {\n        // Initialize skill estimates with reasonable values\n        workers_skills_est.assign(M, Vec(K, 0));\n        skill_mean.assign(M, vector<double>(K, 30.0));\n        skill_var.assign(M, vector<double>(K, 100.0));\n        \n        task_status.assign(N, 0);\n        worker_busy_until.assign(M, 0);\n        worker_task.assign(M, -1);\n        current_day = 1;\n    }\n    \n    bool can_start(int task) {\n        if (task_status[task] != 0) return false;\n        for (int dep : deps[task]) {\n            if (task_status[dep] != 2) return false;\n        }\n        return true;\n    }\n    \n    double expected_duration(int worker, int task) {\n        double w = 0;\n        for (int k = 0; k < K; k++) {\n            w += max(0, task_diff[task][k] - (int)round(workers_skills_est[worker][k]));\n        }\n        return max(1.0, w + 1); // conservative estimate\n    }\n    \n    int find_best_worker(int task) {\n        int best_worker = -1;\n        double best_time = 1e9;\n        vector<int> available;\n        for (int w = 0; w < M; w++) {\n            if (worker_busy_until[w] <= current_day) {\n                available.push_back(w);\n            }\n        }\n        if (available.empty()) return -1;\n        \n        for (int w : available) {\n            double dur = expected_duration(w, task);\n            // Add explore bonus for uncertain skills\n            double uncertainty = 0;\n            for (int k = 0; k < K; k++) {\n                uncertainty += skill_var[w][k];\n            }\n            uncertainty = sqrt(uncertainty / K);\n            dur -= 0.5 * uncertainty; // prefer exploring uncertain workers\n            \n            if (dur < best_time) {\n                best_time = dur;\n                best_worker = w;\n            }\n        }\n        return best_worker;\n    }\n    \n    void update_skills(Observation& obs) {\n        // Simple gradient descent to update skill estimates\n        double learning_rate = 0.1;\n        int actual_dur = obs.duration;\n        Vec& d = obs.task_diff;\n        int w = obs.worker;\n        \n        // Compute predicted w\n        double pred_w = 0;\n        for (int k = 0; k < K; k++) {\n            pred_w += max(0, d[k] - workers_skills_est[w][k]);\n        }\n        \n        // Update if actual duration gives information\n        if (actual_dur > 1) {\n            // The actual w (without noise) is around actual_dur - random(-3 to 3)\n            // We'll use a simple update rule\n            for (int k = 0; k < K; k++) {\n                if (d[k] > workers_skills_est[w][k]) {\n                    // This skill might be lower than estimated\n                    workers_skills_est[w][k] = max(0, workers_skills_est[w][k] + \n                        (int)(learning_rate * (d[k] - workers_skills_est[w][k]) * (actual_dur - 1) / (pred_w + 1)));\n                }\n            }\n        } else {\n            // Task was easy, worker likely has sufficient skills\n            for (int k = 0; k < K; k++) {\n                workers_skills_est[w][k] = max(workers_skills_est[w][k], d[k]);\n            }\n        }\n    }\n    \n    void solve() {\n        while (true) {\n            // Update worker states from previous day's completions\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            stringstream ss(line);\n            int first;\n            ss >> first;\n            \n            if (first == -1) {\n                // End of simulation\n                return;\n            }\n            \n            // Process completed tasks\n            int n_completed = first;\n            for (int i = 0; i < n_completed; i++) {\n                int worker;\n                ss >> worker;\n                worker--;\n                int task = worker_task[worker];\n                if (task >= 0) {\n                    task_status[task] = 2; // completed\n                    int duration = current_day - (worker_busy_until[worker] - 1);\n                    \n                    Observation obs;\n                    obs.worker = worker;\n                    obs.task = task;\n                    obs.duration = duration;\n                    obs.task_diff = task_diff[task];\n                    history.push_back(obs);\n                    \n                    // Update skill estimates\n                    update_skills(obs);\n                    \n                    worker_task[worker] = -1;\n                    worker_busy_until[worker] = current_day; // free now\n                }\n            }\n            \n            // Find tasks that can be started\n            vector<int> available_tasks;\n            for (int t = 0; t < N; t++) {\n                if (can_start(t)) {\n                    available_tasks.push_back(t);\n                }\n            }\n            \n            // Assign workers to tasks\n            vector<pair<int, int>> assignments;\n            \n            // Sort tasks by priority (e.g., by number of descendants)\n            sort(available_tasks.begin(), available_tasks.end(), [&](int a, int b) {\n                return deps[a].size() > deps[b].size();\n            });\n            \n            for (int task : available_tasks) {\n                if (assignments.size() >= M) break;\n                \n                int worker = find_best_worker(task);\n                if (worker >= 0) {\n                    assignments.push_back({worker, task});\n                    worker_task[worker] = task;\n                    task_status[task] = 1; // started\n                    \n                    // Estimate completion time for next day update\n                    double est_dur = expected_duration(worker, task);\n                    worker_busy_until[worker] = current_day + (int)ceil(est_dur);\n                }\n            }\n            \n            // Output assignments\n            cout << assignments.size();\n            for (auto& p : assignments) {\n                cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n            }\n            cout << endl;\n            cout.flush();\n            \n            current_day++;\n            \n            if (current_day > 2000) {\n                // Read remaining input and exit\n                while (true) {\n                    getline(cin, line);\n                    if (line == \"-1\") break;\n                }\n                return;\n            }\n        }\n    }\n};\n\nint main() {\n    Solver solver;\n    solver.solve();\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nconst int DEPOT_X = 400, DEPOT_Y = 400;\nconst int N_ORDERS = 1000;\nconst int PICK = 50;\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nstruct Order {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> orders(N_ORDERS);\n    for (int i = 0; i < N_ORDERS; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Select 50 orders\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < N_ORDERS; ++i) {\n        int rt = manhattan(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b)\n               + manhattan(orders[i].a, orders[i].b, orders[i].c, orders[i].d)\n               + manhattan(orders[i].c, orders[i].d, DEPOT_X, DEPOT_Y);\n        candidates.emplace_back(rt, i);\n    }\n    sort(candidates.begin(), candidates.end());\n    \n    vector<int> selectedIdx(PICK);\n    for (int i = 0; i < PICK; ++i) {\n        selectedIdx[i] = candidates[i].second;\n    }\n\n    // Build nodes: restaurant then destination for each selected order\n    struct Node {\n        int x, y;\n        int orderIdx; // index in selectedIdx (0..PICK-1)\n        bool isRestaurant;\n    };\n    vector<Node> nodes(2 * PICK);\n    for (int i = 0; i < PICK; ++i) {\n        int o = selectedIdx[i];\n        nodes[2*i] = {orders[o].a, orders[o].b, i, true};\n        nodes[2*i+1] = {orders[o].c, orders[o].d, i, false};\n    }\n\n    // Build valid initial route: all restaurants first, then all destinations\n    vector<int> route(2 * PICK);\n    for (int i = 0; i < PICK; ++i) route[i] = 2*i;          // restaurants\n    for (int i = 0; i < PICK; ++i) route[PICK + i] = 2*i+1; // destinations\n    \n    // Shuffle within restaurant group and destination group\n    shuffle(route.begin(), route.begin() + PICK, rng);\n    shuffle(route.begin() + PICK, route.end(), rng);\n\n    auto calcDist = [&](const vector<int>& r) {\n        int total = manhattan(DEPOT_X, DEPOT_Y, nodes[r[0]].x, nodes[r[0]].y);\n        for (int i = 0; i < 2*PICK - 1; ++i) {\n            total += manhattan(nodes[r[i]].x, nodes[r[i]].y, nodes[r[i+1]].x, nodes[r[i+1]].y);\n        }\n        total += manhattan(nodes[r[2*PICK-1]].x, nodes[r[2*PICK-1]].y, DEPOT_X, DEPOT_Y);\n        return total;\n    };\n\n    // Validate that all orders are properly completed\n    auto isValid = [&](const vector<int>& r) {\n        vector<int> restPos(PICK, -1), destPos(PICK, -1);\n        for (int i = 0; i < 2*PICK; ++i) {\n            if (nodes[r[i]].isRestaurant) restPos[nodes[r[i]].orderIdx] = i;\n            else destPos[nodes[r[i]].orderIdx] = i;\n        }\n        for (int i = 0; i < PICK; ++i) {\n            if (restPos[i] == -1 || destPos[i] == -1) return false;\n            if (restPos[i] >= destPos[i]) return false;\n        }\n        return true;\n    };\n\n    // Always valid because each order has restaurant before destination\n    assert(isValid(route));\n\n    int bestT = calcDist(route);\n    vector<int> bestRoute = route;\n\n    // 2-opt local search with strict precedence preservation\n    for (int restart = 0; restart < 5; ++restart) {\n        // Shuffle but keep restaurants before destinations\n        shuffle(route.begin(), route.begin() + PICK, rng);\n        shuffle(route.begin() + PICK, route.end(), rng);\n        \n        int curT = calcDist(route);\n        bool improved = true;\n        \n        while (improved) {\n            improved = false;\n            for (int i = 0; i < 2*PICK - 1; ++i) {\n                for (int j = i + 1; j < 2*PICK; ++j) {\n                    // Strict check: reversal cannot put any destination before its restaurant\n                    bool ok = true;\n                    for (int k = i; k <= j; ++k) {\n                        int other = j - (k - i);\n                        if (nodes[route[k]].isRestaurant && !nodes[route[other]].isRestaurant) {\n                            // Restaurant moving to destination's old position\n                            // Check if its destination is also in segment\n                            auto& rnode = nodes[route[k]];\n                            auto& dnode = nodes[route[other]];\n                            if (rnode.orderIdx == dnode.orderIdx) { ok = false; break; }\n                        } else if (!nodes[route[k]].isRestaurant && nodes[route[other]].isRestaurant) {\n                            // Destination moving to restaurant's old position\n                            auto& dnode = nodes[route[k]];\n                            auto& rnode = nodes[route[other]];\n                            if (dnode.orderIdx == rnode.orderIdx) { ok = false; break; }\n                        }\n                    }\n                    if (!ok) continue;\n                    \n                    // Compute delta distance\n                    int oldDist = 0, newDist = 0;\n                    if (i > 0) {\n                        oldDist += manhattan(nodes[route[i-1]].x, nodes[route[i-1]].y, nodes[route[i]].x, nodes[route[i]].y);\n                        newDist += manhattan(nodes[route[i-1]].x, nodes[route[i-1]].y, nodes[route[j]].x, nodes[route[j]].y);\n                    }\n                    if (j < 2*PICK - 1) {\n                        oldDist += manhattan(nodes[route[j]].x, nodes[route[j]].y, nodes[route[j+1]].x, nodes[route[j+1]].y);\n                        newDist += manhattan(nodes[route[i]].x, nodes[route[i]].y, nodes[route[j+1]].x, nodes[route[j+1]].y);\n                    }\n                    \n                    if (curT - oldDist + newDist >= curT) continue;\n                    \n                    // Apply reversal\n                    reverse(route.begin() + i, route.begin() + j + 1);\n                    curT = curT - oldDist + newDist;\n                    improved = true;\n                    break; // Only one improvement per iteration\n                }\n                if (improved) break;\n            }\n        }\n        \n        if (curT < bestT) {\n            bestT = curT;\n            bestRoute = route;\n        }\n    }\n\n    // Final validation\n    if (!isValid(bestRoute)) {\n        // Fallback: simple route with all restaurants first\n        bestRoute.resize(2*PICK);\n        for (int i = 0; i < PICK; ++i) bestRoute[i] = 2*i;\n        for (int i = 0; i < PICK; ++i) bestRoute[PICK + i] = 2*i+1;\n    }\n\n    // Output\n    cout << PICK;\n    for (int idx : selectedIdx) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n    \n    cout << 2*PICK + 2 << \" \" << DEPOT_X << \" \" << DEPOT_Y;\n    for (int idx : bestRoute) cout << \" \" << nodes[idx].x << \" \" << nodes[idx].y;\n    cout << \" \" << DEPOT_X << \" \" << DEPOT_Y << \"\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\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    vector<pair<int,int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges\n    vector<tuple<int,int,int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges[i] = {u, v, i};\n    }\n    \n    // Precompute Euclidean distances\n    vector<int> euclidean_dist(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        euclidean_dist[i] = (int)round(sqrt(dx*dx + dy*dy));\n    }\n    \n    // Initialize DSU for connectivity tracking\n    dsu dsu_uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        \n        // Read actual cost\n        long long actual_cost;\n        cin >> actual_cost;\n        \n        // If already connected, reject immediately\n        if (dsu_uf.same(u, v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        double ratio = (double)actual_cost / euclidean_dist[i];\n        \n        // Critical check: Can we still connect all components if we reject this edge?\n        // Test by checking if remaining edges can connect the current components\n        dsu temp_uf = dsu_uf;\n        bool can_connect_without = false;\n        \n        // Add remaining edges to see if they can connect everything\n        for (int j = i + 1; j < M; j++) {\n            auto [uj, vj, idxj] = edges[j];\n            if (!temp_uf.same(uj, vj)) {\n                temp_uf.merge(uj, vj);\n            }\n        }\n        \n        // If the remaining edges can connect all components, we can safely reject\n        // (if cost is bad) or we may want to accept if cost is good\n        can_connect_without = (temp_uf.groups().size() == 1);\n        \n        bool accept = false;\n        \n        if (!can_connect_without) {\n            // We MUST accept this edge to have any hope of connectivity\n            accept = true;\n        }\n        else if (ratio <= 1.3) {\n            // Very good deal, definitely accept\n            accept = true;\n        }\n        else if (ratio <= 1.6 && euclidean_dist[i] < 80) {\n            // Short-ish edge with decent cost\n            accept = true;\n        }\n        else if (ratio <= 2.0 && euclidean_dist[i] < 50) {\n            // Very short edge with acceptable cost\n            accept = true;\n        }\n        // Additional heuristics for better score\n        else if (ratio <= 1.8 && euclidean_dist[i] < 120) {\n            // Moderate edge, might be useful\n            accept = true;\n        }\n        // Default: reject if we can still connect without it\n        \n        if (accept) {\n            dsu_uf.merge(u, v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int SIZE = 30;\nconst int TURNS = 300;\nconst int INF = 1e9;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Position& other) const {\n        return !(*this == other);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;  // Start of turn positions\n    vector<vector<bool>> wall;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char moveChar[4] = {'U', 'D', 'L', 'R'};\n    const char wallChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool isWall(int x, int y) {\n        if (!isValid(x, y)) return true;\n        return wall[x][y];\n    }\n    \n    bool hasPet(int x, int y) {\n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return true;\n        }\n        return false;\n    }\n    \n    // Check if a position is occupied by any human (start of turn or planned)\n    bool hasHuman(int x, int y, const vector<Position>& currentPositions,\n                  const vector<Position>& plannedPositions) {\n        // Check start of turn positions\n        for (const auto& h : currentPositions) {\n            if (h.x == x && h.y == y) return true;\n        }\n        // Check positions humans are moving to this turn\n        for (const auto& p : plannedPositions) {\n            if (p.x == x && p.y == y) return true;\n        }\n        return false;\n    }\n    \n    // Check if a position is occupied by any human (start of turn only)\n    bool hasHumanAtStart(int x, int y) {\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return true;\n        }\n        return false;\n    }\n    \n    bool canPlaceWallAt(int x, int y, const vector<vector<bool>>& tempWalls,\n                        const vector<Position>& currentPositions,\n                        const vector<Position>& plannedPositions) {\n        if (!isValid(x, y) || wall[x][y] || tempWalls[x][y]) return false;\n        \n        // Can't place wall on pets\n        if (hasPet(x, y)) return false;\n        \n        // Can't place wall on humans (start of turn)\n        if (hasHumanAtStart(x, y)) return false;\n        \n        // Can't place wall where a human is moving to this turn\n        for (const auto& p : plannedPositions) {\n            if (p.x == x && p.y == y) return false;\n        }\n        \n        // Can't place wall adjacent to pets\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && hasPet(nx, ny)) {\n                return false;\n            }\n        }\n        \n        return true;\n    }\n    \n    bool canMoveTo(int x, int y, const vector<vector<bool>>& tempWalls,\n                   const vector<Position>& plannedPositions) {\n        if (!isValid(x, y)) return false;\n        if (wall[x][y] || tempWalls[x][y]) return false;\n        \n        // Can't move to a square another human is moving to\n        for (const auto& p : plannedPositions) {\n            if (p.x == x && p.y == y) return false;\n        }\n        \n        return true;\n    }\n    \n    // Find best wall position for a human\n    Position findBestWallPosition(int humanIdx, const vector<vector<bool>>& tempWalls,\n                                   const vector<Position>& currentPositions,\n                                   const vector<Position>& plannedPositions) {\n        auto& human = currentPositions[humanIdx];\n        double bestScore = -INF;\n        Position bestPos = {-1, -1};\n        \n        // Search in concentric squares around the human\n        for (int radius = 1; radius <= 10; radius++) {\n            for (int x = max(0, human.x - radius); x <= min(SIZE-1, human.x + radius); x++) {\n                // Check top and bottom rows\n                for (int sign = -1; sign <= 1; sign += 2) {\n                    int y = human.y + sign * radius;\n                    if (y >= 0 && y < SIZE && abs(x - human.x) <= radius) {\n                        if (canPlaceWallAt(x, y, tempWalls, currentPositions, plannedPositions)) {\n                            double score = evaluateWall(x, y, currentPositions);\n                            if (score > bestScore) {\n                                bestScore = score;\n                                bestPos = {x, y};\n                            }\n                        }\n                    }\n                }\n            }\n            for (int y = max(0, human.y - radius + 1); y <= min(SIZE-1, human.y + radius - 1); y++) {\n                // Check left and right columns\n                for (int sign = -1; sign <= 1; sign += 2) {\n                    int x = human.x + sign * radius;\n                    if (x >= 0 && x < SIZE) {\n                        if (canPlaceWallAt(x, y, tempWalls, currentPositions, plannedPositions)) {\n                            double score = evaluateWall(x, y, currentPositions);\n                            if (score > bestScore) {\n                                bestScore = score;\n                                bestPos = {x, y};\n                            }\n                        }\n                    }\n                }\n            }\n            if (bestScore > 100) break; // Found excellent position\n        }\n        \n        return bestPos;\n    }\n    \n    double evaluateWall(int x, int y, const vector<Position>& currentPositions) {\n        double score = 0;\n        \n        // Calculate center of humans\n        int cx = 0, cy = 0;\n        for (const auto& h : currentPositions) {\n            cx += h.x;\n            cy += h.y;\n        }\n        cx /= M;\n        cy /= M;\n        \n        // Distance from center\n        int distFromCenter = abs(x - cx) + abs(y - cy);\n        \n        // Ideal distance for enclosure (not too close, not too far)\n        if (distFromCenter >= 4 && distFromCenter <= 8) {\n            score += 200;\n        } else if (distFromCenter >= 2 && distFromCenter <= 12) {\n            score += 100;\n        }\n        \n        // Prefer walls close to humans (easier to reach)\n        for (const auto& h : currentPositions) {\n            double dist = sqrt((x - h.x) * (x - h.x) + (y - h.y) * (y - h.y));\n            score += 20.0 / (1 + dist);\n        }\n        \n        // Avoid walls too close to pets\n        for (const auto& p : petPos) {\n            double dist = sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));\n            if (dist < 3) score -= 500;\n            else if (dist < 5) score -= 100;\n        }\n        \n        // Prefer walls that are adjacent to existing walls (continuity)\n        int adjacentWalls = 0;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && wall[nx][ny]) adjacentWalls++;\n        }\n        score += adjacentWalls * 50;\n        \n        return score;\n    }\n    \n    char getNextMove(const Position& from, const Position& to,\n                     const vector<vector<bool>>& tempWalls,\n                     const vector<Position>& plannedPositions) {\n        if (from == to) return '.';\n        \n        // Simple greedy: move in direction that reduces distance\n        vector<pair<int, char>> possibleMoves;\n        \n        // Try direct directions first\n        if (to.x < from.x) possibleMoves.push_back({0, 'U'});\n        if (to.x > from.x) possibleMoves.push_back({1, 'D'});\n        if (to.y < from.y) possibleMoves.push_back({2, 'L'});\n        if (to.y > from.y) possibleMoves.push_back({3, 'R'});\n        \n        // Filter valid moves\n        for (auto& move : possibleMoves) {\n            int nx = from.x;\n            int ny = from.y;\n            if (move.second == 'U') nx--;\n            else if (move.second == 'D') nx++;\n            else if (move.second == 'L') ny--;\n            else if (move.second == 'R') ny++;\n            \n            if (!canMoveTo(nx, ny, tempWalls, plannedPositions)) {\n                move.first = -1;\n            }\n        }\n        \n        // Choose first valid move\n        for (auto& move : possibleMoves) {\n            if (move.first != -1) return move.second;\n        }\n        \n        // Try orthogonal directions as fallback\n        possibleMoves.clear();\n        if (canMoveTo(from.x - 1, from.y, tempWalls, plannedPositions))\n            possibleMoves.push_back({0, 'U'});\n        if (canMoveTo(from.x + 1, from.y, tempWalls, plannedPositions))\n            possibleMoves.push_back({1, 'D'});\n        if (canMoveTo(from.x, from.y - 1, tempWalls, plannedPositions))\n            possibleMoves.push_back({2, 'L'});\n        if (canMoveTo(from.x, from.y + 1, tempWalls, plannedPositions))\n            possibleMoves.push_back({3, 'R'});\n        \n        if (!possibleMoves.empty()) {\n            // Prefer move that gets closer to target\n            auto best = possibleMoves[0];\n            int bestDist = INF;\n            for (auto& move : possibleMoves) {\n                int nx = from.x;\n                int ny = from.y;\n                if (move.second == 'U') nx--;\n                else if (move.second == 'D') nx++;\n                else if (move.second == 'L') ny--;\n                else if (move.second == 'R') ny++;\n                int dist = abs(nx - to.x) + abs(ny - to.y);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = move;\n                }\n            }\n            return best.second;\n        }\n        \n        return '.';\n    }\n    \npublic:\n    Solver() {\n        wall = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n    }\n    \n    void readInput() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n            petPos[i].x--;\n            petPos[i].y--;\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n            humanPos[i].x--;\n            humanPos[i].y--;\n        }\n    }\n    \n    void solve() {\n        for (int turn = 0; turn < TURNS; turn++) {\n            string output;\n            vector<vector<bool>> tempWalls(SIZE, vector<bool>(SIZE, false));\n            vector<Position> plannedPositions;  // Where humans will be after this turn\n            vector<Position> currentPositions = humanPos;  // Start of turn positions\n            \n            for (int i = 0; i < M; i++) {\n                char action = '.';\n                auto& human = humanPos[i];\n                \n                // Find best wall position\n                Position wallTarget = findBestWallPosition(i, tempWalls, currentPositions, plannedPositions);\n                \n                if (wallTarget.x != -1) {\n                    int dist = abs(wallTarget.x - human.x) + abs(wallTarget.y - human.y);\n                    \n                    if (dist == 1) {\n                        // Adjacent to wall position - place the wall\n                        for (int d = 0; d < 4; d++) {\n                            if (human.x + dx[d] == wallTarget.x && human.y + dy[d] == wallTarget.y) {\n                                if (canPlaceWallAt(wallTarget.x, wallTarget.y, tempWalls, currentPositions, plannedPositions)) {\n                                    action = wallChar[d];\n                                    tempWalls[wallTarget.x][wallTarget.y] = true;\n                                }\n                                break;\n                            }\n                        }\n                    } else {\n                        // Need to move closer\n                        action = getNextMove(human, wallTarget, tempWalls, plannedPositions);\n                    }\n                }\n                \n                // If no action determined, try to stay safe and maybe build a nearby wall\n                if (action == '.') {\n                    // Try to find an adjacent wall to build\n                    for (int d = 0; d < 4; d++) {\n                        int nx = human.x + dx[d];\n                        int ny = human.y + dy[d];\n                        if (canPlaceWallAt(nx, ny, tempWalls, currentPositions, plannedPositions)) {\n                            action = wallChar[d];\n                            tempWalls[nx][ny] = true;\n                            break;\n                        }\n                    }\n                }\n                \n                // If still no action, move to expand territory\n                if (action == '.') {\n                    // Try to move in any valid direction\n                    if (canMoveTo(human.x - 1, human.y, tempWalls, plannedPositions)) action = 'U';\n                    else if (canMoveTo(human.x + 1, human.y, tempWalls, plannedPositions)) action = 'D';\n                    else if (canMoveTo(human.x, human.y - 1, tempWalls, plannedPositions)) action = 'L';\n                    else if (canMoveTo(human.x, human.y + 1, tempWalls, plannedPositions)) action = 'R';\n                }\n                \n                output += action;\n                \n                // Track planned position\n                Position plannedPos = human;\n                if (action == 'U') plannedPos.x--;\n                else if (action == 'D') plannedPos.x++;\n                else if (action == 'L') plannedPos.y--;\n                else if (action == 'R') plannedPos.y++;\n                plannedPositions.push_back(plannedPos);\n            }\n            \n            // Apply all walls\n            for (int x = 0; x < SIZE; x++) {\n                for (int y = 0; y < SIZE; y++) {\n                    if (tempWalls[x][y]) {\n                        wall[x][y] = true;\n                    }\n                }\n            }\n            \n            // Update human positions\n            for (int i = 0; i < M; i++) {\n                char action = output[i];\n                if (action == 'U') humanPos[i].x--;\n                else if (action == 'D') humanPos[i].x++;\n                else if (action == 'L') humanPos[i].y--;\n                else if (action == 'R') humanPos[i].y++;\n                // Wall placing actions don't change position\n            }\n            \n            // Output\n            cout << output << endl;\n            cout.flush();\n            \n            // Read pet movements\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            vector<string> petMovements(N);\n            stringstream ss(line);\n            for (int i = 0; i < N; i++) {\n                ss >> petMovements[i];\n            }\n            \n            // Update pet positions\n            for (int i = 0; i < N; i++) {\n                for (char c : petMovements[i]) {\n                    if (c == 'U') petPos[i].x--;\n                    else if (c == 'D') petPos[i].x++;\n                    else if (c == 'L') petPos[i].y--;\n                    else if (c == 'R') petPos[i].y++;\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.readInput();\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> h, v;\n    \n    bool canMove(int i, int j, int d) const {\n        if (d == 0 && i > 0 && !v[i-1][j]) return true;\n        if (d == 1 && i < 19 && !v[i][j]) return true;\n        if (d == 2 && j > 0 && !h[i][j-1]) return true;\n        if (d == 3 && j < 19 && !h[i][j]) return true;\n        return false;\n    }\n};\n\n// DP for expected score calculation (exact)\ndouble calculateExpectedScore(const string& s, int si, int sj, int ti, int tj,\n                             const Grid& grid, double p) {\n    int L = min((int)s.size(), 400);\n    vector<vector<double>> dp(20, vector<double>(20, 0.0));\n    dp[si][sj] = 1.0;\n    double expected = 0.0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n    \n    for (int step = 0; step < L; ++step) {\n        vector<vector<double>> ndp(20, vector<double>(20, 0.0));\n        \n        for (int i = 0; i < 20; ++i) {\n            for (int j = 0; j < 20; ++j) {\n                if (dp[i][j] < 1e-12) continue;\n                if (i == ti && j == tj) {\n                    expected += dp[i][j] * (401.0 - step);\n                    continue;\n                }\n                \n                // Forget with probability p\n                ndp[i][j] += dp[i][j] * p;\n                \n                // Try to move\n                int d = 0;\n                for (; d < 4; ++d) if (s[step] == dirs[d]) break;\n                if (grid.canMove(i, j, d)) {\n                    ndp[i+di[d]][j+dj[d]] += dp[i][j] * (1.0 - p);\n                } else {\n                    ndp[i][j] += dp[i][j] * (1.0 - p);\n                }\n            }\n        }\n        dp = ndp;\n    }\n    \n    // Add remaining probability at goal\n    for (int i = 0; i < 20; ++i) {\n        for (int j = 0; j < 20; ++j) {\n            if (i == ti && j == tj) {\n                expected += dp[i][j] * 1.0; // Score for reaching exactly at end\n            }\n        }\n    }\n    \n    return expected;\n}\n\n// Generate multiple candidate paths using different strategies\nvector<string> generateCandidates(int si, int sj, int ti, int tj,\n                                  const Grid& grid, double p) {\n    vector<string> candidates;\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dir_char[] = {'U', 'D', 'L', 'R'};\n    \n    // BFS for shortest path\n    vector<vector<int>> dist(20, vector<int>(20, 1e9));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    \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            if (!grid.canMove(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    // Reconstruct shortest path\n    vector<char> path;\n    int ci = ti, cj = tj;\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        if (pi == ci - 1) path.push_back('D');\n        else if (pi == ci + 1) path.push_back('U');\n        else if (pj == cj - 1) path.push_back('R');\n        else path.push_back('L');\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Strategy 1: Adaptive repeats based on position\n    for (int targetLen = (int)path.size(); targetLen <= 200; targetLen += 10) {\n        string candidate;\n        int remaining = targetLen - (int)path.size();\n        \n        // Compute criticality using DP\n        vector<double> criticality(path.size(), 1.0);\n        \n        // For each position, check how many alternative paths exist\n        for (int skip = 0; skip < (int)path.size(); ++skip) {\n            // Check if we can still reach goal with slightly different path\n            int cx = si, cy = sj;\n            for (int idx = 0; idx < (int)path.size(); ++idx) {\n                if (idx == skip) continue;\n                int d = 0;\n                if (path[idx] == 'U') d = 0;\n                else if (path[idx] == 'D') d = 1;\n                else if (path[idx] == 'L') d = 2;\n                else d = 3;\n                \n                if (grid.canMove(cx, cy, d)) {\n                    cx += di[d]; cy += dj[d];\n                }\n            }\n            // Measure Manhattan distance to goal as proxy for criticality\n            criticality[skip] = abs(cx - ti) + abs(cy - tj) + 1;\n        }\n        \n        // Normalize criticalities\n        double sumCrit = accumulate(criticality.begin(), criticality.end(), 0.0);\n        for (auto& c : criticality) c /= sumCrit;\n        \n        // Build string with adaptive repeats\n        for (int i = 0; i < (int)path.size() && (int)candidate.size() < targetLen; ++i) {\n            candidate.push_back(path[i]);\n            int extra = max(0, min(remaining, (int)(criticality[i] * remaining * 2 + 0.5)));\n            extra = min(extra, (int)(2.0 / (1.0 - p))); // Cap repeats\n            \n            for (int r = 0; r < extra && (int)candidate.size() < targetLen; ++r) {\n                candidate.push_back(path[i]);\n                remaining--;\n            }\n        }\n        \n        while ((int)candidate.size() < targetLen && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        \n        if ((int)candidate.size() <= 200) {\n            candidates.push_back(candidate);\n        }\n    }\n    \n    // Strategy 2: Even repeats\n    int evenRepeat = max(1, (int)(1.0 / (1.0 - p) + 0.5));\n    string evenStr;\n    for (char c : path) {\n        for (int r = 0; r < evenRepeat && (int)evenStr.size() < 200; ++r) {\n            evenStr.push_back(c);\n        }\n        if ((int)evenStr.size() >= 200) break;\n    }\n    candidates.push_back(evenStr);\n    \n    // Strategy 3: More aggressive repeats for high p\n    if (p > 0.3) {\n        string aggressive;\n        int repeat = (int)(1.5 / (1.0 - p) + 0.5);\n        for (char c : path) {\n            for (int r = 0; r < repeat && (int)aggressive.size() < 200; ++r) {\n                aggressive.push_back(c);\n            }\n            if ((int)aggressive.size() >= 200) break;\n        }\n        candidates.push_back(aggressive);\n    }\n    \n    return candidates;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    Grid grid;\n    grid.h.resize(20, vector<int>(19));\n    grid.v.resize(19, vector<int>(20));\n    \n    for (int i = 0; i < 20; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 19; ++j) grid.h[i][j] = s[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 20; ++j) grid.v[i][j] = s[j] - '0';\n    }\n    \n    // Generate candidates and pick the best\n    auto candidates = generateCandidates(si, sj, ti, tj, grid, p);\n    \n    string bestPath;\n    double bestScore = -1.0;\n    \n    for (const auto& candidate : candidates) {\n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Local optimization: try small adjustments\n    for (int iter = 0; iter < 50 && (int)bestPath.size() > 10; ++iter) {\n        int idx = rand() % (int)bestPath.size();\n        string modified = bestPath;\n        modified.erase(modified.begin() + idx);\n        \n        double score = calculateExpectedScore(modified, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = modified;\n        }\n    }\n    \n    // Final truncation\n    if ((int)bestPath.size() > 200) {\n        bestPath.resize(200);\n    }\n    \n    cout << bestPath << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0\n    {3, -1, -1, 0},  // 1\n    {-1, -1, 3, 2},  // 2\n    {-1, 2, 1, -1},  // 3\n    {1, 0, 3, 2},    // 4\n    {3, 2, 1, 0},    // 5\n    {2, -1, 0, -1},  // 6\n    {-1, 3, -1, 1},  // 7\n};\n\n// Ultra-fast heuristic: count connected components and their sizes\n// Returns product of two largest components\nint fastHeuristic(const int tiles[30][30]) {\n    bool visited[30][30] = {false};\n    \n    // Count degree of each tile (how many directions it connects)\n    int degreeSum = 0;\n    int goodConnections = 0;\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int deg = 0;\n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] != -1) deg++;\n            }\n            degreeSum += deg;\n            \n            // Check if adjacent tiles connect\n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] == -1) continue;\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n                \n                int nd = (to[tiles[i][j]][d] + 2) % 4;\n                if (to[tiles[ni][nj]][nd] != -1) goodConnections++;\n            }\n        }\n    }\n    \n    // Heuristic: good connections / 2 (each connection counted twice)\n    return goodConnections;\n}\n\n// Fast loop tracer - just returns length, no visited marking overhead\nint traceLoopFast(const int tiles[30][30], int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (length < 900) {\n        int d2 = to[tiles[i][j]][d];\n        if (d2 == -1) return 0;\n        \n        i += di[d2];\n        j += dj[d2];\n        if (i < 0 || i >= 30 || j < 0 || j >= 30) return 0;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\n// Compute score for final evaluation only\nlong long computeScore(const int tiles[30][30]) {\n    bool visited[30][30] = {false};\n    int L1 = 0, L2 = 0;\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            if (visited[i][j]) continue;\n            \n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] == -1) continue;\n                \n                // Quick check: is this a potential loop?\n                int len = traceLoopFast(tiles, i, j, d);\n                if (len > 0) {\n                    // Mark tiles in this loop as visited\n                    int ci = i, cj = j, cd = d;\n                    for (int k = 0; k < len; k++) {\n                        visited[ci][cj] = true;\n                        int d2 = to[tiles[ci][cj]][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                    \n                    if (len > L1) { L2 = L1; L1 = len; }\n                    else if (len > L2) { L2 = len; }\n                }\n            }\n        }\n    }\n    \n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    int tiles[30][30];\n    for (int i = 0; i < 30; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 30; j++) {\n            tiles[i][j] = line[j] - '0';\n        }\n    }\n    \n    int best[30][30];\n    memcpy(best, tiles, sizeof(tiles));\n    long long bestScore = computeScore(best);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> posDist(0, 29);\n    uniform_int_distribution<int> rotDist(1, 3);\n    \n    // Single pass greedy optimization\n    int current[30][30];\n    memcpy(current, tiles, sizeof(tiles));\n    \n    // Phase 1: Fast local improvements using heuristic\n    for (int iter = 0; iter < 500; iter++) {\n        int i = posDist(rng);\n        int j = posDist(rng);\n        int oldVal = current[i][j];\n        \n        // Try all rotations, use heuristic for quick evaluation\n        int bestRot = 0;\n        int bestHeur = -1;\n        \n        for (int r = 0; r < 4; r++) {\n            current[i][j] = (oldVal + r) % 8;\n            int h = fastHeuristic(current);\n            if (h > bestHeur) {\n                bestHeur = h;\n                bestRot = r;\n            }\n        }\n        \n        current[i][j] = (oldVal + bestRot) % 8;\n    }\n    \n    // Evaluate once\n    long long score = computeScore(current);\n    if (score > bestScore) {\n        memcpy(best, current, sizeof(best));\n        bestScore = score;\n    }\n    \n    // Phase 2: Targeted improvements on found loops\n    memcpy(current, best, sizeof(best));\n    for (int iter = 0; iter < 100; iter++) {\n        int i = posDist(rng);\n        int j = posDist(rng);\n        int oldVal = current[i][j];\n        \n        // Quick local evaluation\n        int bestRot = 0;\n        long long bestLocal = -1;\n        \n        for (int r = 0; r < 4; r++) {\n            current[i][j] = (oldVal + r) % 8;\n            long long s = computeScore(current);\n            if (s > bestLocal) {\n                bestLocal = s;\n                bestRot = r;\n            }\n        }\n        \n        current[i][j] = (oldVal + bestRot) % 8;\n        \n        if (bestLocal > bestScore) {\n            memcpy(best, current, sizeof(best));\n            bestScore = bestLocal;\n        }\n    }\n    \n    // Phase 3: Try 2x2 block rotations\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 29; j++) {\n            // Save these 4 tiles\n            int saved[4] = {current[i][j], current[i][j+1], \n                           current[i+1][j], current[i+1][j+1]};\n            \n            // Try rotating all 4 tiles together\n            for (int r = 1; r < 4; r++) {\n                current[i][j] = (saved[0] + r) % 8;\n                current[i][j+1] = (saved[1] + r) % 8;\n                current[i+1][j] = (saved[2] + r) % 8;\n                current[i+1][j+1] = (saved[3] + r) % 8;\n                \n                long long s = computeScore(current);\n                if (s > bestScore) {\n                    memcpy(best, current, sizeof(best));\n                    bestScore = s;\n                }\n            }\n            \n            // Restore\n            current[i][j] = saved[0];\n            current[i][j+1] = saved[1];\n            current[i+1][j] = saved[2];\n            current[i+1][j+1] = saved[3];\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int rot = (best[i][j] - tiles[i][j] + 8) % 8;\n            cout << (rot % 4);\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int dy[] = {-1, 1, 0, 0};  // U, D, L, R (tile moves)\nconst int dx[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\n\nint N, T;\nvector<vector<int>> board;\nint empty_y, empty_x;\nint current_ops;\n\nint hex_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nbool valid(int y, int x) {\n    return y >= 0 && y < N && x >= 0 && x < N;\n}\n\nvoid apply_move(int dir_idx) {\n    if (current_ops >= T) return;\n    int ty = empty_y + dy[dir_idx];\n    int tx = empty_x + dx[dir_idx];\n    if (!valid(ty, tx)) return;\n    swap(board[empty_y][empty_x], board[ty][tx]);\n    empty_y = ty;\n    empty_x = tx;\n    current_ops++;\n}\n\nvoid apply_moves(const string& moves) {\n    for (char c : moves) {\n        if (current_ops >= T) break;\n        if (c == 'U') apply_move(0);\n        else if (c == 'D') apply_move(1);\n        else if (c == 'L') apply_move(2);\n        else apply_move(3);\n    }\n}\n\n// Calculate tree size\nint calc_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]) continue;\n            \n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [y, x] = q.front(); q.pop();\n                size++;\n                int tile = board[y][x];\n                \n                if ((tile & UP) && y > 0 && (board[y-1][x] & DOWN) && !visited[y-1][x]) {\n                    visited[y-1][x] = true;\n                    q.push({y-1, x});\n                }\n                if ((tile & DOWN) && y < N-1 && (board[y+1][x] & UP) && !visited[y+1][x]) {\n                    visited[y+1][x] = true;\n                    q.push({y+1, x});\n                }\n                if ((tile & LEFT) && x > 0 && (board[y][x-1] & RIGHT) && !visited[y][x-1]) {\n                    visited[y][x-1] = true;\n                    q.push({y, x-1});\n                }\n                if ((tile & RIGHT) && x < N-1 && (board[y][x+1] & LEFT) && !visited[y][x+1]) {\n                    visited[y][x+1] = true;\n                    q.push({y, x+1});\n                }\n            }\n            max_size = max(max_size, size);\n        }\n    }\n    return max_size;\n}\n\n// Check if a tile has a specific direction\nbool has_up(int tile) { return tile & UP; }\nbool has_down(int tile) { return tile & DOWN; }\nbool has_left(int tile) { return tile & LEFT; }\nbool has_right(int tile) { return tile & RIGHT; }\nint count_connections(int tile) { return __builtin_popcount(tile); }\n\n// Analyze the board and try to identify which tiles should be connected\n// Returns a list of pairs that should be connected\nvector<pair<pair<int,int>, pair<int,int>>> find_desired_connections() {\n    vector<pair<pair<int,int>, pair<int,int>>> connections;\n    \n    // For each tile, check if it wants to connect to adjacent tiles\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            // Check right connection\n            if (has_right(board[i][j]) && j < N-1 && board[i][j+1] != 0) {\n                if (has_left(board[i][j+1])) {\n                    connections.push_back({{i, j}, {i, j+1}});\n                }\n            }\n            \n            // Check down connection\n            if (has_down(board[i][j]) && i < N-1 && board[i+1][j] != 0) {\n                if (has_up(board[i+1][j])) {\n                    connections.push_back({{i, j}, {i+1, j}});\n                }\n            }\n        }\n    }\n    \n    return connections;\n}\n\n// Find all connected components\nvector<vector<pair<int,int>>> find_components() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> components;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            \n            vector<pair<int,int>> comp;\n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            \n            while (!q.empty()) {\n                auto [y, x] = q.front(); q.pop();\n                comp.push_back({y, x});\n                int tile = board[y][x];\n                \n                if ((tile & UP) && y > 0 && (board[y-1][x] & DOWN) && !visited[y-1][x]) {\n                    visited[y-1][x] = true;\n                    q.push({y-1, x});\n                }\n                if ((tile & DOWN) && y < N-1 && (board[y+1][x] & UP) && !visited[y+1][x]) {\n                    visited[y+1][x] = true;\n                    q.push({y+1, x});\n                }\n                if ((tile & LEFT) && x > 0 && (board[y][x-1] & RIGHT) && !visited[y][x-1]) {\n                    visited[y][x-1] = true;\n                    q.push({y, x-1});\n                }\n                if ((tile & RIGHT) && x < N-1 && (board[y][x+1] & LEFT) && !visited[y][x+1]) {\n                    visited[y][x+1] = true;\n                    q.push({y, x+1});\n                }\n            }\n            components.push_back(comp);\n        }\n    }\n    return components;\n}\n\n// Move empty to a position adjacent to (y,x) if possible\n// Returns the move sequence\nstring move_empty_adjacent_to(int y, int x) {\n    if (empty_y == y && empty_x == x) return \"\";\n    \n    // Check if empty is already adjacent\n    for (int d = 0; d < 4; d++) {\n        if (empty_y + dy[d] == y && empty_x + dx[d] == x) {\n            // Empty is adjacent, we can move the tile\n            // But we want to move empty to y,x first\n            // Actually, we want to swap the tile at y,x into empty\n            return string(1, dir_char[d]);\n        }\n    }\n    \n    // BFS to find path for empty to reach (y,x)\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> prev_dir(N, vector<int>(N, -1));\n    \n    queue<pair<int,int>> q;\n    q.push({empty_y, empty_x});\n    vis[empty_y][empty_x] = true;\n    \n    while (!q.empty()) {\n        auto [cy, cx] = q.front(); q.pop();\n        if (cy == y && cx == x) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int ny = cy + dy[d], nx = cx + dx[d];\n            if (!valid(ny, nx) || vis[ny][nx]) continue;\n            vis[ny][nx] = true;\n            prev[ny][nx] = {cy, cx};\n            prev_dir[ny][nx] = d;\n            q.push({ny, nx});\n        }\n    }\n    \n    // Reconstruct path\n    string path;\n    int cy = y, cx = x;\n    while (cy != empty_y || cx != empty_x) {\n        int d = prev_dir[cy][cx];\n        // The tile that moved into empty at this step came from direction d\n        // So the empty moved opposite to d\n        // d=0 means tile came from up (U), so empty moves down (D)\n        if (d == 0) path += 'D';\n        else if (d == 1) path += 'U';\n        else if (d == 2) path += 'R';\n        else path += 'L';\n        \n        auto [py, px] = prev[cy][cx];\n        cy = py; cx = px;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring solve() {\n    // Read input\n    string line;\n    getline(cin, line);\n    stringstream ss(line);\n    ss >> N >> T;\n    \n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string row;\n        getline(cin, row);\n        row.erase(remove(row.begin(), row.end(), ' '), row.end());\n        for (int j = 0; j < N; j++) {\n            board[i][j] = hex_to_int(row[j]);\n            if (board[i][j] == 0) {\n                empty_y = i;\n                empty_x = j;\n            }\n        }\n    }\n    \n    current_ops = 0;\n    string total_moves;\n    \n    int initial_tree = calc_tree_size();\n    if (initial_tree == N * N - 1) return \"\";\n    \n    // Main improvement loop\n    int best_tree = initial_tree;\n    int no_improve_count = 0;\n    \n    while (current_ops < T && no_improve_count < 20) {\n        // Find desired connections based on tile patterns\n        auto desired_connections = find_desired_connections();\n        auto components = find_components();\n        \n        if (components.size() <= 1) {\n            // Already one component, check if it's a tree\n            if (calc_tree_size() == N * N - 1) break;\n        }\n        \n        bool improved = false;\n        \n        // Try to realize desired connections\n        for (auto& conn : desired_connections) {\n            if (current_ops >= T) break;\n            \n            auto [y1, x1] = conn.first;\n            auto [y2, x2] = conn.second;\n            \n            // Check if these tiles are already connected\n            int tile1 = board[y1][x1];\n            int tile2 = board[y2][x2];\n            bool already_connected = false;\n            \n            if (y1 == y2) { // horizontal\n                already_connected = has_right(tile1) && has_left(tile2);\n            } else { // vertical\n                already_connected = has_down(tile1) && has_up(tile2);\n            }\n            \n            if (!already_connected && current_ops < T) {\n                // Need to swap tiles to make them connect\n                // Find a path using empty to swap tiles around\n                string path = move_empty_adjacent_to(y1, x1);\n                if (!path.empty()) {\n                    total_moves += path;\n                    apply_moves(path);\n                    improved = true;\n                    \n                    // Move the tile into empty\n                    if (current_ops < T && empty_y == y1 && empty_x == x1) {\n                        // Try to find a good swap\n                        int best_swap_dir = -1;\n                        for (int d = 0; d < 4; d++) {\n                            int ny = y1 + dy[d];\n                            int nx = x1 + dx[d];\n                            if (!valid(ny, nx) || board[ny][nx] == 0) continue;\n                            if (ny == y2 && nx == x2) continue; // Don't swap with target\n                            \n                            // This swap might help\n                            best_swap_dir = d;\n                            break;\n                        }\n                        \n                        if (best_swap_dir != -1) {\n                            total_moves += dir_char[best_swap_dir];\n                            apply_move(best_swap_dir);\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Check if tree improved\n        int new_tree = calc_tree_size();\n        if (new_tree > best_tree) {\n            best_tree = new_tree;\n            no_improve_count = 0;\n            improved = true;\n            if (best_tree == N * N - 1) break;\n        }\n        \n        if (!improved) {\n            // Do a systematic shuffle (snake pattern)\n            no_improve_count++;\n            \n            // Move empty to (0,0) first\n            string shuffle_moves;\n            while (empty_y > 0 && current_ops < T) {\n                shuffle_moves += 'U';\n                apply_move(0);\n            }\n            while (empty_x > 0 && current_ops < T) {\n                shuffle_moves += 'L';\n                apply_move(2);\n            }\n            \n            // Snake pattern\n            for (int i = 0; i < N && current_ops < T; i++) {\n                if (i % 2 == 0) {\n                    while (empty_x < N-1 && current_ops < T) {\n                        shuffle_moves += 'R';\n                        apply_move(3);\n                    }\n                } else {\n                    while (empty_x > 0 && current_ops < T) {\n                        shuffle_moves += 'L';\n                        apply_move(2);\n                    }\n                }\n                if (i < N-1 && current_ops < T) {\n                    shuffle_moves += 'D';\n                    apply_move(1);\n                }\n            }\n            total_moves += shuffle_moves;\n        }\n    }\n    \n    return total_moves;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    string answer = solve();\n    cout << answer << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ld = long double;\n\nconst ll BOUND = 1000000000LL;\nconst ll CAKE_RADIUS = 10000LL;\n\nstruct Point {\n    ll x, y;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Build target piece sizes (largest d first)\n    vector<int> targets;\n    int total_pieces = 0;\n    for (int d = 10; d >= 1; --d) {\n        for (int j = 0; j < a[d]; ++j) {\n            targets.push_back(d);\n            total_pieces++;\n        }\n    }\n\n    // Strategy: Create a grid of alternating vertical and horizontal cuts\n    // Each cut will be a line across the entire cake (-RADIUS to RADIUS)\n    \n    vector<pair<Point,Point>> cuts;\n    vector<int> target_idx(targets.size());\n    iota(target_idx.begin(), target_idx.end(), 0);\n    \n    // We'll try multiple partitioning strategies and pick the best\n    // Strategy: Use sqrt(N) vertical cuts and remaining for horizontal\n    \n    // First, sort strawberries by x coordinate to find good vertical cut positions\n    vector<int> sorted_by_x(N);\n    iota(sorted_by_x.begin(), sorted_by_x.end(), 0);\n    sort(sorted_by_x.begin(), sorted_by_x.end(), [&](int i, int j) {\n        return strawberries[i].x < strawberries[j].x;\n    });\n    \n    // Sort by y for horizontal cuts\n    vector<int> sorted_by_y(N);\n    iota(sorted_by_y.begin(), sorted_by_y.end(), 0);\n    sort(sorted_by_y.begin(), sorted_by_y.end(), [&](int i, int j) {\n        return strawberries[i].y < strawberries[j].y;\n    });\n    \n    // Calculate ideal number of vertical and horizontal cuts\n    // We want each cell to have ~5-10 strawberries\n    int num_vertical = min(K/2, (int)sqrt(N * K / 50) + 1);\n    int num_horizontal = min(K - num_vertical, (int)sqrt(N * K / 50) + 1);\n    num_vertical = min(num_vertical, K - num_horizontal);\n    \n    // Adjust to make total = K (or close)\n    while (num_vertical + num_horizontal < K && num_vertical < N) {\n        if (num_vertical <= num_horizontal) num_vertical++;\n        else num_horizontal++;\n    }\n    \n    // Place vertical cuts at equal intervals of sorted x\n    vector<ll> vertical_positions;\n    int step = max(1, N / (num_vertical + 1));\n    for (int v = 1; v <= num_vertical; ++v) {\n        int pos_idx = min(v * step, N - 1);\n        ll cut_x = strawberries[sorted_by_x[pos_idx]].x;\n        // Avoid placing cut exactly on a strawberry\n        cut_x = max(-CAKE_RADIUS + 1LL, min(CAKE_RADIUS - 1LL, cut_x + 1));\n        vertical_positions.push_back(cut_x);\n    }\n    sort(vertical_positions.begin(), vertical_positions.end());\n    vertical_positions.erase(unique(vertical_positions.begin(), vertical_positions.end()), vertical_positions.end());\n    \n    // Place horizontal cuts at equal intervals of sorted y\n    step = max(1, N / (num_horizontal + 1));\n    vector<ll> horizontal_positions;\n    for (int h = 1; h <= num_horizontal; ++h) {\n        int pos_idx = min(h * step, N - 1);\n        ll cut_y = strawberries[sorted_by_y[pos_idx]].y;\n        cut_y = max(-CAKE_RADIUS + 1LL, min(CAKE_RADIUS - 1LL, cut_y + 1));\n        horizontal_positions.push_back(cut_y);\n    }\n    sort(horizontal_positions.begin(), horizontal_positions.end());\n    horizontal_positions.erase(unique(horizontal_positions.begin(), horizontal_positions.end()), horizontal_positions.end());\n    \n    // Create the cuts\n    for (ll x : vertical_positions) {\n        if ((int)cuts.size() >= K) break;\n        Point p1 = {x, -CAKE_RADIUS};\n        Point p2 = {x, CAKE_RADIUS};\n        cuts.emplace_back(p1, p2);\n    }\n    \n    for (ll y : horizontal_positions) {\n        if ((int)cuts.size() >= K) break;\n        Point p1 = {-CAKE_RADIUS, y};\n        Point p2 = {CAKE_RADIUS, y};\n        cuts.emplace_back(p1, p2);\n    }\n    \n    // Now we have a grid. Let's evaluate the cells and try to form pieces\n    // First, compute which cell each strawberry belongs to\n    vector<vector<int>> grid(horizontal_positions.size() + 2, vector<int>(vertical_positions.size() + 2, 0));\n    vector<vector<vector<int>>> grid_straws(horizontal_positions.size() + 2, \n                                            vector<vector<int>>(vertical_positions.size() + 2));\n    \n    for (int i = 0; i < N; ++i) {\n        int row = 0, col = 0;\n        while (row < (int)horizontal_positions.size() && strawberries[i].y > horizontal_positions[row]) row++;\n        while (col < (int)vertical_positions.size() && strawberries[i].x > vertical_positions[col]) col++;\n        grid[row][col]++;\n        grid_straws[row][col].push_back(i);\n    }\n    \n    // Now we have a grid. We need to form pieces of exact sizes 1-10.\n    // Simple greedy: process cells row by row, group adjacent cells to form pieces\n    vector<bool> used(N, false);\n    int formed_pieces = 0;\n    int target_pos = 0;\n    \n    // Process cells in order, trying to form pieces\n    for (int r = 0; r <= (int)horizontal_positions.size(); ++r) {\n        for (int c = 0; c <= (int)vertical_positions.size(); ++c) {\n            if (target_pos >= (int)targets.size()) break;\n            \n            // Get available strawberries in this cell\n            vector<int> cell_straws;\n            for (int idx : grid_straws[r][c]) {\n                if (!used[idx]) cell_straws.push_back(idx);\n            }\n            \n            int need = targets[target_pos];\n            if ((int)cell_straws.size() >= need) {\n                // We can form a piece from this cell\n                // Take the first 'need' strawberries\n                for (int k = 0; k < need; ++k) {\n                    used[cell_straws[k]] = true;\n                }\n                target_pos++;\n                formed_pieces++;\n            }\n        }\n    }\n    \n    // If we still need more pieces, try to form them from remaining strawberries\n    // by taking them from cells with surplus\n    if (target_pos < (int)targets.size()) {\n        // Collect all unused strawberries\n        vector<int> unused;\n        for (int i = 0; i < N; ++i) {\n            if (!used[i]) unused.push_back(i);\n        }\n        \n        // Sort by x coordinate for easier grouping\n        sort(unused.begin(), unused.end(), [&](int i, int j) {\n            return strawberries[i].x < strawberries[j].x;\n        });\n        \n        int u_idx = 0;\n        while (u_idx < (int)unused.size() && target_pos < (int)targets.size() && (int)cuts.size() < K) {\n            int need = targets[target_pos];\n            \n            if (u_idx + need <= (int)unused.size()) {\n                // Add a vertical cut to separate this group\n                if ((int)cuts.size() < K) {\n                    ll cut_x;\n                    if (u_idx + need < (int)unused.size()) {\n                        cut_x = (strawberries[unused[u_idx + need - 1]].x + \n                                strawberries[unused[u_idx + need]].x) / 2;\n                    } else {\n                        cut_x = strawberries[unused[u_idx]].x + 1;\n                    }\n                    cut_x = max(-CAKE_RADIUS, min(CAKE_RADIUS, cut_x));\n                    \n                    Point p1 = {cut_x, -CAKE_RADIUS};\n                    Point p2 = {cut_x, CAKE_RADIUS};\n                    cuts.emplace_back(p1, p2);\n                }\n                \n                for (int k = 0; k < need; ++k) {\n                    used[unused[u_idx + k]] = true;\n                }\n                target_pos++;\n                u_idx += need;\n            } else {\n                u_idx++;\n            }\n        }\n    }\n    \n    // Output the cuts\n    int out_k = min((int)cuts.size(), K);\n    cout << out_k << \"\\n\";\n    for (int idx = 0; idx < out_k; ++idx) {\n        cout << cuts[idx].first.x << \" \" << cuts[idx].first.y << \" \"\n             << cuts[idx].second.x << \" \" << cuts[idx].second.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> hasDot;\nvector<vector<bool>> horizSegment;\nvector<vector<bool>> vertSegment;\nvector<bool> diagSegment;\nvector<array<int, 8>> operations;\nint center;\n\nint get_weight(int x, int y) {\n    return (x-center)*(x-center) + (y-center)*(y-center) + 1;\n}\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Check if this is a valid rectangle shape\nbool isValidRectangleShape(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check axis-aligned case\n    if (x1 == x2 && x3 == x4 && y1 == y4 && y2 == y3) {\n        return (x1 != x3 && y1 != y2);  // Non-zero size\n    }\n    if (y1 == y2 && y3 == y4 && x1 == x4 && x2 == x3) {\n        return (x1 != x3 && y1 != y3);  // Non-zero size\n    }\n    \n    // Check 45-degree rectangle (diamond shape)\n    int dx12 = abs(x2 - x1), dy12 = abs(y2 - y1);\n    int dx23 = abs(x3 - x2), dy23 = abs(y3 - y2);\n    int dx34 = abs(x4 - x3), dy34 = abs(y4 - y3);\n    int dx41 = abs(x1 - x4), dy41 = abs(y1 - y4);\n    \n    if (dx12 == dy12 && dx12 > 0 && dx23 == dy23 && dx23 > 0 && \n        dx34 == dy34 && dx34 > 0 && dx41 == dy41 && dx41 > 0) {\n        int len12 = dx12 * dx12 + dy12 * dy12;\n        int len23 = dx23 * dx23 + dy23 * dy23;\n        int len34 = dx34 * dx34 + dy34 * dy34;\n        int len41 = dx41 * dx41 + dy41 * dy41;\n        return (len12 == len23 && len23 == len34 && len34 == len41);\n    }\n    \n    return false;\n}\n\n// Check if we can use a segment\nbool canUseSegment(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) { // vertical\n        int sy = min(y1, y2), ey = max(y1, y2);\n        for (int y = sy; y < ey; y++) {\n            if (vertSegment[x1][y]) return false;\n        }\n    } else if (y1 == y2) { // horizontal\n        int sx = min(x1, x2), ex = max(x1, x2);\n        for (int x = sx; x < ex; x++) {\n            if (horizSegment[x][y1]) return false;\n        }\n    } else { // diagonal\n        int dx = (x2 > x1) ? 1 : -1;\n        int dy = (y2 > y1) ? 1 : -1;\n        int x = x1, y = y1;\n        while (x != x2) {\n            int idx = min(x, x + dx) * N + min(y, y + dy);\n            if (diagSegment[idx]) return false;\n            x += dx; \n            y += dy;\n        }\n    }\n    return true;\n}\n\n// Mark a segment as used\nvoid markSegment(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) { // vertical\n        int sy = min(y1, y2), ey = max(y1, y2);\n        for (int y = sy; y < ey; y++) {\n            vertSegment[x1][y] = true;\n        }\n    } else if (y1 == y2) { // horizontal\n        int sx = min(x1, x2), ex = max(x1, x2);\n        for (int x = sx; x < ex; x++) {\n            horizSegment[x][y1] = true;\n        }\n    } else { // diagonal\n        int dx = (x2 > x1) ? 1 : -1;\n        int dy = (y2 > y1) ? 1 : -1;\n        int x = x1, y = y1;\n        while (x != x2) {\n            int idx = min(x, x + dx) * N + min(y, y + dy);\n            diagSegment[idx] = true;\n            x += dx; \n            y += dy;\n        }\n    }\n}\n\n// Check if rectangle placement is valid\nbool canPlaceRectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check bounds\n    if (!in_bounds(x1, y1) || !in_bounds(x2, y2) || \n        !in_bounds(x3, y3) || !in_bounds(x4, y4)) {\n        return false;\n    }\n    \n    // Check rectangle shape\n    if (!isValidRectangleShape(x1, y1, x2, y2, x3, y3, x4, y4)) {\n        return false;\n    }\n    \n    // p1 must be empty\n    if (hasDot[x1][y1]) return false;\n    \n    // p2, p3, p4 must have dots\n    if (!hasDot[x2][y2] || !hasDot[x3][y3] || !hasDot[x4][y4]) return false;\n    \n    // Check all four points are distinct\n    if (x1 == x2 && y1 == y2) return false;\n    if (x1 == x3 && y1 == y3) return false;\n    if (x1 == x4 && y1 == y4) return false;\n    if (x2 == x3 && y2 == y3) return false;\n    if (x2 == x4 && y2 == y4) return false;\n    if (x3 == x4 && y3 == y4) return false;\n    \n    // Check all segments are available\n    if (!canUseSegment(x1, y1, x2, y2)) return false;\n    if (!canUseSegment(x2, y2, x3, y3)) return false;\n    if (!canUseSegment(x3, y3, x4, y4)) return false;\n    if (!canUseSegment(x4, y4, x1, y1)) return false;\n    \n    // Check no other dots on the perimeter\n    auto checkSide = [&](int ax, int ay, int bx, int by) {\n        int steps = max(abs(bx - ax), abs(by - ay));\n        if (steps <= 1) return true;\n        \n        for (int i = 1; i < steps; i++) {\n            int px = ax + (bx - ax) * i / steps;\n            int py = ay + (by - ay) * i / steps;\n            if (hasDot[px][py] && \n                !(px == x1 && py == y1) &&\n                !(px == x2 && py == y2) &&\n                !(px == x3 && py == y3) &&\n                !(px == x4 && py == y4)) {\n                return false;\n            }\n        }\n        return true;\n    };\n    \n    return checkSide(x1, y1, x2, y2) && checkSide(x2, y2, x3, y3) &&\n           checkSide(x3, y3, x4, y4) && checkSide(x4, y4, x1, y1);\n}\n\n// Try to place a rectangle centered at (x,y) as p1\nbool tryPlaceRectangle(int x, int y, int& best_weight, array<int, 8>& best_op) {\n    // Try axis-aligned rectangles\n    int maxSize = min(10, N - max(x, y));\n    for (int dx = 1; dx <= maxSize && x + dx < N; dx++) {\n        for (int dy = 1; dy <= maxSize && y + dy < N; dy++) {\n            int x2 = x + dx, y2 = y;\n            int x3 = x + dx, y3 = y + dy;\n            int x4 = x, y4 = y + dy;\n            \n            if (canPlaceRectangle(x, y, x2, y2, x3, y3, x4, y4)) {\n                best_weight = get_weight(x, y);\n                best_op = {x, y, x2, y2, x3, y3, x4, y4};\n                return true;\n            }\n        }\n    }\n    \n    // Try 45-degree rectangles\n    int maxD = min(10, min(N - x, min(y + 1, N - y)));\n    for (int d = 1; d <= maxD; d++) {\n        // Horizontal diamond: p1=(x,y), p2=(x+d,y+d), p3=(x,y+2d), p4=(x-d,y+d)\n        if (x + d < N && y + d < N && x - d >= 0 && y + 2*d < N) {\n            int x2 = x + d, y2 = y + d;\n            int x3 = x, y3 = y + 2*d;\n            int x4 = x - d, y4 = y + d;\n            \n            if (canPlaceRectangle(x, y, x2, y2, x3, y3, x4, y4)) {\n                best_weight = get_weight(x, y);\n                best_op = {x, y, x2, y2, x3, y3, x4, y4};\n                return true;\n            }\n        }\n        \n        // Vertical diamond: p1=(x,y), p2=(x+d,y), p3=(x+d,y-d), p4=(x,y-d)\n        if (x + d < N && y - d >= 0) {\n            int x2 = x + d, y2 = y;\n            int x3 = x + d, y3 = y - d;\n            int x4 = x, y4 = y - d;\n            \n            if (canPlaceRectangle(x, y, x2, y2, x3, y3, x4, y4)) {\n                best_weight = get_weight(x, y);\n                best_op = {x, y, x2, y2, x3, y3, x4, y4};\n                return true;\n            }\n        }\n    }\n    \n    return false;\n}\n\nvoid solve() {\n    bool improved = true;\n    int iterations = 0;\n    \n    while (improved && iterations < 5000) {\n        improved = false;\n        iterations++;\n        \n        int best_weight = -1;\n        array<int, 8> best_op;\n        \n        // Search in high-weight areas first\n        int minX = max(0, center - N/2);\n        int maxX = min(N-1, center + N/2);\n        int minY = max(0, center - N/2);\n        int maxY = min(N-1, center + N/2);\n        \n        for (int x = minX; x <= maxX && !improved; x++) {\n            for (int y = minY; y <= maxY && !improved; y++) {\n                if (hasDot[x][y]) continue;\n                \n                int w = get_weight(x, y);\n                if (w <= best_weight) continue;\n                \n                if (tryPlaceRectangle(x, y, best_weight, best_op)) {\n                    improved = true;\n                }\n            }\n        }\n        \n        if (improved) {\n            operations.push_back(best_op);\n            hasDot[best_op[0]][best_op[1]] = true;\n            \n            markSegment(best_op[0], best_op[1], best_op[2], best_op[3]);\n            markSegment(best_op[2], best_op[3], best_op[4], best_op[5]);\n            markSegment(best_op[4], best_op[5], best_op[6], best_op[7]);\n            markSegment(best_op[6], best_op[7], best_op[0], best_op[1]);\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    center = (N-1)/2;\n    \n    hasDot.assign(N, vector<bool>(N, false));\n    horizSegment.assign(N, vector<bool>(N, false));\n    vertSegment.assign(N, vector<bool>(N, false));\n    diagSegment.assign(N * N, false);\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        hasDot[x][y] = true;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            cout << op[i] << (i < 7 ? \" \" : \"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int T = 100;\n\nstruct State {\n    int grid[N][N] = {};\n    \n    State() {}\n    State(const State& other) {\n        memcpy(grid, other.grid, sizeof(grid));\n    }\n    \n    bool valid(int x, int y) const {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void place(int p, int flavor) {\n        int count = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[x][y] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    State tilt(int d) const {\n        State res(*this);\n        \n        if (d == 0) {  // Forward\n            for (int x = 0; x < N; x++) {\n                for (int y = 1; y < N; y++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny > 0 && res.grid[x][ny-1] == 0) ny--;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 1) {  // Backward\n            for (int x = 0; x < N; x++) {\n                for (int y = N-2; y >= 0; y--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny < N-1 && res.grid[x][ny+1] == 0) ny++;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 2) {  // Left\n            for (int y = 0; y < N; y++) {\n                for (int x = 1; x < N; x++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx > 0 && res.grid[nx-1][y] == 0) nx--;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else {  // Right\n            for (int y = 0; y < N; y++) {\n                for (int x = N-2; x >= 0; x--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx < N-1 && res.grid[nx+1][y] == 0) nx++;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        \n        return res;\n    }\n    \n    double evaluate(const vector<int>& future_flavors, int remaining, int total_placed) const {\n        double score = 0.0;\n        \n        // 1. Adjacent same-flavor pairs (primary metric)\n        int pairs = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int f = grid[x][y];\n                if (x + 1 < N && grid[x+1][y] == f) pairs++;\n                if (y + 1 < N && grid[x][y+1] == f) pairs++;\n            }\n        }\n        score += pairs * 10.0;\n        \n        // 2. Component size estimation (quadratic for scoring formula)\n        bool visited[N][N] = {};\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0 || visited[x][y]) continue;\n                int flavor = grid[x][y];\n                int size = 0;\n                \n                queue<pair<int,int>> q;\n                q.push({x, y});\n                visited[x][y] = true;\n                \n                while (!q.empty()) {\n                    auto [cx, cy] = q.front(); q.pop();\n                    size++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = cx + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                        int ny = cy + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                        if (valid(nx, ny) && !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                \n                score += size * size * 0.5;\n            }\n        }\n        \n        // 3. Future potential\n        int future_counts[4] = {};\n        for (int i = 0; i < remaining; i++) {\n            future_counts[future_flavors[i]]++;\n        }\n        \n        // Check each empty cell's expansion potential\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0) continue;\n                \n                // Count adjacent same-flavor neighbors\n                int neighbor_flavors[4] = {};\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] > 0) {\n                        neighbor_flavors[grid[nx][ny]]++;\n                    }\n                }\n                \n                // Bonus for expandable space near same-flavor clusters\n                for (int f = 1; f <= 3; f++) {\n                    if (neighbor_flavors[f] > 0 && future_counts[f] > 0) {\n                        score += neighbor_flavors[f] * 3.0;\n                    }\n                }\n            }\n        }\n        \n        // 4. Empty space cluster bonus\n        int empty_visited[N][N] = {};\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0 || empty_visited[x][y]) continue;\n                \n                int empty_size = 0;\n                queue<pair<int,int>> q;\n                q.push({x, y});\n                empty_visited[x][y] = true;\n                \n                while (!q.empty()) {\n                    auto [cx, cy] = q.front(); q.pop();\n                    empty_size++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = cx + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                        int ny = cy + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                        if (valid(nx, ny) && !empty_visited[nx][ny] && grid[nx][ny] == 0) {\n                            empty_visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                \n                // Check what flavors are adjacent to this empty cluster\n                int adjacent_flavors[4] = {};\n                for (int dy = -1; dy <= 1; dy++) {\n                    for (int dx = -1; dx <= 1; dx++) {\n                        int nx = x + dx;\n                        int ny = y + dy;\n                        if (valid(nx, ny) && grid[nx][ny] > 0) {\n                            adjacent_flavors[grid[nx][ny]]++;\n                        }\n                    }\n                }\n                \n                for (int f = 1; f <= 3; f++) {\n                    if (adjacent_flavors[f] > 0 && future_counts[f] > 0) {\n                        double bonus = min(empty_size, future_counts[f]) * 0.5;\n                        score += bonus;\n                    }\n                }\n            }\n        }\n        \n        // 5. Isolation penalty\n        int isolated = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int flavor = grid[x][y];\n                bool has_same = false;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] == flavor) {\n                        has_same = true;\n                        break;\n                    }\n                }\n                if (!has_same) isolated++;\n            }\n        }\n        score -= isolated * 5.0;\n        \n        // 6. Density bonus - encourage compact clusters\n        double density_score = 0.0;\n        for (int y = 0; y < N - 1; y++) {\n            for (int x = 0; x < N - 1; x++) {\n                int cells = (grid[x][y] > 0) + (grid[x+1][y] > 0) + (grid[x][y+1] > 0) + (grid[x+1][y+1] > 0);\n                if (cells >= 3) {\n                    // Check if they're all same flavor\n                    int flavors_present[4] = {};\n                    if (grid[x][y] > 0) flavors_present[grid[x][y]]++;\n                    if (grid[x+1][y] > 0) flavors_present[grid[x+1][y]]++;\n                    if (grid[x][y+1] > 0) flavors_present[grid[x][y+1]]++;\n                    if (grid[x+1][y+1] > 0) flavors_present[grid[x+1][y+1]]++;\n                    \n                    for (int f = 1; f <= 3; f++) {\n                        if (flavors_present[f] >= 3) {\n                            density_score += 2.0;\n                        }\n                    }\n                }\n            }\n        }\n        score += density_score;\n        \n        return score;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(T);\n    for (int i = 0; i < T; i++) {\n        cin >> flavors[i];\n    }\n    \n    State current_state;\n    const char dir_names[] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < T; t++) {\n        int p;\n        cin >> p;\n        \n        current_state.place(p, flavors[t]);\n        \n        if (t == T - 1) break;\n        \n        double best_score = -1e18;\n        int best_dir = 0;\n        \n        vector<int> remaining(flavors.begin() + t + 1, flavors.end());\n        int total_placed = t + 1;\n        \n        for (int d = 0; d < 4; d++) {\n            State new_state = current_state.tilt(d);\n            double score = new_state.evaluate(remaining, T - t - 1, total_placed);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n        \n        current_state = current_state.tilt(best_dir);\n        cout << dir_names[best_dir] << '\\n';\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\nusing namespace std;\n\nconst int QUERIES = 100;\nint M;\ndouble eps;\n\nstruct Graph {\n    vector<vector<bool>> adj;\n    string str;\n    int N, edges;\n    vector<int> degSeq;\n    int triangles;\n    \n    Graph() : N(0), edges(0), triangles(0) {}\n    Graph(int n) : N(n), adj(n, vector<bool>(n, false)), edges(0), triangles(0) {}\n};\n\nstring graphToStr(const Graph& g) {\n    return g.str;\n}\n\nGraph strToGraph(const string& s) {\n    int N = 0;\n    while (N * (N-1) / 2 < (int)s.size()) N++;\n    \n    Graph g(N);\n    int idx = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            g.adj[i][j] = g.adj[j][i] = (s[idx++] == '1');\n            if (g.adj[i][j]) g.edges++;\n        }\n    }\n    \n    // Degree sequence\n    g.degSeq.resize(N);\n    for (int i = 0; i < N; i++) {\n        int deg = 0;\n        for (int j = 0; j < N; j++) {\n            if (g.adj[i][j]) deg++;\n        }\n        g.degSeq[i] = deg;\n    }\n    sort(g.degSeq.begin(), g.degSeq.end());\n    \n    // Triangles\n    g.triangles = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (!g.adj[i][j]) continue;\n            for (int k = j+1; k < N; k++) {\n                if (g.adj[i][k] && g.adj[j][k]) g.triangles++;\n            }\n        }\n    }\n    \n    g.str = s;\n    g.N = N;\n    return g;\n}\n\nstruct Features {\n    int edges;\n    double avgDeg, degStd;\n    int minDeg, maxDeg, medDeg;\n    int isolated, leaves;\n    int triangles;\n    double clustering;\n    \n    Features() : edges(0), avgDeg(0), degStd(0), minDeg(0), maxDeg(0), medDeg(0), \n                 isolated(0), leaves(0), triangles(0), clustering(0) {}\n                 \n    Features(const Graph& g) {\n        int N = g.N;\n        edges = g.edges;\n        \n        auto deg = g.degSeq;\n        avgDeg = 2.0 * edges / N;\n        \n        double var = 0;\n        for (int d : deg) var += (d - avgDeg) * (d - avgDeg);\n        degStd = sqrt(var / N);\n        \n        minDeg = deg[0];\n        maxDeg = deg[N-1];\n        medDeg = deg[N/2];\n        \n        isolated = 0;\n        leaves = 0;\n        for (int d : deg) {\n            if (d == 0) isolated++;\n            if (d == 1) leaves++;\n        }\n        \n        triangles = g.triangles;\n        \n        int triplets = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (!g.adj[i][j]) continue;\n                for (int k = j+1; k < N; k++) {\n                    if (g.adj[i][k] || g.adj[j][k]) triplets++;\n                }\n            }\n        }\n        clustering = triplets > 0 ? 3.0 * triangles / triplets : 0.0;\n    }\n};\n\n// L1 distance (more robust than L2 for high noise)\ninline double featureDist(const Features& a, const Features& b) {\n    double d = 0;\n    \n    // Edge count (most discriminative)\n    d += abs(a.edges - b.edges) * 2.0;\n    \n    // Degree distribution\n    d += abs(a.avgDeg - b.avgDeg) * 0.5;\n    d += abs(a.degStd - b.degStd) * 0.3;\n    d += abs(a.medDeg - b.medDeg) * 0.2;\n    \n    // Special nodes\n    d += abs(a.isolated - b.isolated) * 0.5;\n    d += abs(a.leaves - b.leaves) * 0.3;\n    \n    // Triangles\n    d += abs(a.triangles - b.triangles) * 0.01;\n    d += abs(a.clustering - b.clustering) * 2.0;\n    \n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> M >> eps;\n    \n    // Critical: Use much smaller N for reliable discrimination\n    // For low noise, we can use larger N but need more structure\n    // For high noise, small N is better because edge count is robust\n    int N;\n    if (eps <= 0.02) {\n        N = min(60, max(15, 10 + M/2));\n    } else if (eps <= 0.05) {\n        N = min(40, max(12, 8 + M/3));\n    } else if (eps <= 0.10) {\n        N = min(30, max(10, 6 + M/4));\n    } else if (eps <= 0.20) {\n        N = min(20, max(8, 5 + M/5));\n    } else {\n        N = min(15, max(6, 4 + M/6));\n    }\n    \n    int totalPossibleEdges = N * (N-1) / 2;\n    \n    // Generate graphs with STRUCTURED, NOT RANDOM differences\n    // Use: empty, stars, complete bipartite, near-complete, complete\n    // This ensures maximum Hamming distance between codewords\n    vector<Graph> graphs(M);\n    mt19937_64 rng(42);\n    \n    for (int k = 0; k < M; k++) {\n        Graph g(N);\n        \n        // Create deterministic structured graphs\n        double targetDensity = (double)k / max(1, M-1);\n        \n        // Strategy: Create graphs with distinct structural signatures\n        if (targetDensity < 0.1) {\n            // Empty graph for k=0, almost empty for small k\n            // Add a few edges to make degree non-zero\n            for (int i = 0; i < min(k+1, N); i++) {\n                if (i+1 < N) {\n                    g.adj[i][i+1] = g.adj[i+1][i] = true;\n                    g.edges++;\n                }\n            }\n        } else if (targetDensity < 0.3) {\n            // Star-like structures\n            int starCenter = 0;\n            int numSpokes = (targetDensity - 0.1) / 0.2 * (N-1);\n            for (int i = 1; i <= numSpokes && i < N; i++) {\n                g.adj[starCenter][i] = g.adj[i][starCenter] = true;\n                g.edges++;\n            }\n            // Add some extra edges for variation\n            uniform_int_distribution<int> dist(0, N-1);\n            while (g.edges < (int)(targetDensity * totalPossibleEdges)) {\n                int u = dist(rng);\n                int v = dist(rng);\n                if (u != v && !g.adj[u][v]) {\n                    g.adj[u][v] = g.adj[v][u] = true;\n                    g.edges++;\n                }\n            }\n        } else if (targetDensity < 0.5) {\n            // Two-cluster structures\n            int half = N / 2;\n            double intraDensity = 0.7;\n            double interDensity = 0.1 + targetDensity * 0.3;\n            \n            for (int i = 0; i < half; i++) {\n                for (int j = i+1; j < half; j++) {\n                    if (uniform_real_distribution<double>(0,1)(rng) < intraDensity) {\n                        g.adj[i][j] = g.adj[j][i] = true;\n                        g.edges++;\n                    }\n                }\n            }\n            for (int i = half; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    if (uniform_real_distribution<double>(0,1)(rng) < intraDensity) {\n                        g.adj[i][j] = g.adj[j][i] = true;\n                        g.edges++;\n                    }\n                }\n            }\n            for (int i = 0; i < half; i++) {\n                for (int j = half; j < N; j++) {\n                    if (uniform_real_distribution<double>(0,1)(rng) < interDensity) {\n                        g.adj[i][j] = g.adj[j][i] = true;\n                        g.edges++;\n                    }\n                }\n            }\n        } else {\n            // Near-complete graphs (complement of sparse structures)\n            // Start with complete graph, remove edges\n            for (int i = 0; i < N; i++) {\n                for (int j = i+1; j < N; j++) {\n                    g.adj[i][j] = g.adj[j][i] = true;\n                }\n            }\n            g.edges = totalPossibleEdges;\n            \n            int targetEdges = (int)(targetDensity * totalPossibleEdges);\n            while (g.edges > targetEdges) {\n                int u = rng() % N;\n                int v = rng() % N;\n                if (u != v && g.adj[u][v]) {\n                    g.adj[u][v] = g.adj[v][u] = false;\n                    g.edges--;\n                }\n            }\n        }\n        \n        // Compute degree sequence\n        g.degSeq.resize(N);\n        for (int i = 0; i < N; i++) {\n            int deg = 0;\n            for (int j = 0; j < N; j++) {\n                if (g.adj[i][j]) deg++;\n            }\n            g.degSeq[i] = deg;\n        }\n        sort(g.degSeq.begin(), g.degSeq.end());\n        \n        // Compute triangles\n        g.triangles = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (!g.adj[i][j]) continue;\n                for (int l = j+1; l < N; l++) {\n                    if (g.adj[i][l] && g.adj[j][l]) g.triangles++;\n                }\n            }\n        }\n        \n        // Create string\n        string s;\n        s.reserve(totalPossibleEdges);\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                s += (g.adj[i][j] ? '1' : '0');\n            }\n        }\n        g.str = s;\n        g.N = N;\n        \n        graphs[k] = g;\n    }\n    \n    // Precompute features\n    vector<Features> refFeatures(M);\n    for (int k = 0; k < M; k++) {\n        refFeatures[k] = Features(graphs[k]);\n    }\n    \n    // Output\n    cout << N << endl;\n    for (const auto& g : graphs) {\n        cout << g.str << endl;\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < QUERIES; q++) {\n        string H_str;\n        cin >> H_str;\n        \n        Graph observed = strToGraph(H_str);\n        Features obsFeat(observed);\n        \n        // Simple distance-based classification\n        int best = 0;\n        double bestDist = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double dist = featureDist(refFeatures[k], obsFeat);\n            \n            // Bonus for edge count match (most robust)\n            int edgeDiff = abs(refFeatures[k].edges - obsFeat.edges);\n            dist += edgeDiff * 3.0;\n            \n            if (dist < bestDist) {\n                bestDist = dist;\n                best = k;\n            }\n        }\n        \n        // For very high noise, just use edge count\n        if (eps > 0.25) {\n            int edgeBest = 0;\n            int minEdgeDiff = 1e9;\n            for (int k = 0; k < M; k++) {\n                int diff = abs(refFeatures[k].edges - obsFeat.edges);\n                if (diff < minEdgeDiff) {\n                    minEdgeDiff = diff;\n                    edgeBest = k;\n                }\n            }\n            best = edgeBest;\n        }\n        \n        cout << best << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\n\nint N, M, D, K;\nvector<tuple<int, int, int>> edges;\nvector<vector<pair<int, int>>> graph;\n\ndouble quick_evaluate(const vector<int>& schedule) {\n    double cost = 0;\n    vector<double> day_cost(D+1, 0);\n    vector<vector<int>> day_edges(D+1);\n    \n    // Group edges by day\n    for (int e = 0; e < M; e++) {\n        day_edges[schedule[e]].push_back(e);\n    }\n    \n    // Compute cost for each day\n    for (int day = 1; day <= D; day++) {\n        if (day_edges[day].empty()) continue;\n        \n        double total_importance = 0;\n        // Check vertex conflicts among edges on this day\n        unordered_map<int, int> vertex_usage;\n        \n        for (int e : day_edges[day]) {\n            auto [u, v, w] = edges[e];\n            vertex_usage[u]++;\n            vertex_usage[v]++;\n            // Heuristic: heavier edges cause more frustration\n            total_importance += w * 0.001; // Scale down weight\n        }\n        \n        // Penalty: vertices with multiple incident edges being repaired on same day\n        double vertex_conflict_penalty = 0;\n        for (auto& [v, count] : vertex_usage) {\n            if (count > 1) {\n                vertex_conflict_penalty += (count - 1) * (count - 1) * 1000;\n            }\n        }\n        \n        cost += total_importance + vertex_conflict_penalty;\n    }\n    \n    return cost;\n}\n\nvector<int> solve() {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Simple edge importance: weight * degree_factor\n    vector<double> edge_importance(M);\n    vector<int> degree(N, 0);\n    for (auto& [u, v, w] : edges) {\n        degree[u]++;\n        degree[v]++;\n    }\n    for (int e = 0; e < M; e++) {\n        auto [u, v, w] = edges[e];\n        edge_importance[e] = w * (1.0 / degree[u] + 1.0 / degree[v]);\n    }\n    \n    // Sort by importance\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    vector<int> best_schedule;\n    double best_cost = INF;\n    \n    // Multiple attempts (reduced from 15 to 10)\n    for (int trial = 0; trial < 10; trial++) {\n        vector<int> schedule(M);\n        vector<int> day_count(D+1, 0);\n        \n        // Fast greedy: spread important edges across days\n        // Use a round-robin approach for important edges\n        int day_idx = 1;\n        for (int idx = 0; idx < M; idx++) {\n            int e = edge_order[idx];\n            \n            // Find least loaded valid day\n            int best_day = -1;\n            double best_score = INF;\n            \n            // Try days in order, prefer less loaded days\n            vector<pair<int, int>> day_load;\n            for (int d = 1; d <= D; d++) {\n                day_load.push_back({day_count[d], d});\n            }\n            sort(day_load.begin(), day_load.end());\n            \n            for (auto& [load, d] : day_load) {\n                if (load >= K) continue;\n                \n                auto [u, v, w] = edges[e];\n                double score = load * 100;\n                \n                // Add penalty for vertex conflicts with already assigned important edges\n                for (int other = 0; other < M; other++) {\n                    if (other != e && schedule[other] == d) {\n                        auto [ou, ov, ow] = edges[other];\n                        if (ou == u || ou == v || ov == u || ov == v) {\n                            score += edge_importance[other] * 0.1;\n                        }\n                    }\n                }\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_day = d;\n                }\n            }\n            \n            schedule[e] = best_day;\n            day_count[best_day]++;\n        }\n        \n        // Lightweight local search (reduced iterations)\n        double current_cost = quick_evaluate(schedule);\n        double temp = 1.0;\n        \n        for (int iter = 0; iter < 500 && temp > 0.1; iter++) {\n            int e1 = rng() % M;\n            int old_day = schedule[e1];\n            int new_day = rng() % D + 1;\n            \n            if (new_day == old_day || day_count[new_day] >= K) continue;\n            \n            // Quick check: minimize vertex conflicts\n            auto [u, v, w] = edges[e1];\n            \n            // Count conflicts on old day (excluding this edge)\n            int old_conflicts = 0;\n            for (int other = 0; other < M; other++) {\n                if (other != e1 && schedule[other] == old_day) {\n                    auto [ou, ov, ow] = edges[other];\n                    if (ou == u || ou == v || ov == u || ov == v) {\n                        old_conflicts++;\n                    }\n                }\n            }\n            \n            // Count conflicts on new day\n            int new_conflicts = 0;\n            for (int other = 0; other < M; other++) {\n                if (other != e1 && schedule[other] == new_day) {\n                    auto [ou, ov, ow] = edges[other];\n                    if (ou == u || ou == v || ov == u || ov == v) {\n                        new_conflicts++;\n                    }\n                }\n            }\n            \n            double delta = (new_conflicts - old_conflicts) * w * 0.001;\n            \n            if (delta < 0 || exp(-delta / temp) > (double)rng() / RAND_MAX) {\n                schedule[e1] = new_day;\n                day_count[old_day]--;\n                day_count[new_day]++;\n                current_cost += delta;\n            }\n            \n            temp *= 0.99;\n        }\n        \n        double cost = quick_evaluate(schedule);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_schedule = schedule;\n        }\n    }\n    \n    return best_schedule;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\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        graph[u].push_back({v, w});\n        graph[v].push_back({u, w});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Generate schedule (no expensive precomputation)\n    vector<int> schedule = solve();\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << schedule[i] << (i+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nint D;\nint dx[] = {1, -1, 0, 0, 0, 0};\nint dy[] = {0, 0, 1, -1, 0, 0};\nint dz[] = {0, 0, 0, 0, 1, -1};\n\nstruct Pos {\n    int x, y, z;\n    Pos(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}\n    bool operator<(const Pos& other) const {\n        if (x != other.x) return x < other.x;\n        if (y != other.y) return y < other.y;\n        return z < other.z;\n    }\n    bool operator==(const Pos& other) const {\n        return x == other.x && y == other.y && z == other.z;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read silhouettes\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int k = 0; k < D; k++) cin >> f[i][k];\n        for (int k = 0; k < D; k++) cin >> r[i][k];\n    }\n    \n    // Store cubes for each object\n    vector<vector<Pos>> cubes(2);\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                        cubes[i].push_back({x, y, z});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find shared cubes (used in both objects)\n    map<Pos, int> shared_idx;\n    for (auto p : cubes[0]) {\n        if (find(cubes[1].begin(), cubes[1].end(), p) != cubes[1].end()) {\n            shared_idx[p] = shared_idx.size();\n        }\n    }\n    \n    // Assign block IDs greedily\n    // For each object, assign block IDs using BFS/DFS to merge adjacent cubes\n    vector<vector<int>> result(2, vector<int>(D * D * D, 0));\n    vector<set<int>> block_sizes; // Track which object uses which block\n    int block_cnt = 0;\n    map<pair<int, int>, int> block_id_map; // Maps (object_id, cube_position_index) to block_id\n    \n    for (int obj = 0; obj < 2; obj++) {\n        set<Pos> visited;\n        for (auto start : cubes[obj]) {\n            if (visited.count(start)) continue;\n            \n            // BFS to find connected component\n            queue<Pos> q;\n            q.push(start);\n            visited.insert(start);\n            vector<Pos> component;\n            \n            while (!q.empty()) {\n                auto p = q.front(); q.pop();\n                component.push_back(p);\n                \n                for (int d = 0; d < 6; d++) {\n                    Pos np = {p.x + dx[d], p.y + dy[d], p.z + dz[d]};\n                    if (np.x < 0 || np.x >= D || np.y < 0 || np.y >= D || np.z < 0 || np.z >= D) continue;\n                    if (visited.count(np)) continue;\n                    if (find(cubes[obj].begin(), cubes[obj].end(), np) == cubes[obj].end()) continue;\n                    visited.insert(np);\n                    q.push(np);\n                }\n            }\n            \n            // Assign block ID\n            block_cnt++;\n            for (auto p : component) {\n                int idx = p.x * D * D + p.y * D + p.z;\n                result[obj][idx] = block_cnt;\n            }\n        }\n    }\n    \n    // Now try to merge blocks that appear in both objects\n    // For simplicity, we'll keep the current blocks\n    // Output\n    cout << block_cnt << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        for (int j = 0; j < D * D * D; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <cmath>\n#include <random>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    long long w;\n};\n\nint N, M, K;\nvector<pair<int,int>> vertices;\nvector<Edge> edges;\nvector<pair<int,int>> residents;\nvector<vector<int>> adj;\nvector<vector<long long>> dist_sq_resident;\nvector<vector<long long>> all_pair_dist;\nvector<vector<long long>> dist_between_stations;\nrandom_device rd;\nmt19937 gen(rd());\n\nvoid read_input() {\n    cin >> N >> M >> K;\n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    edges.resize(M);\n    adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--; edges[j].v--;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n    residents.resize(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n    \n    dist_sq_resident.assign(N, vector<long long>(K));\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < K; k++) {\n            long long dx = vertices[i].first - residents[k].first;\n            long long dy = vertices[i].second - residents[k].second;\n            dist_sq_resident[i][k] = dx*dx + dy*dy;\n        }\n    }\n    \n    // Precompute Euclidean distances between stations\n    dist_between_stations.assign(N, vector<long long>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            long long dx = vertices[i].first - vertices[j].first;\n            long long dy = vertices[i].second - vertices[j].second;\n            dist_between_stations[i][j] = dx*dx + dy*dy;\n        }\n    }\n}\n\nstruct Solution {\n    vector<int> P;\n    vector<bool> edge_on;\n    vector<bool> reachable;\n    long long total_cost;\n    bool valid;\n    \n    Solution() : P(N, 0), edge_on(M, false), reachable(N, false), total_cost(LLONG_MAX), valid(false) {}\n    \n    void compute_reachable() {\n        fill(reachable.begin(), reachable.end(), false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (int e_idx : adj[u]) {\n                if (!edge_on[e_idx]) continue;\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                if (!reachable[v]) {\n                    reachable[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    bool check_coverage() {\n        for (int k = 0; k < K; k++) {\n            bool ok = false;\n            for (int i = 0; i < N && !ok; i++) {\n                if (!reachable[i] || P[i] == 0) continue;\n                if (dist_sq_resident[i][k] <= (long long)P[i] * P[i]) {\n                    ok = true;\n                }\n            }\n            if (!ok) return false;\n        }\n        return true;\n    }\n    \n    long long get_total_cost() {\n        long long cost = 0;\n        for (int i = 0; i < N; i++) {\n            cost += (long long)P[i] * P[i];\n        }\n        for (int j = 0; j < M; j++) {\n            if (edge_on[j]) cost += edges[j].w;\n        }\n        return cost;\n    }\n    \n    bool is_valid() {\n        for (int i = 0; i < N; i++) {\n            if (P[i] < 0 || P[i] > 5000) return false;\n        }\n        compute_reachable();\n        if (!check_coverage()) return false;\n        total_cost = get_total_cost();\n        valid = true;\n        return true;\n    }\n};\n\nint clamp_power(long long val) {\n    if (val < 0) return 0;\n    if (val > 5000) return 5000;\n    return (int)val;\n}\n\nint compute_required_power(long long dist_sq) {\n    if (dist_sq <= 0) return 0;\n    if (dist_sq >= 5000LL * 5000) return 5000;\n    long long p = (long long)ceil(sqrt((double)dist_sq));\n    return clamp_power(p);\n}\n\n// Compute all-pair shortest paths\nvector<vector<long long>> compute_all_pair_dist() {\n    vector<vector<long long>> dist(N, vector<long long>(N, LLONG_MAX));\n    for (int start = 0; start < N; start++) {\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        dist[start][start] = 0;\n        pq.push({0, start});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[start][u]) continue;\n            for (int e_idx : adj[u]) {\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                long long nd = d + edges[e_idx].w;\n                if (nd < dist[start][v]) {\n                    dist[start][v] = nd;\n                    pq.push({nd, v});\n                }\n            }\n        }\n    }\n    return dist;\n}\n\n// Optimize power levels for a set of active stations\nvoid optimize_powers(Solution& sol, const vector<int>& active_stations) {\n    // First pass: assign residents to nearest reachable station\n    vector<vector<int>> station_residents(N);\n    vector<int> current_assignments(K, -1);\n    \n    for (int k = 0; k < K; k++) {\n        int best_i = -1;\n        long long best_dist = LLONG_MAX;\n        for (int i : active_stations) {\n            if (!sol.reachable[i]) continue;\n            if (dist_sq_resident[i][k] < best_dist) {\n                best_dist = dist_sq_resident[i][k];\n                best_i = i;\n            }\n        }\n        if (best_i != -1) {\n            station_residents[best_i].push_back(k);\n            current_assignments[k] = best_i;\n        }\n    }\n    \n    // Set powers based on assigned residents\n    for (int i : active_stations) {\n        if (!sol.reachable[i] || station_residents[i].empty()) {\n            sol.P[i] = 0;\n            continue;\n        }\n        long long max_sq = 0;\n        for (int k : station_residents[i]) {\n            max_sq = max(max_sq, dist_sq_resident[i][k]);\n        }\n        sol.P[i] = compute_required_power(max_sq);\n    }\n    \n    // Second pass: try to reduce power by sharing with nearby stations\n    for (int iter = 0; iter < 3; iter++) {\n        for (int i : active_stations) {\n            if (sol.P[i] == 0) continue;\n            \n            // Try to give some residents to nearby station\n            for (int j : active_stations) {\n                if (i == j || sol.P[j] == 0) continue;\n                if (dist_between_stations[i][j] > 40000000LL) continue; // too far\n                \n                // Check if j can help cover residents of i\n                long long max_i_sq = 0, max_j_sq = 0;\n                vector<int> new_j_residents;\n                \n                for (int k : station_residents[i]) {\n                    if (dist_sq_resident[j][k] <= (long long)sol.P[j] * sol.P[j]) {\n                        new_j_residents.push_back(k);\n                    } else {\n                        max_i_sq = max(max_i_sq, dist_sq_resident[i][k]);\n                    }\n                }\n                \n                for (int k : station_residents[j]) {\n                    max_j_sq = max(max_j_sq, dist_sq_resident[j][k]);\n                }\n                \n                // If we can reduce i's power\n                if (new_j_residents.size() > 0 && sol.P[i] >= (int)ceil(sqrt(max_i_sq))) {\n                    int new_p_i = compute_required_power(max_i_sq);\n                    if (new_p_i < sol.P[i]) {\n                        sol.P[i] = new_p_i;\n                        // Update station_residents\n                        for (int k : new_j_residents) {\n                            station_residents[j].push_back(k);\n                            station_residents[i].erase(\n                                remove(station_residents[i].begin(), \n                                       station_residents[i].end(), k), \n                                station_residents[i].end());\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Build solution with given active stations\nSolution build_solution(vector<int>& active_stations) {\n    Solution sol;\n    auto shortest = compute_all_pair_dist();\n    \n    // Ensure station 1 is included\n    if (find(active_stations.begin(), active_stations.end(), 0) == active_stations.end()) {\n        active_stations.insert(active_stations.begin(), 0);\n    }\n    \n    // Build tree connecting stations using Prim's\n    vector<bool> in_tree(N, false);\n    in_tree[0] = true;\n    \n    vector<long long> min_dist(N, LLONG_MAX);\n    vector<int> parent_edge(N, -1);\n    \n    auto update_dist = [&](int u) {\n        for (int e_idx : adj[u]) {\n            int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n            if (edges[e_idx].w < min_dist[v]) {\n                min_dist[v] = edges[e_idx].w;\n                parent_edge[v] = e_idx;\n            }\n        }\n    };\n    \n    update_dist(0);\n    \n    // Connect active stations\n    vector<int> remaining;\n    for (int i : active_stations) {\n        if (!in_tree[i]) remaining.push_back(i);\n    }\n    \n    while (!remaining.empty()) {\n        int best = -1;\n        long long best_cost = LLONG_MAX;\n        \n        for (int i : remaining) {\n            if (min_dist[i] < best_cost) {\n                best_cost = min_dist[i];\n                best = i;\n            }\n        }\n        \n        if (best == -1) break;\n        \n        int e_idx = parent_edge[best];\n        if (e_idx != -1) {\n            sol.edge_on[e_idx] = true;\n        }\n        in_tree[best] = true;\n        update_dist(best);\n        \n        remaining.erase(remove(remaining.begin(), remaining.end(), best), remaining.end());\n    }\n    \n    // Connect any remaining stations via shortest paths\n    for (int i : active_stations) {\n        if (in_tree[i]) continue;\n        \n        long long best_dist = LLONG_MAX;\n        int best_start = -1;\n        for (int s : active_stations) {\n            if (in_tree[s] && shortest[s][i] < best_dist) {\n                best_dist = shortest[s][i];\n                best_start = s;\n            }\n        }\n        \n        if (best_start == -1) continue;\n        \n        // Find path\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> parent(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        \n        dist[best_start] = 0;\n        pq.push({0, best_start});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            if (u == i) break;\n            \n            for (int e_idx : adj[u]) {\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                long long nd = d + edges[e_idx].w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    parent[v] = e_idx;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        int cur = i;\n        while (parent[cur] != -1) {\n            int e_idx = parent[cur];\n            sol.edge_on[e_idx] = true;\n            in_tree[cur] = true;\n            int prev = (edges[e_idx].u == cur) ? edges[e_idx].v : edges[e_idx].u;\n            cur = prev;\n        }\n    }\n    \n    sol.compute_reachable();\n    \n    // Optimize powers\n    vector<int> reachable_stations;\n    for (int i : active_stations) {\n        if (sol.reachable[i]) {\n            reachable_stations.push_back(i);\n        }\n    }\n    \n    optimize_powers(sol, reachable_stations);\n    \n    // Try to reduce by removing unnecessary stations\n    for (int i : active_stations) {\n        if (i == 0) continue;\n        if (!sol.reachable[i] || sol.P[i] == 0) continue;\n        \n        int old_p = sol.P[i];\n        sol.P[i] = 0;\n        \n        if (!sol.check_coverage()) {\n            sol.P[i] = old_p;\n        }\n    }\n    \n    sol.is_valid();\n    return sol;\n}\n\n// Local search to improve solution\nSolution local_search(Solution base_sol, const vector<int>& base_stations) {\n    Solution best_sol = base_sol;\n    vector<int> best_stations = base_stations;\n    long long best_cost = base_sol.total_cost;\n    \n    uniform_int_distribution<int> station_dist(1, N-1);\n    uniform_int_distribution<int> power_dist(100, 500);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    int no_improve = 0;\n    double temperature = 1000.0;\n    \n    for (int iter = 0; iter < 500; iter++) {\n        vector<int> new_stations = best_stations;\n        \n        // Random operation\n        int op = uniform_int_distribution<int>(0, 2)(gen);\n        \n        if (op == 0 && new_stations.size() > 1) {\n            // Remove random station (except 0)\n            int idx = uniform_int_distribution<int>(1, new_stations.size()-1)(gen);\n            new_stations.erase(new_stations.begin() + idx);\n        } else if (op == 1 && new_stations.size() < N) {\n            // Add random station\n            int s = station_dist(gen);\n            if (find(new_stations.begin(), new_stations.end(), s) == new_stations.end()) {\n                new_stations.push_back(s);\n            }\n        } else {\n            // Replace a station\n            if (new_stations.size() > 1) {\n                int idx = uniform_int_distribution<int>(1, new_stations.size()-1)(gen);\n                int old_s = new_stations[idx];\n                int new_s = station_dist(gen);\n                if (find(new_stations.begin(), new_stations.end(), new_s) == new_stations.end()) {\n                    new_stations[idx] = new_s;\n                }\n            }\n        }\n        \n        Solution new_sol = build_solution(new_stations);\n        \n        if (new_sol.valid && new_sol.total_cost < best_cost) {\n            best_sol = new_sol;\n            best_stations = new_stations;\n            best_cost = new_sol.total_cost;\n            no_improve = 0;\n            \n            // Also try to refine further by removing redundant stations\n            for (int i : new_stations) {\n                if (i == 0) continue;\n                int old_p = best_sol.P[i];\n                best_sol.P[i] = 0;\n                if (!best_sol.check_coverage()) {\n                    best_sol.P[i] = old_p;\n                }\n            }\n            best_sol.is_valid();\n            if (best_sol.valid && best_sol.total_cost < best_cost) {\n                best_cost = best_sol.total_cost;\n            }\n        } else if (new_sol.valid && prob_dist(gen) < exp(-(new_sol.total_cost - best_cost) / temperature)) {\n            best_sol = new_sol;\n            best_stations = new_stations;\n        }\n        \n        temperature *= 0.995;\n        no_improve++;\n        if (no_improve > 100) break;\n    }\n    \n    return best_sol;\n}\n\nSolution solve() {\n    auto shortest = compute_all_pair_dist();\n    \n    // Greedy station selection\n    vector<bool> resident_covered(K, false);\n    vector<int> active_stations = {0};\n    \n    // Cover with station 1\n    for (int k = 0; k < K; k++) {\n        if (dist_sq_resident[0][k] <= 5000LL * 5000) {\n            resident_covered[k] = true;\n        }\n    }\n    \n    // Greedy selection\n    while (true) {\n        bool all_covered = true;\n        for (int k = 0; k < K; k++) {\n            if (!resident_covered[k]) { all_covered = false; break; }\n        }\n        if (all_covered) break;\n        \n        int best_i = -1;\n        double best_score = 0;\n        \n        for (int i = 1; i < N; i++) {\n            if (find(active_stations.begin(), active_stations.end(), i) != active_stations.end()) \n                continue;\n            \n            int new_residents = 0;\n            long long max_sq = 0;\n            \n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k]) {\n                    long long d = dist_sq_resident[i][k];\n                    if (d <= 5000LL * 5000) {\n                        new_residents++;\n                        max_sq = max(max_sq, d);\n                    }\n                }\n            }\n            \n            if (new_residents == 0) continue;\n            \n            long long min_edge = LLONG_MAX;\n            for (int s : active_stations) {\n                min_edge = min(min_edge, shortest[s][i]);\n            }\n            \n            if (min_edge >= LLONG_MAX / 2) continue;\n            \n            int power_needed = compute_required_power(max_sq);\n            double score = (double)new_residents * new_residents / \n                          (power_needed * power_needed + min_edge + 1);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        active_stations.push_back(best_i);\n        for (int k = 0; k < K; k++) {\n            if (!resident_covered[k] && dist_sq_resident[best_i][k] <= 5000LL * 5000) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    Solution sol = build_solution(active_stations);\n    \n    // Try local search for improvement\n    sol = local_search(sol, active_stations);\n    \n    return sol;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    read_input();\n    Solution sol = solve();\n    \n    // Final validation\n    if (!sol.valid) {\n        // Fallback: use all stations with all edges\n        sol.edge_on.assign(M, true);\n        sol.compute_reachable();\n        vector<int> all_stations(N);\n        iota(all_stations.begin(), all_stations.end(), 0);\n        optimize_powers(sol, all_stations);\n        sol.is_valid();\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << clamp_power(sol.P[i]) << (i+1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (sol.edge_on[j] ? 1 : 0) << (j+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint grid[N][N];\nvector<tuple<int,int,int,int>> ops;\n\nvoid my_swap(int x1, int y1, int x2, int y2) {\n    ops.push_back({x1, y1, x2, y2});\n    swap(grid[x1][y1], grid[x2][y2]);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j <= i; j++)\n            cin >> grid[i][j];\n    \n    // Multiple passes: bottom-up heap construction\n    // Key optimization: only swap when necessary, and track changes\n    bool changed = true;\n    while (changed) {\n        changed = false;\n        // Process from bottom to top\n        for (int x = N - 2; x >= 0 && ops.size() < 10000; x--) {\n            for (int y = 0; y <= x && ops.size() < 10000; y++) {\n                int val = grid[x][y];\n                int left = grid[x+1][y];\n                int right = grid[x+1][y+1];\n                \n                if (val > left || val > right) {\n                    changed = true;\n                    // Swap with the smaller child\n                    if (left <= right) {\n                        my_swap(x, y, x+1, y);\n                    } else {\n                        my_swap(x, y, x+1, y+1);\n                    }\n                    // After swap, the current position now has a child value\n                    // Continue checking the new parent in next iteration\n                }\n            }\n        }\n        \n        // Also check from top to bottom for cascading violations\n        for (int x = 0; x < N - 1 && ops.size() < 10000; x++) {\n            for (int y = 0; y <= x && ops.size() < 10000; y++) {\n                int val = grid[x][y];\n                int left = grid[x+1][y];\n                int right = grid[x+1][y+1];\n                \n                if (val > left || val > right) {\n                    changed = true;\n                    if (left <= right) {\n                        my_swap(x, y, x+1, y);\n                    } else {\n                        my_swap(x, y, x+1, y+1);\n                    }\n                }\n            }\n        }\n        \n        // If we're close to limit, just do one more pass and stop\n        if (ops.size() > 9500) {\n            // Final correction pass\n            for (int x = N - 2; x >= 0 && ops.size() < 10000; x--) {\n                for (int y = 0; y <= x && ops.size() < 10000; y++) {\n                    int val = grid[x][y];\n                    int left = grid[x+1][y];\n                    int right = grid[x+1][y+1];\n                    \n                    if (val > left || val > right) {\n                        if (left <= right) {\n                            my_swap(x, y, x+1, y);\n                        } else {\n                            my_swap(x, y, x+1, y+1);\n                        }\n                    }\n                }\n            }\n            break;\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nvector<vector<int>> input, output;\n\n// Check if adjacency relationships are preserved for the current output\nbool checkAdjacencies() {\n    // For each pair of colors (0..M), check if their adjacency status matches input\n    for (int c = 0; c <= m; c++) {\n        for (int d = c + 1; d <= m; d++) {\n            bool adjInput = false, adjOutput = false;\n            \n            // Check input adjacency (excluding boundary for now)\n            for (int i = 0; i < n && !adjInput; i++) {\n                for (int j = 0; j < n && !adjInput; j++) {\n                    if (input[i][j] == c || input[i][j] == d) {\n                        // Check neighbors\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (input[i][j] == c && input[ni][nj] == d) adjInput = true;\n                                if (input[i][j] == d && input[ni][nj] == c) adjInput = true;\n                            } else if (input[i][j] == 0) {\n                                // Boundary tile of color 0\n                                adjInput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Check output adjacency\n            for (int i = 0; i < n && !adjOutput; i++) {\n                for (int j = 0; j < n && !adjOutput; j++) {\n                    if (output[i][j] == c) {\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (output[ni][nj] == d) adjOutput = true;\n                            } else {\n                                // Cell is on boundary - adjacent to color 0\n                                if (d == 0) adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Also check for c=0: cells on boundary are adjacent to color 0\n            if (c == 0) {\n                for (int i = 0; i < n && !adjOutput; i++) {\n                    for (int j = 0; j < n && !adjOutput; j++) {\n                        if (output[i][j] == d) {\n                            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                                adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (adjInput != adjOutput) return false;\n        }\n    }\n    return true;\n}\n\n// Check connectivity for all colors (including 0)\nbool checkConnectivity() {\n    // For each color, check if its cells are connected (4-directional)\n    for (int c = 0; c <= m; c++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == c) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 0;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            count++;\n            \n            int di[] = {0, 1, 0, -1};\n            int dj[] = {1, 0, -1, 0};\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) {\n                    if (!visited[ni][nj] && output[ni][nj] == c) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                } else if (c == 0) {\n                    // Color 0 can connect through outside\n                    // Already counted as connected if adjacent to boundary\n                }\n            }\n        }\n        \n        if (count != (int)cells.size()) return false;\n    }\n    return true;\n}\n\n// Check if a cell can be safely set to 0 (empty)\nbool canSetToZero(int i, int j, int originalColor) {\n    int saved = output[i][j];\n    output[i][j] = 0;\n    \n    // Check constraints\n    bool valid = checkAdjacencies() && checkConnectivity();\n    \n    output[i][j] = saved;\n    return valid;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    input.assign(n, vector<int>(n));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    // Start with a copy of input\n    output = input;\n    \n    // Multiple passes to remove unnecessary cells\n    for (int pass = 0; pass < 10; pass++) {\n        // Collect all cells that might be removable\n        vector<pair<int,int>> candidates;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] > 0) {\n                    // Check if this color appears elsewhere\n                    bool hasOtherCell = false;\n                    for (int ii = 0; ii < n && !hasOtherCell; ii++) {\n                        for (int jj = 0; jj < n && !hasOtherCell; jj++) {\n                            if ((ii != i || jj != j) && output[ii][jj] == output[i][j]) {\n                                hasOtherCell = true;\n                            }\n                        }\n                    }\n                    if (hasOtherCell) {\n                        candidates.push_back({i, j});\n                    }\n                }\n            }\n        }\n        \n        // Shuffle candidates for randomness\n        random_device rd;\n        mt19937 g(rd());\n        shuffle(candidates.begin(), candidates.end(), g);\n        \n        // Try to remove cells\n        for (auto [i, j] : candidates) {\n            int originalColor = output[i][j];\n            if (originalColor == 0) continue;\n            \n            if (canSetToZero(i, j, originalColor)) {\n                output[i][j] = 0;\n            }\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << output[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint N, D, Q;\nint queries = 0;\n\nchar compare(int a, int b) {\n    if (a == b || queries >= Q) return '=';\n    queries++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    cout.flush();\n    string s; cin >> s;\n    return s[0];\n}\n\nchar compare_set(const vector<int>& L, const vector<int>& R) {\n    if (L.empty() || R.empty() || queries >= Q) return '=';\n    queries++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    string s; cin >> s;\n    return s[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> D >> Q;\n    \n    // Phase 1: Learn approximate weights using pairwise comparisons\n    // Use tournament-style sorting to get a reliable ordering\n    vector<int> order;\n    for (int i = 0; i < N; i++) {\n        order.push_back(i);\n    }\n    \n    // Sort using merge sort style comparisons (more efficient than insertion)\n    // Allocate ~N*log(N) queries for sorting if possible\n    int sort_queries = min(Q * 2 / 3, N * 10);\n    \n    // Simple bubble sort with limited passes - gives rough ordering\n    for (int pass = 0; pass < min(5, N) && queries < sort_queries; pass++) {\n        for (int i = 0; i < N - 1 && queries < sort_queries; i++) {\n            char res = compare(order[i], order[i + 1]);\n            if (res == '>') {\n                swap(order[i], order[i + 1]);\n            }\n        }\n    }\n    \n    // Phase 2: More precise comparisons for a subset of items\n    // Focus on determining the relative order of extreme items\n    int remaining = Q - queries;\n    int refine_queries = remaining * 2 / 3;\n    \n    // Do another pass of bubble sort on the bottom/top items\n    int half = N / 2;\n    for (int pass = 0; pass < 3 && queries < Q - remaining/3; pass++) {\n        // Sort bottom half\n        for (int i = half; i < N - 1 && queries < Q - remaining/3; i++) {\n            char res = compare(order[i], order[i + 1]);\n            if (res == '>') {\n                swap(order[i], order[i + 1]);\n            }\n        }\n        // Sort top half\n        for (int i = 0; i < half - 1 && queries < Q - remaining/3; i++) {\n            char res = compare(order[i], order[i + 1]);\n            if (res == '>') {\n                swap(order[i], order[i + 1]);\n            }\n        }\n    }\n    \n    // Phase 3: Create initial groups using greedy approach\n    // Assign weights based on position (exponential scale since weights follow exponential distribution)\n    vector<double> estimated_weights(N);\n    for (int i = 0; i < N; i++) {\n        // Weight estimation: items at higher positions are heavier\n        // Use exponential distribution characteristic\n        estimated_weights[order[i]] = exp(1.0 * i / N * 5); // Rough exponential scaling\n    }\n    \n    // Greedy assignment: assign heaviest items first to lightest groups\n    vector<vector<int>> groups(D);\n    vector<double> group_weights(D, 0);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = order[i];\n        int best_group = 0;\n        double min_weight = group_weights[0];\n        \n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] < min_weight) {\n                min_weight = group_weights[j];\n                best_group = j;\n            }\n        }\n        \n        groups[best_group].push_back(item);\n        group_weights[best_group] += estimated_weights[item];\n    }\n    \n    // Phase 4: Refinement using real comparisons\n    remaining = Q - queries;\n    int refine_ops = min(remaining / 2, 30);\n    \n    for (int op = 0; op < refine_ops; op++) {\n        if (remaining < 2) break;\n        \n        // Find the most imbalanced pair of groups\n        int g1 = -1, g2 = -1;\n        double max_diff = 0;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = i + 1; j < D; j++) {\n                if (groups[i].empty() || groups[j].empty()) continue;\n                double diff = abs(group_weights[i] - group_weights[j]);\n                if (diff > max_diff) {\n                    max_diff = diff;\n                    g1 = i;\n                    g2 = j;\n                }\n            }\n        }\n        \n        if (g1 == -1 || max_diff < 0.1) break;\n        \n        // Actually compare the groups\n        remaining--;\n        char real_res = compare_set(groups[g1], groups[g2]);\n        \n        // Determine which is actually heavier\n        int heavy = (real_res == '>') ? g1 : (real_res == '<') ? g2 : -1;\n        int light = (real_res == '>') ? g2 : (real_res == '<') ? g1 : -1;\n        \n        if (heavy == -1) continue; // Equal weights\n        \n        // Try to move one item from heavy to light\n        if (groups[heavy].size() <= 1 || remaining < 1) continue;\n        \n        // Pick an item that would help balance (prefer middle-weight items)\n        int move_idx = groups[heavy].size() / 2; // Middle item\n        int item = groups[heavy][move_idx];\n        \n        // Move it\n        groups[heavy].erase(groups[heavy].begin() + move_idx);\n        groups[light].push_back(item);\n        group_weights[heavy] -= estimated_weights[item];\n        group_weights[light] += estimated_weights[item];\n        \n        // Verify the move helped\n        remaining--;\n        char verify_res = compare_set(groups[heavy], groups[light]);\n        \n        if (verify_res == '>') {\n            // Still heavier, try moving another item\n            if (groups[heavy].size() > 1 && remaining >= 1) {\n                int item2 = groups[heavy].back();\n                groups[heavy].pop_back();\n                groups[light].push_back(item2);\n                group_weights[heavy] -= estimated_weights[item2];\n                group_weights[light] += estimated_weights[item2];\n                remaining--;\n            }\n        }\n        // If verify_res == '<' or '=', the moves helped, keep them\n    }\n    \n    // Consume remaining queries\n    while (queries < Q) {\n        compare(0, min(1, N - 1));\n    }\n    \n    // Create final assignment\n    vector<int> assignment(N);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << (i ? \" \" : \"\") << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int n = 200, m = 10;\n    const int h = n / m; // 20\n    \n    // Read input\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; j++) {\n            cin >> stacks[i][j];\n        }\n        reverse(stacks[i].begin(), stacks[i].end()); // top is at back\n    }\n    \n    vector<array<int, 2>> operations;\n    int next_to_remove = 1;\n    \n    // Helper to remove from top\n    auto try_remove = [&]() -> bool {\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_to_remove) {\n                stacks[i].pop_back();\n                operations.push_back({next_to_remove, 0});\n                next_to_remove++;\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    // Helper to find stack containing a given box\n    auto find_stack = [&](int v) -> 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] == v) return i;\n            }\n        }\n        return -1;\n    };\n    \n    // Remove easily accessible boxes first\n    while (true) {\n        bool removed = try_remove();\n        if (!removed) break;\n    }\n    \n    // Process remaining boxes\n    while (next_to_remove <= n) {\n        int target_stack = find_stack(next_to_remove);\n        if (target_stack == -1) {\n            break;\n        }\n        \n        auto& st = stacks[target_stack];\n        // Find position of target box (from top, which is back)\n        int pos = -1;\n        for (int i = 0; i < (int)st.size(); i++) {\n            if (st[i] == next_to_remove) {\n                pos = i;\n                break;\n            }\n        }\n        \n        if (pos == (int)st.size() - 1) {\n            // It's already on top\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n            continue;\n        }\n        \n        // Need to move boxes above it\n        // Find best destination: stack with smallest top, or empty stack\n        int best_dest = -1;\n        int best_top = n + 1;\n        for (int i = 0; i < m; i++) {\n            if (i == target_stack) continue;\n            if (stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n            if (stacks[i].back() < best_top) {\n                best_top = stacks[i].back();\n                best_dest = i;\n            }\n        }\n        \n        // Move boxes from position pos+1 to end to best_dest\n        int k = (int)st.size() - pos - 1;\n        // Move in one operation by moving the top box v = st[pos+1]\n        if (k > 0) {\n            int v = st[pos + 1];\n            operations.push_back({v, best_dest});\n            // Update stacks\n            vector<int> moved(st.begin() + pos + 1, st.end());\n            st.resize(pos + 1);\n            for (int x : moved) {\n                stacks[best_dest].push_back(x);\n            }\n        }\n        \n        // Now remove the target box\n        if (!st.empty() && st.back() == next_to_remove) {\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n        }\n        \n        // Try to remove any consecutive boxes that are now on top\n        while (true) {\n            bool removed = try_remove();\n            if (!removed) break;\n        }\n        \n        if (operations.size() > 5000) break;\n    }\n    \n    // Output\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_CELL = MAX_N * MAX_N;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\n\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dirChar[4] = {'R', 'D', 'L', 'U'};\n\nint cellId(int i, int j) { return i * N + j; }\n\nvector<int> neighbors[MAX_CELL];\nint dist[MAX_CELL][MAX_CELL];\n\nvoid buildGraph() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = cellId(i, j);\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = cellId(i, j+1);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = cellId(i+1, j);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n        }\n    }\n}\n\nvoid precomputeDistances() {\n    int total = N * N;\n    for (int src = 0; src < total; src++) {\n        fill(dist[src], dist[src] + total, 1e9);\n        queue<int> q;\n        dist[src][src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int nb : neighbors[u]) {\n                if (dist[src][nb] == 1e9) {\n                    dist[src][nb] = dist[src][u] + 1;\n                    q.push(nb);\n                }\n            }\n        }\n    }\n}\n\n// DFS coverage (Euler tour)\nvoid dfsCover(int i, int j, vector<vector<bool>>& vis, string& route) {\n    vis[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (dir == 0 && v[i][j] == '1') continue;\n        if (dir == 1 && h[i][j] == '1') continue;\n        if (dir == 2 && v[i][j-1] == '1') continue;\n        if (dir == 3 && h[i-1][j] == '1') continue;\n        if (!vis[ni][nj]) {\n            route.push_back(dirChar[dir]);\n            dfsCover(ni, nj, vis, route);\n            route.push_back(dirChar[(dir+2)%4]);\n        }\n    }\n}\n\n// Get path from src to dst as list of direction indices\nvector<int> getPath(int src, int dst) {\n    vector<int> path;\n    int cur = src;\n    while (cur != dst) {\n        for (int nb : neighbors[cur]) {\n            if (dist[nb][dst] == dist[cur][dst] - 1) {\n                // Determine direction\n                int ci = cur / N, cj = cur % N;\n                int ni = nb / N, nj = nb % N;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (ci + di[dir] == ni && cj + dj[dir] == nj) {\n                        path.push_back(dir);\n                        break;\n                    }\n                }\n                cur = nb;\n                break;\n            }\n        }\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n\n    buildGraph();\n    precomputeDistances();\n\n    const int MAX_MOVES = 100000;\n    int totalCells = N * N;\n\n    // Phase 1: DFS coverage\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    string route;\n    route.reserve(MAX_MOVES);\n    dfsCover(0, 0, vis, route);\n    int dfsLen = (int)route.size();\n\n    // Initialize dirt state after DFS\n    vector<vector<int>> dirt(N, vector<int>(N, 0));\n    int curPos = 0;\n    {\n        int ci = 0, cj = 0;\n        for (char ch : route) {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n            int dir = -1;\n            if (ch == 'R') dir = 0;\n            else if (ch == 'D') dir = 1;\n            else if (ch == 'L') dir = 2;\n            else if (ch == 'U') dir = 3;\n            ci += di[dir]; cj += dj[dir];\n            dirt[ci][cj] = 0;\n        }\n        curPos = 0;\n    }\n\n    int remainingSteps = MAX_MOVES - dfsLen;\n    int stepsUsed = 0;\n\n    // We'll repeatedly find the best cell to visit, compute full path, and execute it\n    while (stepsUsed < remainingSteps) {\n        // Check if remaining steps are enough to return to origin\n        if (remainingSteps - stepsUsed <= dist[curPos][0] + 2) {\n            // Need to start heading back\n            break;\n        }\n\n        // Find the cell with the highest \"urgency\" = d * (time since last visit)\n        // But we also consider how many more times we want to visit it\n        // Target visit count proportional to sqrt(d)\n        \n        int bestTarget = -1;\n        double bestScore = -1e18;\n        \n        for (int id = 0; id < totalCells; id++) {\n            if (id == curPos) continue; // already here\n            \n            int i = id / N, j = id % N;\n            \n            // Urgency = current dirt accumulation\n            double urgency = (double)dirt[i][j] / (1 + d[i][j]); // normalize by dirt rate\n            \n            // Score = urgency / distance (prioritize nearby high-urgency cells)\n            double score = urgency / (1 + dist[curPos][id]);\n            \n            // Add bonus for cells with high dirt rate (break ties)\n            score += (double)d[i][j] / 100000.0;\n            \n            if (score > bestScore) {\n                bestScore = score;\n                bestTarget = id;\n            }\n        }\n        \n        if (bestTarget == -1) break;\n        \n        // Compute full path to bestTarget\n        vector<int> path = getPath(curPos, bestTarget);\n        \n        // Check if we have enough steps for this path + eventual return\n        if (stepsUsed + (int)path.size() + dist[bestTarget][0] > remainingSteps) {\n            // Can't make this trip, try a shorter one\n            // Sort targets by distance and try the closest feasible one\n            vector<pair<int,int>> candidates; // (distance, id)\n            for (int id = 0; id < totalCells; id++) {\n                if (id == curPos) continue;\n                candidates.push_back({dist[curPos][id], id});\n            }\n            sort(candidates.begin(), candidates.end());\n            \n            bool found = false;\n            for (auto& p : candidates) {\n                int id = p.second;\n                vector<int> shortPath = getPath(curPos, id);\n                if (stepsUsed + (int)shortPath.size() + dist[id][0] <= remainingSteps) {\n                    path = shortPath;\n                    bestTarget = id;\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) break;\n        }\n        \n        // Execute the path\n        for (int dir : path) {\n            route.push_back(dirChar[dir]);\n            int ci = curPos / N, cj = curPos % N;\n            int ni = ci + di[dir], nj = cj + dj[dir];\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n            curPos = cellId(ni, nj);\n            dirt[ni][nj] = 0;\n            stepsUsed++;\n        }\n    }\n\n    // Return to origin\n    vector<int> returnPath = getPath(curPos, 0);\n    for (int dir : returnPath) {\n        route.push_back(dirChar[dir]);\n    }\n\n    // Ensure length\n    if ((int)route.size() > MAX_MOVES) {\n        route.resize(MAX_MOVES);\n    }\n\n    cout << route << endl;\n\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<pair<int,int>> char_pos[26];\n\nvoid precompute() {\n    for (int c = 0; c < 26; c++) {\n        char_pos[c].clear();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == c + 'A') {\n                    char_pos[c].push_back({i, j});\n                }\n            }\n        }\n    }\n}\n\n// For a given sequence of characters, find the optimal typing path\nvector<pair<int,int>> get_optimal_path(const string& s, int start_i, int start_j) {\n    vector<pair<int,int>> path;\n    int cur_i = start_i, cur_j = start_j;\n    \n    for (char c : s) {\n        // Find closest position with character c\n        int best_dist = 1e9, best_i = -1, best_j = -1;\n        for (auto& p : char_pos[c - 'A']) {\n            int dist = abs(p.first - cur_i) + abs(p.second - cur_j) + 1;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_i = p.first;\n                best_j = p.second;\n            }\n        }\n        path.push_back({best_i, best_j});\n        cur_i = best_i;\n        cur_j = best_j;\n    }\n    \n    return path;\n}\n\n// Compute overlap between two strings\nint compute_overlap(const string& a, const string& b) {\n    for (int len = min((int)a.size(), (int)b.size()); len >= 0; len--) {\n        if (a.substr(a.size() - len) == b.substr(0, len)) {\n            return len;\n        }\n    }\n    return 0;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    cin >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    words.resize(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n    \n    precompute();\n    \n    // Build superstring with maximum overlap\n    string result;\n    vector<bool> used(M, false);\n    \n    // Start with longest word (just heuristic)\n    int start_idx = 0;\n    for (int i = 1; i < M; i++) {\n        if (words[i].size() > words[start_idx].size()) start_idx = i;\n    }\n    \n    result = words[start_idx];\n    used[start_idx] = true;\n    int added = 1;\n    \n    while (added < M) {\n        int best_overlap = -1;\n        int best_word = -1;\n        bool at_end = true;\n        \n        // Check if any word is already contained\n        for (int i = 0; i < M; i++) {\n            if (!used[i] && result.find(words[i]) != string::npos) {\n                used[i] = true;\n                added++;\n                best_word = -2; // signal\n                break;\n            }\n        }\n        if (best_word == -2) continue;\n        \n        // Find best word to add at end or beginning\n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            \n            // Try at end\n            int ov_end = compute_overlap(result, words[i]);\n            if (ov_end > best_overlap) {\n                best_overlap = ov_end;\n                best_word = i;\n                at_end = true;\n            }\n            \n            // Try at beginning\n            int ov_begin = compute_overlap(words[i], result);\n            if (ov_begin > best_overlap) {\n                best_overlap = ov_begin;\n                best_word = i;\n                at_end = false;\n            }\n        }\n        \n        if (best_word == -1) {\n            // No overlap possible, just add first unused word\n            for (int i = 0; i < M; i++) {\n                if (!used[i]) {\n                    best_word = i;\n                    best_overlap = 0;\n                    at_end = true;\n                    break;\n                }\n            }\n        }\n        \n        used[best_word] = true;\n        added++;\n        \n        if (at_end) {\n            result += words[best_word].substr(best_overlap);\n        } else {\n            result = words[best_word].substr(0, 5 - best_overlap) + result;\n        }\n    }\n    \n    // Get optimal path for the superstring\n    auto path = get_optimal_path(result, si, sj);\n    \n    // Output\n    for (int i = 0; i < min((int)path.size(), 5000); i++) {\n        cout << path[i].first << \" \" << path[i].second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct OilField {\n    int id;\n    int size;\n    vector<pair<int,int>> cells; // relative positions\n    int max_i, max_j; // maximum coordinates\n};\n\nint N, M;\ndouble eps;\nvector<OilField> fields;\nset<pair<int,int>> known_oil, known_dry;\n\n// Safely read double response\ndouble read_double() {\n    string line;\n    while (line.empty()) {\n        if (!getline(cin, line)) break;\n    }\n    return stod(line);\n}\n\n// Query single cell\nint query_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl << flush;\n    return (int)read_double();\n}\n\n// Query set of cells\ndouble query_set(const vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto [i,j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n    return read_double();\n}\n\n// Make guess\nbool make_guess(const vector<pair<int,int>>& guess) {\n    cout << \"a \" << guess.size();\n    for (auto [i,j] : guess) cout << \" \" << i << \" \" << j;\n    cout << endl << flush;\n    int result = (int)read_double();\n    return result == 1;\n}\n\nint main() {\n    // Read parameters\n    string first_line;\n    getline(cin, first_line);\n    stringstream ss(first_line);\n    ss >> N >> M >> eps;\n    \n    // Read oil field shapes\n    fields.resize(M);\n    for (int k = 0; k < M; k++) {\n        string line;\n        getline(cin, line);\n        stringstream ssf(line);\n        \n        int d;\n        ssf >> d;\n        \n        fields[k].id = k;\n        fields[k].size = d;\n        fields[k].cells.resize(d);\n        fields[k].max_i = 0;\n        fields[k].max_j = 0;\n        \n        for (int t = 0; t < d; t++) {\n            ssf >> fields[k].cells[t].first >> fields[k].cells[t].second;\n            fields[k].max_i = max(fields[k].max_i, fields[k].cells[t].first);\n            fields[k].max_j = max(fields[k].max_j, fields[k].cells[t].second);\n        }\n    }\n    \n    // Strategy: Use grid-based probing with small random sets\n    // First, do some initial divinations to get a rough idea\n    \n    // Phase 1: Row queries (cost effective)\n    vector<double> row_sums(N, 0.0);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) {\n            row.push_back({i,j});\n        }\n        row_sums[i] = query_set(row);\n    }\n    \n    // Phase 2: Column queries\n    vector<double> col_sums(N, 0.0);\n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) {\n            col.push_back({i,j});\n        }\n        col_sums[j] = query_set(col);\n    }\n    \n    // Estimate oil probabilities using tomographic reconstruction\n    vector<vector<double>> prob(N, vector<double>(N, 0.0));\n    double total_estimate = 0;\n    for (int i = 0; i < N; i++) total_estimate += row_sums[i];\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            // Simple reconstruction: average of row and column estimates\n            double row_contrib = row_sums[i] / N;\n            double col_contrib = col_sums[j] / N;\n            prob[i][j] = (row_contrib + col_contrib) / 2.0;\n            prob[i][j] = max(0.0, min(1.0, prob[i][j]));\n        }\n    }\n    \n    // Phase 3: Drill cells with highest probability\n    int ops_used = 2 * N; // for initial queries\n    int max_ops = 2 * N * N - M; // leave room for final guess and some extra queries\n    \n    // Collect cells sorted by probability\n    vector<tuple<double,int,int>> priority;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            priority.push_back({prob[i][j], i, j});\n        }\n    }\n    sort(priority.rbegin(), priority.rend());\n    \n    // Drill cells, but also try to verify with small divination sets\n    for (auto [p, i, j] : priority) {\n        if (ops_used >= max_ops) break;\n        if (known_oil.count({i,j}) || known_dry.count({i,j})) continue;\n        \n        // If probability is very low, skip (likely no oil)\n        if (p < 0.1 && known_oil.size() > 0) break;\n        \n        int val = query_cell(i, j);\n        ops_used++;\n        \n        if (val > 0) {\n            known_oil.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n        }\n    }\n    \n    // Phase 4: Use known oil field shapes to predict remaining cells\n    set<pair<int,int>> final_guess = known_oil;\n    \n    // For each oil field, try to find a position that covers all known oil cells\n    for (int k = 0; k < M && ops_used < max_ops; k++) {\n        bool found = false;\n        int best_i = 0, best_j = 0;\n        int max_covered = 0;\n        \n        // Try all positions\n        for (int pi = 0; pi + fields[k].max_i < N; pi++) {\n            for (int pj = 0; pj + fields[k].max_j < N; pj++) {\n                int covered = 0;\n                bool valid = true;\n                \n                // Check if position overlaps with known dry cells\n                for (auto [di,dj] : fields[k].cells) {\n                    int ni = pi + di, nj = pj + dj;\n                    if (known_dry.count({ni,nj})) {\n                        valid = false;\n                        break;\n                    }\n                }\n                if (!valid) continue;\n                \n                // Count how many known oil cells are covered\n                for (auto [oi,oj] : known_oil) {\n                    for (auto [di,dj] : fields[k].cells) {\n                        if (pi + di == oi && pj + dj == oj) {\n                            covered++;\n                            break;\n                        }\n                    }\n                }\n                \n                if (covered > max_covered) {\n                    max_covered = covered;\n                    best_i = pi;\n                    best_j = pj;\n                    found = true;\n                }\n            }\n        }\n        \n        // If we found a good position, add its cells\n        if (found && max_covered > 0) {\n            for (auto [di,dj] : fields[k].cells) {\n                int ni = best_i + di, nj = best_j + dj;\n                if (known_dry.count({ni,nj}) == 0) {\n                    final_guess.insert({ni,nj});\n                }\n            }\n        }\n    }\n    \n    // Phase 5: Verify suspicious cells with divination if we have operations left\n    // Look for cells that are likely oil but not yet confirmed\n    vector<pair<int,int>> suspect_cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (final_guess.count({i,j}) || known_dry.count({i,j})) continue;\n            // Check if this cell is near known oil (could be part of a shape)\n            bool near_oil = false;\n            for (int di = -1; di <= 1 && !near_oil; di++) {\n                for (int dj = -1; dj <= 1 && !near_oil; dj++) {\n                    if (known_oil.count({i+di, j+dj})) {\n                        near_oil = true;\n                    }\n                }\n            }\n            if (near_oil && prob[i][j] > 0.3) {\n                suspect_cells.push_back({i,j});\n            }\n        }\n    }\n    \n    // Drill suspect cells if we have enough operations\n    for (auto [i,j] : suspect_cells) {\n        if (ops_used >= max_ops) break;\n        int val = query_cell(i, j);\n        ops_used++;\n        if (val > 0) {\n            known_oil.insert({i,j});\n            final_guess.insert({i,j});\n        } else {\n            known_dry.insert({i,j});\n            final_guess.erase({i,j});\n        }\n    }\n    \n    // Generate final guess\n    vector<pair<int,int>> guess_list(final_guess.begin(), final_guess.end());\n    make_guess(guess_list);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Store rectangles: for each day [d], store N rectangles as (i0, j0, i1, j1)\n    vector<vector<array<int,4>>> rect(D, vector<array<int,4>>(N));\n    \n    // Day 0: simple strips\n    {\n        int cur_y = 0;\n        for (int k = 0; k < N; k++) {\n            int need_h = (a[0][k] + W - 1) / W;  // ceil division\n            // If last reservation, take remaining space\n            if (k == N - 1) {\n                need_h = W - cur_y;\n            }\n            // Ensure we don't exceed W\n            if (cur_y + need_h > W) {\n                need_h = W - cur_y;\n            }\n            rect[0][k] = {cur_y, 0, cur_y + need_h, W};\n            cur_y += need_h;\n        }\n    }\n    \n    // Store previous boundaries\n    vector<int> prev_bounds(N + 1);\n    {\n        int cur = 0;\n        prev_bounds[0] = 0;\n        for (int k = 0; k < N; k++) {\n            cur += rect[0][k][2] - rect[0][k][0];  // height\n            prev_bounds[k + 1] = cur;\n        }\n    }\n    \n    // For each subsequent day\n    for (int d = 1; d < D; d++) {\n        // First compute minimal heights needed for each reservation\n        vector<int> need_h(N);\n        int total_need = 0;\n        for (int k = 0; k < N; k++) {\n            need_h[k] = (a[d][k] + W - 1) / W;  // ceil division\n            total_need += need_h[k];\n        }\n        \n        // DP: dp[current_boundary] = min cost\n        const int INF = 1e9;\n        vector<int> dp(W + 1, INF);\n        dp[0] = 0;\n        \n        for (int k = 0; k < N; k++) {\n            vector<int> ndp(W + 1, INF);\n            int prev_start = prev_bounds[k];\n            int prev_end = prev_bounds[k + 1];\n            \n            for (int cur_start = 0; cur_start <= W; cur_start++) {\n                if (dp[cur_start] >= INF) continue;\n                \n                // Try all possible heights for this reservation\n                for (int h = need_h[k]; h <= W - cur_start; h++) {\n                    int cur_end = cur_start + h;\n                    \n                    // Cost to change boundaries\n                    int change_cost = abs(cur_start - prev_start) + abs(cur_end - prev_end);\n                    \n                    // Area penalty\n                    int area = h * W;\n                    int penalty = 0;\n                    if (area < a[d][k]) {\n                        penalty = 100 * (a[d][k] - area);\n                    }\n                    \n                    int new_cost = dp[cur_start] + change_cost + penalty;\n                    if (new_cost < ndp[cur_end]) {\n                        ndp[cur_end] = new_cost;\n                    }\n                }\n            }\n            dp = move(ndp);\n        }\n        \n        // Find best final boundary\n        int best_cost = INF;\n        int best_final = W;  // must end at W\n        for (int h = W; h <= W; h++) {\n            if (dp[h] < best_cost) {\n                best_cost = dp[h];\n                best_final = h;\n            }\n        }\n        \n        // Backtrack to get boundaries\n        vector<int> new_bounds(N + 1);\n        new_bounds[N] = W;\n        \n        // Greedy approximation: just use need_h with possible trimming\n        {\n            int cur_y = 0;\n            for (int k = 0; k < N; k++) {\n                int h = need_h[k];\n                if (k == N - 1) {\n                    h = W - cur_y;\n                }\n                if (cur_y + h > W) {\n                    h = W - cur_y;\n                }\n                rect[d][k] = {cur_y, 0, cur_y + h, W};\n                new_bounds[k] = cur_y;\n                cur_y += h;\n            }\n            new_bounds[N] = W;\n        }\n        \n        // Update previous boundaries\n        prev_bounds = move(new_bounds);\n    }\n    \n    // Output rectangles\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto [i0, j0, i1, j1] = rect[d][k];\n            cout << i0 << \" \" << j0 << \" \" << i1 << \" \" << j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int STAMP_SIZE = 3;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_actual, M, K;\n    cin >> N_actual >> M >> K;\n    \n    // Initialize board\n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    // Read stamps\n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(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 >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    // Precompute stamp effectiveness for each cell\n    // For each cell (i,j), find which stamps/positions affect it\n    // A stamp at position (p,q) affects cells (p..p+2, q..q+2)\n    vector<vector<vector<pair<int,int>>>> covering_stamps(N, vector<vector<pair<int,int>>>(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                for (int i = 0; i < 3; i++) {\n                    for (int j = 0; j < 3; j++) {\n                        covering_stamps[p+i][q+j].push_back({m, stamps[m][i][j] % MOD});\n                    }\n                }\n            }\n        }\n    }\n    \n    vector<tuple<int,int,int>> operations; // (m, p, q)\n    \n    // Track remaining budget for each cell's potential\n    // We'll use a priority queue approach based on need\n    auto get_cell_value = [&](int i, int j) {\n        return board[i][j] % MOD;\n    };\n    \n    auto get_cell_potential = [&](int i, int j) {\n        long long cur = get_cell_value(i, j);\n        return (MOD - 1 - cur + MOD) % MOD; // How much more we need\n    };\n    \n    // For each operation, we'll do beam search over a few best options\n    for (int op = 0; op < K; op++) {\n        // Find most needy cell\n        double max_need = -1;\n        int target_i = -1, target_j = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                double need = get_cell_potential(i, j);\n                if (need > max_need) {\n                    max_need = need;\n                    target_i = i;\n                    target_j = j;\n                }\n            }\n        }\n        \n        // Now find best stamp/position that helps this cell and nearby cells\n        double best_score = -1e9;\n        int best_m = -1, best_p = -1, best_q = -1;\n        \n        // Search all stamps and positions that can affect target cell\n        for (int m = 0; m < M; m++) {\n            for (int p = max(0, target_i - 2); p <= min(N - 3, target_i); p++) {\n                for (int q = max(0, target_j - 2); q <= min(N - 3, target_j); q++) {\n                    // Check if this placement actually affects the target cell\n                    if (p > target_i || p + 2 < target_i || q > target_j || q + 2 < target_j) continue;\n                    \n                    double score = 0;\n                    \n                    // Evaluate all 9 cells affected\n                    for (int di = 0; di < 3; di++) {\n                        for (int dj = 0; dj < 3; dj++) {\n                            int ci = p + di, cj = q + dj;\n                            long long cur_val = board[ci][cj];\n                            long long cur_rem = cur_val % MOD;\n                            long long add_val = stamps[m][di][dj] % MOD;\n                            long long new_rem = (cur_rem + add_val) % MOD;\n                            \n                            // Score: improvement in remainder, weighted by how bad the cell is\n                            long long current_potential = (MOD - 1 - cur_rem + MOD) % MOD;\n                            long long new_potential = (MOD - 1 - new_rem + MOD) % MOD;\n                            long long improvement = current_potential - new_potential;\n                            \n                            // Weight: cells with high potential (far from MOD-1) get more weight\n                            double weight = 1.0 + (double)current_potential / MOD * 2.0;\n                            \n                            // Extra bonus for the target cell\n                            if (ci == target_i && cj == target_j) {\n                                weight *= 3.0;\n                            }\n                            \n                            score += improvement * weight;\n                        }\n                    }\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation\n        if (best_m != -1) {\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n            operations.push_back({best_m, best_p, best_q});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Coord {\n    int r, c;\n    Coord(int r = 0, int c = 0) : r(r), c(c) {}\n    bool operator==(const Coord& o) const { return r == o.r && c == o.c; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Target positions for containers: (row, col) = (container/N, 4)\n    vector<int> targetRow(N*N), targetCol(N*N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int container = i*N + j;\n            targetRow[container] = i;\n            targetCol[container] = 4;  // dispatch gate\n        }\n    }\n    \n    // Grid state: -1 = empty, otherwise container number\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Crane state\n    vector<int> craneRow(N), craneCol(N);\n    vector<int> holding(N, -1);  // which container each crane holds, -1 = empty\n    for (int i = 0; i < N; i++) {\n        craneRow[i] = i;\n        craneCol[i] = 0;\n    }\n    \n    // Receiving state\n    vector<int> nextReceiving(N, 0);  // next container index to appear at each gate\n    \n    // Dispatch state\n    vector<int> nextDispatch(N, 0);  // next number to dispatch at each gate\n    vector<bool> dispatched(N*N, false);\n    \n    // Output strings\n    vector<string> ops(N);\n    \n    // Helper function to check if a cell is occupied by another crane\n    auto craneAt = [&](int r, int c, int exclude) -> bool {\n        for (int i = 0; i < N; i++) {\n            if (i != exclude && craneRow[i] == r && craneCol[i] == c) return true;\n        }\n        return false;\n    };\n    \n    // Check if a move is valid for given crane\n    auto canMove = [&](int crane, int nr, int nc) -> bool {\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n        if (craneAt(nr, nc, crane)) return false;\n        \n        // Small crane with container cannot move to occupied cell\n        if (holding[crane] != -1 && crane > 0 && grid[nr][nc] != -1) return false;\n        \n        return true;\n    };\n    \n    // Move one step towards target (simple Manhattan distance)\n    auto moveTowards = [&](int crane, int tr, int tc) -> char {\n        int r = craneRow[crane], c = craneCol[crane];\n        if (r == tr && c == tc) return '.';\n        \n        // Try horizontal first, then vertical\n        if (c < tc && canMove(crane, r, c+1)) return 'R';\n        if (c > tc && canMove(crane, r, c-1)) return 'L';\n        if (r < tr && canMove(crane, r+1, c)) return 'D';\n        if (r > tr && canMove(crane, r-1, c)) return 'U';\n        \n        // If blocked, try other directions\n        if (r < tr && canMove(crane, r+1, c)) return 'D';\n        if (r > tr && canMove(crane, r-1, c)) return 'U';\n        if (c < tc && canMove(crane, r, c+1)) return 'R';\n        if (c > tc && canMove(crane, r, c-1)) return 'L';\n        \n        return '.';\n    };\n    \n    // Main simulation loop\n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        // Step 1: Deliver new containers to receiving gates\n        for (int i = 0; i < N; i++) {\n            if (nextReceiving[i] < N && grid[i][0] == -1 && !craneAt(i, 0, -1)) {\n                grid[i][0] = A[i][nextReceiving[i]];\n                nextReceiving[i]++;\n            }\n        }\n        \n        // Step 3: Dispatch containers at gates (can be done before or after actions)\n        for (int i = 0; i < N; i++) {\n            if (grid[i][4] != -1) {\n                int container = grid[i][4];\n                if (container / N == i && container % N == nextDispatch[i]) {\n                    dispatched[container] = true;\n                    grid[i][4] = -1;\n                    nextDispatch[i]++;\n                }\n            }\n        }\n        \n        // Determine actions for each crane\n        for (int crane = 0; crane < N; crane++) {\n            int r = craneRow[crane], c = craneCol[crane];\n            char action = '.';\n            \n            if (crane == 0) {\n                // Large crane: shuttle containers to their target rows\n                if (holding[crane] == -1) {\n                    // Find a container to pick up (prefer those far from target)\n                    int bestContainer = -1, bestDist = -1;\n                    for (int i = 0; i < N; i++) {\n                        for (int j = 0; j < N; j++) {\n                            if (grid[i][j] != -1 && !(i == r && j == c)) {\n                                int container = grid[i][j];\n                                int target = targetRow[container];\n                                int dist = abs(i - target) + abs(j - targetCol[container]);\n                                if (dist > bestDist) {\n                                    bestDist = dist;\n                                    bestContainer = container;\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (bestContainer != -1) {\n                        // Move towards the best container or pick it up\n                        if (grid[r][c] != -1) {\n                            action = 'P';\n                        } else {\n                            action = moveTowards(crane, r, c);\n                            // Better: find the container and move towards it\n                            for (int i = 0; i < N && action == '.'; i++) {\n                                for (int j = 0; j < N && action == '.'; j++) {\n                                    if (grid[i][j] == bestContainer) {\n                                        action = moveTowards(crane, i, j);\n                                    }\n                                }\n                            }\n                        }\n                    } else {\n                        // Move around randomly\n                        if (canMove(crane, r, c+1)) action = 'R';\n                        else if (canMove(crane, r+1, c)) action = 'D';\n                        else if (canMove(crane, r-1, c)) action = 'U';\n                        else if (canMove(crane, r, c-1)) action = 'L';\n                    }\n                } else {\n                    // Holding a container, deliver to target row\n                    int container = holding[crane];\n                    int targetR = targetRow[container];\n                    \n                    if (r == targetR && c == 4) {\n                        // At dispatch gate\n                        if (grid[r][4] == -1 && container % N == nextDispatch[r]) {\n                            action = 'Q';\n                        } else {\n                            // Wait or move aside\n                            if (canMove(crane, r, c-1)) action = 'L';\n                        }\n                    } else {\n                        // Move towards dispatch gate of target row\n                        action = moveTowards(crane, targetR, 4);\n                    }\n                }\n            } else {\n                // Small crane: manage its row\n                if (holding[crane] == -1) {\n                    // Look for containers that need sorting in this row\n                    bool foundWork = false;\n                    for (int j = 0; j < N && !foundWork; j++) {\n                        if (grid[r][j] != -1) {\n                            int container = grid[r][j];\n                            if (container / N != r || container % N != nextDispatch[r]) {\n                                // This container needs moving\n                                foundWork = true;\n                                if (c == j) {\n                                    action = 'P';\n                                } else {\n                                    action = moveTowards(crane, r, j);\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (!foundWork) {\n                        // Move towards receiving gate to help\n                        if (c > 0 && canMove(crane, r, c-1)) action = 'L';\n                        else if (c < 3 && canMove(crane, r, c+1)) action = 'R';\n                        else if (c < 4 && canMove(crane, r, c+1)) action = 'R';\n                    }\n                } else {\n                    // Holding container\n                    int container = holding[crane];\n                    int targetC = 4; // dispatch gate\n                    \n                    if (container / N == r) {\n                        // Belongs to this row, move to dispatch\n                        if (c == 4) {\n                            if (grid[r][4] == -1 && container % N == nextDispatch[r]) {\n                                action = 'Q';\n                            } else {\n                                // Move aside\n                                if (canMove(crane, r, c-1)) action = 'L';\n                            }\n                        } else {\n                            action = moveTowards(crane, r, 4);\n                        }\n                    } else {\n                        // Belongs to another row, drop it for large crane\n                        // Find empty cell in this row\n                        if (grid[r][c] == -1 && holding[crane] != -1) {\n                            // Drop it here if there's empty space\n                            for (int j = 0; j < 4; j++) {\n                                if (grid[r][j] == -1) {\n                                    if (canMove(crane, r, j)) {\n                                        action = moveTowards(crane, r, j);\n                                        if (c == j) action = 'Q';\n                                    }\n                                    break;\n                                }\n                            }\n                        }\n                        if (action == '.') {\n                            action = moveTowards(crane, r, 0); // Move to receiving side\n                        }\n                    }\n                }\n            }\n            \n            // Execute action\n            if (action == 'P' && grid[r][c] != -1 && holding[crane] == -1) {\n                holding[crane] = grid[r][c];\n                grid[r][c] = -1;\n            } else if (action == 'Q' && grid[r][c] == -1 && holding[crane] != -1) {\n                grid[r][c] = holding[crane];\n                holding[crane] = -1;\n            } else if (action == 'U' && canMove(crane, r-1, c)) {\n                craneRow[crane] = r-1;\n            } else if (action == 'D' && canMove(crane, r+1, c)) {\n                craneRow[crane] = r+1;\n            } else if (action == 'L' && canMove(crane, r, c-1)) {\n                craneCol[crane] = c-1;\n            } else if (action == 'R' && canMove(crane, r, c+1)) {\n                craneCol[crane] = c+1;\n            }\n            \n            ops[crane] += action;\n        }\n        \n        // Check completion\n        bool allDone = true;\n        for (int i = 0; i < N*N && allDone; i++) {\n            if (!dispatched[i]) allDone = false;\n        }\n        if (allDone) break;\n    }\n    \n    // Normalize output strings\n    int maxLen = 0;\n    for (int i = 0; i < N; i++) {\n        maxLen = max(maxLen, (int)ops[i].length());\n    }\n    for (int i = 0; i < N; i++) {\n        while ((int)ops[i].length() < maxLen) {\n            ops[i] += '.';\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << ops[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\nconst int MAX_TURNS = 100000;\nconst int DX[] = {-1, 1, 0, 0};\nconst int DY[] = {0, 0, -1, 1};\nconst string DIR = \"UDLR\";\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int x = 0, y = 0;\n    int load = 0;\n    \n    // BFS for shortest path\n    auto get_path = [&](int sx, int sy, int tx, int ty) -> vector<pair<int,int>> {\n        if (sx == tx && sy == ty) return {};\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n        \n        dist[sx][sy] = 0;\n        q.push({sx, sy});\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            if (cx == tx && cy == ty) break;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cx + DX[d], ny = cy + DY[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] > dist[cx][cy] + 1) {\n                    dist[nx][ny] = dist[cx][cy] + 1;\n                    prev[nx][ny] = {cx, cy};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        if (dist[tx][ty] == INF) return {};\n        \n        vector<pair<int,int>> path;\n        int cx = tx, cy = ty;\n        while (cx != sx || cy != sy) {\n            path.push_back({cx, cy});\n            auto [px, py] = prev[cx][cy];\n            cx = px; cy = py;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto move_to = [&](int tx, int ty) {\n        if (x == tx && y == ty) return;\n        auto path = get_path(x, y, tx, ty);\n        for (auto [nx, ny] : path) {\n            for (int d = 0; d < 4; d++) {\n                if (x + DX[d] == nx && y + DY[d] == ny) {\n                    ops.push_back(DIR.substr(d, 1));\n                    break;\n                }\n            }\n            x = nx; y = ny;\n        }\n    };\n    \n    // Phase 1: Calculate \"gravity\" center of soil\n    // The optimal hub is roughly the weighted center of mass\n    long long total_positive = 0, sum_x = 0, sum_y = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (h[i][j] > 0) {\n                total_positive += h[i][j];\n                sum_x += (long long)h[i][j] * i;\n                sum_y += (long long)h[i][j] * j;\n            }\n        }\n    }\n    \n    // Hub position (center of mass of positive soil)\n    int hub_x = sum_x / max(total_positive, 1LL);\n    int hub_y = sum_y / max(total_positive, 1LL);\n    \n    // Actually, let's just scan the grid in a snake pattern and move soil to nearest sink\n    // This is simpler and often works better\n    \n    // Collect all soil to central storage (hub)\n    // Then distribute from hub\n    \n    // Phase 1: Scan grid and collect all positive soil\n    for (int i = 0; i < N && (int)ops.size() < MAX_TURNS - 1000; i++) {\n        for (int j = 0; j < N && (int)ops.size() < MAX_TURNS - 1000; j++) {\n            if (h[i][j] > 0) {\n                // Move to this cell\n                move_to(i, j);\n                \n                // Load everything\n                int amount = h[i][j];\n                ops.push_back(\"+\" + to_string(amount));\n                h[i][j] = 0;\n                load += amount;\n                \n                // Immediately find a sink to dump\n                int best_sink_x = -1, best_sink_y = -1;\n                int best_dist = INF;\n                \n                for (int ii = 0; ii < N; ii++) {\n                    for (int jj = 0; jj < N; jj++) {\n                        if (h[ii][jj] < 0) {\n                            int dist = abs(i - ii) + abs(j - jj);\n                            if (dist < best_dist) {\n                                best_dist = dist;\n                                best_sink_x = ii;\n                                best_sink_y = jj;\n                            }\n                        }\n                    }\n                }\n                \n                if (best_sink_x == -1) break; // No more sinks\n                \n                // Move to sink\n                move_to(best_sink_x, best_sink_y);\n                \n                // Unload as much as needed\n                int needed = -h[best_sink_x][best_sink_y];\n                int to_dump = min(load, needed);\n                ops.push_back(\"-\" + to_string(to_dump));\n                h[best_sink_x][best_sink_y] += to_dump;\n                load -= to_dump;\n                \n                // If we still have load, find another sink\n                while (load > 0 && (int)ops.size() < MAX_TURNS - 100) {\n                    // Find nearest sink with remaining need\n                    int best_dist = INF;\n                    int best_sx = -1, best_sy = -1;\n                    \n                    for (int ii = 0; ii < N; ii++) {\n                        for (int jj = 0; jj < N; jj++) {\n                            if (h[ii][jj] < 0) {\n                                int dist = abs(x - ii) + abs(y - jj);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best_sx = ii;\n                                    best_sy = jj;\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (best_sx == -1) break;\n                    \n                    move_to(best_sx, best_sy);\n                    needed = -h[best_sx][best_sy];\n                    to_dump = min(load, needed);\n                    ops.push_back(\"-\" + to_string(to_dump));\n                    h[best_sx][best_sy] += to_dump;\n                    load -= to_dump;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Handle any remaining work\n    while ((int)ops.size() < MAX_TURNS - 100) {\n        // Find any pair of source and sink\n        bool found = false;\n        for (int i = 0; i < N && !found; i++) {\n            for (int j = 0; j < N && !found; j++) {\n                if (h[i][j] > 0) {\n                    // Find nearest sink\n                    for (int ii = 0; ii < N && !found; ii++) {\n                        for (int jj = 0; jj < N && !found; jj++) {\n                            if (h[ii][jj] < 0) {\n                                int amount = min(h[i][j], -h[ii][jj]);\n                                amount = min(amount, 500);\n                                \n                                if (amount > 0) {\n                                    move_to(i, j);\n                                    ops.push_back(\"+\" + to_string(amount));\n                                    h[i][j] -= amount;\n                                    load = amount;\n                                    \n                                    move_to(ii, jj);\n                                    ops.push_back(\"-\" + to_string(amount));\n                                    h[ii][jj] += amount;\n                                    load = 0;\n                                    found = true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        if (!found) break;\n    }\n    \n    // Output\n    for (const string& op : ops) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 6;\n    const int M = 15;\n    const int SEED_COUNT = 2 * N * (N - 1); // 60\n    const int T = 10;\n    \n    vector<vector<int>> seeds(SEED_COUNT, vector<int>(M));\n    vector<int> totals(SEED_COUNT);\n    \n    for (int i = 0; i < SEED_COUNT; i++) {\n        totals[i] = 0;\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n            totals[i] += seeds[i][j];\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Find current best trait values\n        vector<int> best_trait(M, 0);\n        for (int i = 0; i < SEED_COUNT; i++) {\n            for (int j = 0; j < M; j++) {\n                best_trait[j] = max(best_trait[j], seeds[i][j]);\n            }\n        }\n        \n        // Score seeds: total value + trait excellence + complementarity\n        vector<pair<int, int>> scores; // (score, index)\n        for (int i = 0; i < SEED_COUNT; i++) {\n            int score = totals[i] * 3;  // Base: total value\n            \n            // Bonus for having the absolute best value in any trait\n            int best_count = 0;\n            for (int j = 0; j < M; j++) {\n                if (seeds[i][j] == best_trait[j]) {\n                    best_count++;\n                }\n            }\n            score += best_count * 150;\n            \n            // Bonus for very high individual traits (>= 90)\n            for (int j = 0; j < M; j++) {\n                if (seeds[i][j] >= 90) {\n                    score += seeds[i][j] - 80;  // Linear bonus from 10 to 20\n                }\n            }\n            \n            scores.push_back({score, i});\n        }\n        \n        sort(scores.rbegin(), scores.rend());\n        \n        // Create placement using spiral pattern from center\n        vector<vector<int>> grid(N, vector<int>(N));\n        vector<bool> used(SEED_COUNT, false);\n        \n        // Spiral pattern: start at center, spiral outward\n        vector<pair<int,int>> spiral = {\n            {2,2}, {2,3}, {3,3}, {3,2},  // Center 2x2\n            {1,2}, {1,3}, {2,4}, {3,4}, {4,3}, {4,2}, {3,1}, {2,1},  // First ring\n            {1,1}, {1,4}, {4,4}, {4,1},  // Ring corners\n            {0,2}, {0,3}, {2,5}, {3,5}, {5,3}, {5,2}, {2,0}, {3,0},  // Second ring\n            {0,1}, {0,4}, {1,5}, {4,5}, {5,4}, {5,1}, {4,0}, {1,0},  // Third ring  \n            {0,0}, {0,5}, {5,5}, {5,0}   // Corners\n        };\n        \n        int idx = 0;\n        for (auto pos : spiral) {\n            grid[pos.first][pos.second] = scores[idx].second;\n            idx++;\n        }\n        \n        // Output 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        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < SEED_COUNT; i++) {\n            totals[i] = 0;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n                totals[i] += seeds[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int x, y;\n    Position(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass TakoyakiSolver {\nprivate:\n    int N, M, V;\n    vector<string> initial_grid, target_grid;\n    vector<Position> initial_positions, target_positions;\n    vector<vector<bool>> occupied;\n    \n    // Simple arm: root + 1 fingertip\n    int edge_length;\n    Position root_pos;\n    int direction; // 0: right, 1: down, 2: left, 3: up\n    \n    // State\n    bool holding;\n    int holding_idx;\n    vector<int> target_for_initial;\n    vector<int> pickup_order; // Optimal order to pick up takoyaki\n    \n    // Output\n    vector<string> commands;\n    \npublic:\n    TakoyakiSolver() {\n        readInput();\n        matchPositions();\n        planOptimalOrder();\n        solve();\n    }\n    \n    void readInput() {\n        cin >> N >> M >> V;\n        \n        initial_grid.resize(N);\n        target_grid.resize(N);\n        occupied.assign(N, vector<bool>(N, false));\n        \n        for (int i = 0; i < N; i++) {\n            cin >> initial_grid[i];\n            for (int j = 0; j < N; j++) {\n                if (initial_grid[i][j] == '1') {\n                    initial_positions.push_back(Position(i, j));\n                    occupied[i][j] = true;\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> target_grid[i];\n            for (int j = 0; j < N; j++) {\n                if (target_grid[i][j] == '1') {\n                    target_positions.push_back(Position(i, j));\n                }\n            }\n        }\n        \n        holding = false;\n        holding_idx = -1;\n    }\n    \n    void matchPositions() {\n        target_for_initial.assign(M, -1);\n        vector<bool> target_used(M, false);\n        \n        // Hungarian-like matching with better distance metric\n        for (int i = 0; i < M; i++) {\n            int best_j = -1;\n            int best_dist = 1e9;\n            \n            for (int j = 0; j < M; j++) {\n                if (!target_used[j]) {\n                    // Use Manhattan distance\n                    int dist = abs(initial_positions[i].x - target_positions[j].x) +\n                              abs(initial_positions[i].y - target_positions[j].y);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_j = j;\n                    }\n                }\n            }\n            \n            target_for_initial[i] = best_j;\n            target_used[best_j] = true;\n        }\n    }\n    \n    void planOptimalOrder() {\n        // Plan order to pick up takoyaki to minimize total travel\n        pickup_order.clear();\n        vector<bool> picked(M, false);\n        \n        // Start from root position (0,0)\n        Position current = Position(0, 0);\n        \n        for (int step = 0; step < M; step++) {\n            int best_idx = -1;\n            int best_dist = 1e9;\n            \n            for (int i = 0; i < M; i++) {\n                if (!picked[i]) {\n                    // Distance from current position to this takoyaki\n                    int dist = abs(initial_positions[i].x - current.x) +\n                              abs(initial_positions[i].y - current.y);\n                    \n                    // Add bonus for being near its target too\n                    Position target = target_positions[target_for_initial[i]];\n                    dist += abs(target.x - initial_positions[i].x) +\n                            abs(target.y - initial_positions[i].y);\n                    \n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx >= 0) {\n                pickup_order.push_back(best_idx);\n                picked[best_idx] = true;\n                current = target_positions[target_for_initial[best_idx]];\n            }\n        }\n    }\n    \n    Position getFingertipPosition() {\n        return Position(\n            root_pos.x + dx[direction] * edge_length,\n            root_pos.y + dy[direction] * edge_length\n        );\n    }\n    \n    char moveRootTowards(const Position& target) {\n        char move = '.';\n        int dx_target = target.x - root_pos.x;\n        int dy_target = target.y - root_pos.y;\n        \n        // Always move in the direction with larger difference\n        if (abs(dx_target) >= abs(dy_target)) {\n            if (dx_target > 0 && root_pos.x < N - 1) {\n                move = 'D';\n                root_pos.x++;\n            } else if (dx_target < 0 && root_pos.x > 0) {\n                move = 'U';\n                root_pos.x--;\n            } else if (dy_target > 0 && root_pos.y < N - 1) {\n                move = 'R';\n                root_pos.y++;\n            } else if (dy_target < 0 && root_pos.y > 0) {\n                move = 'L';\n                root_pos.y--;\n            }\n        } else {\n            if (dy_target > 0 && root_pos.y < N - 1) {\n                move = 'R';\n                root_pos.y++;\n            } else if (dy_target < 0 && root_pos.y > 0) {\n                move = 'L';\n                root_pos.y--;\n            } else if (dx_target > 0 && root_pos.x < N - 1) {\n                move = 'D';\n                root_pos.x++;\n            } else if (dx_target < 0 && root_pos.x > 0) {\n                move = 'U';\n                root_pos.x--;\n            }\n        }\n        \n        return move;\n    }\n    \n    string generateCommand() {\n        string cmd(4, '.'); // For 2 vertices\n        \n        // Determine where to go based on state\n        Position target;\n        \n        if (!holding) {\n            // Find next takoyaki to pick up\n            int next_idx = -1;\n            int min_dist = 1e9;\n            \n            for (int i = 0; i < M; i++) {\n                if (occupied[initial_positions[i].x][initial_positions[i].y]) {\n                    int dist = abs(initial_positions[i].x - root_pos.x) +\n                              abs(initial_positions[i].y - root_pos.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        next_idx = i;\n                    }\n                }\n            }\n            \n            if (next_idx >= 0) {\n                target = initial_positions[next_idx];\n                \n                // Move root towards target\n                cmd[0] = moveRootTowards(target);\n                \n                // Rotate fingertip towards target\n                Position fingertip = getFingertipPosition();\n                int dx_target = target.x - root_pos.x;\n                int dy_target = target.y - root_pos.y;\n                int target_dir = (abs(dx_target) >= abs(dy_target)) ? \n                                 ((dx_target > 0) ? 1 : 3) : \n                                 ((dy_target > 0) ? 0 : 2);\n                \n                if (target_dir != direction) {\n                    int diff = (target_dir - direction + 4) % 4;\n                    if (diff <= 2) {\n                        cmd[1] = 'R';\n                        direction = (direction + 1) % 4;\n                    } else {\n                        cmd[1] = 'L';\n                        direction = (direction + 3) % 4;\n                    }\n                }\n                \n                // Try to grab\n                fingertip = getFingertipPosition();\n                if (fingertip.x >= 0 && fingertip.x < N && \n                    fingertip.y >= 0 && fingertip.y < N &&\n                    fingertip == target && occupied[target.x][target.y]) {\n                    cmd[3] = 'P';\n                    holding = true;\n                    holding_idx = next_idx;\n                    occupied[target.x][target.y] = false;\n                }\n            }\n        } else {\n            // Deliver the held takoyaki\n            target = target_positions[target_for_initial[holding_idx]];\n            \n            if (!occupied[target.x][target.y]) {\n                cmd[0] = moveRootTowards(target);\n                \n                Position fingertip = getFingertipPosition();\n                int dx_target = target.x - root_pos.x;\n                int dy_target = target.y - root_pos.y;\n                int target_dir = (abs(dx_target) >= abs(dy_target)) ? \n                                 ((dx_target > 0) ? 1 : 3) : \n                                 ((dy_target > 0) ? 0 : 2);\n                \n                if (target_dir != direction) {\n                    int diff = (target_dir - direction + 4) % 4;\n                    if (diff <= 2) {\n                        cmd[1] = 'R';\n                        direction = (direction + 1) % 4;\n                    } else {\n                        cmd[1] = 'L';\n                        direction = (direction + 3) % 4;\n                    }\n                }\n                \n                fingertip = getFingertipPosition();\n                if (fingertip.x >= 0 && fingertip.x < N && \n                    fingertip.y >= 0 && fingertip.y < N &&\n                    fingertip == target) {\n                    cmd[3] = 'P';\n                    holding = false;\n                    occupied[target.x][target.y] = true;\n                    holding_idx = -1;\n                }\n            }\n        }\n        \n        return cmd;\n    }\n    \n    void solve() {\n        // Design arm: edge length = min(N-1, N/2)\n        edge_length = min(N - 1, N / 2);\n        if (edge_length < 1) edge_length = 1;\n        \n        cout << 2 << endl;\n        cout << 0 << \" \" << edge_length << endl;\n        \n        // Initial position\n        root_pos = Position(0, 0);\n        direction = 0;\n        cout << root_pos.x << \" \" << root_pos.y << endl;\n        \n        // Generate commands\n        commands.clear();\n        \n        // Pre-calculate adjacent targets for faster path\n        vector<vector<int>> adj_initial(M);\n        for (int i = 0; i < M; i++) {\n            for (int j = i + 1; j < M; j++) {\n                int dist = abs(initial_positions[i].x - initial_positions[j].x) +\n                          abs(initial_positions[i].y - initial_positions[j].y);\n                if (dist <= 3) { // Close enough to be \"adjacent\"\n                    adj_initial[i].push_back(j);\n                    adj_initial[j].push_back(i);\n                }\n            }\n        }\n        \n        for (int turn = 0; turn < 100000; turn++) {\n            string cmd = generateCommand();\n            commands.push_back(cmd);\n            \n            // Check all delivered\n            bool all_delivered = true;\n            for (int i = 0; i < M; i++) {\n                Position target = target_positions[target_for_initial[i]];\n                if (!occupied[target.x][target.y]) {\n                    all_delivered = false;\n                    break;\n                }\n            }\n            \n            if (all_delivered && !holding) {\n                break;\n            }\n            \n            // Safety\n            root_pos.x = max(0, min(N - 1, root_pos.x));\n            root_pos.y = max(0, min(N - 1, root_pos.y));\n        }\n        \n        // Output\n        for (const string& cmd : commands) {\n            cout << cmd << endl;\n        }\n    }\n    \n    static const int dx[4];\n    static const int dy[4];\n};\n\nconst int TakoyakiSolver::dx[4] = {0, 1, 0, -1};\nconst int TakoyakiSolver::dy[4] = {1, 0, -1, 0};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TakoyakiSolver solver;\n    \n    return 0;\n}","ahc039":"#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 = 5000;\n    vector<pair<int,int>> mackerel(N), sardine(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> mackerel[i].first >> mackerel[i].second;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sardine[i].first >> sardine[i].second;\n    }\n    \n    int best_score = -1e9;\n    int best_x1 = 0, best_y1 = 0, best_x2 = 0, best_y2 = 0;\n    \n    // Use multiple cell sizes to cover different cluster scales\n    // Fish clusters have std dev 1000-5000, so cell size 200-800 should work\n    vector<pair<int,int>> configs = {\n        {200, 0}, {200, 50}, {200, 100}, {200, 150},\n        {300, 0}, {300, 75}, {300, 150}, {300, 225},\n        {400, 0}, {400, 100}, {400, 200}, {400, 300},\n        {500, 0}, {500, 125}, {500, 250}, {500, 375},\n        {600, 0}, {600, 150}, {600, 300}, {600, 450},\n        {800, 0}, {800, 200}, {800, 400}, {800, 600}\n    };\n    \n    for (auto& [CELL, OFFSET] : configs) {\n        int CELLS = 100000 / CELL + 2;\n        \n        // Build grid\n        vector<vector<short>> grid(CELLS, vector<short>(CELLS, 0));\n        for (auto& p : mackerel) {\n            int cx = (p.first + OFFSET) / CELL;\n            int cy = (p.second + OFFSET) / CELL;\n            if (cx >= 0 && cx < CELLS && cy >= 0 && cy < CELLS)\n                grid[cx][cy]++;\n        }\n        for (auto& p : sardine) {\n            int cx = (p.first + OFFSET) / CELL;\n            int cy = (p.second + OFFSET) / CELL;\n            if (cx >= 0 && cx < CELLS && cy >= 0 && cy < CELLS)\n                grid[cx][cy]--;\n        }\n        \n        // Kadane 2D with early termination for negative regions\n        for (int top = 0; top < CELLS; top++) {\n            vector<int> temp(CELLS, 0);\n            for (int bottom = top; bottom < CELLS; bottom++) {\n                // Quick check if continuing is worth it\n                bool all_negative = true;\n                for (int j = 0; j < CELLS; j++) {\n                    temp[j] += grid[bottom][j];\n                    if (temp[j] > 0) all_negative = false;\n                }\n                if (all_negative) continue;\n                \n                int cur = 0, left = 0;\n                for (int j = 0; j < CELLS; j++) {\n                    cur += temp[j];\n                    if (cur > best_score) {\n                        best_score = cur;\n                        const int MARGIN = 15;\n                        best_x1 = max(0, top * CELL - OFFSET - MARGIN);\n                        best_y1 = max(0, left * CELL - OFFSET - MARGIN);\n                        best_x2 = min(100000, (bottom + 1) * CELL - OFFSET + MARGIN);\n                        best_y2 = min(100000, (j + 1) * CELL - OFFSET + MARGIN);\n                    }\n                    if (cur < 0) {\n                        cur = 0;\n                        left = j + 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Fallback: direct search around each mackerel\n    if (best_score <= 5) {\n        for (int i = 0; i < N; i++) {\n            auto [mx, my] = mackerel[i];\n            for (int s : {200, 500, 1000, 2000, 5000}) {\n                int x1 = max(0, mx - s);\n                int y1 = max(0, my - s);\n                int x2 = min(100000, mx + s);\n                int y2 = min(100000, my + s);\n                \n                if (x1 >= x2 || y1 >= y2) continue;\n                \n                int score = 0;\n                for (auto& p : mackerel)\n                    if (p.first >= x1 && p.first <= x2 && p.second >= y1 && p.second <= y2)\n                        score++;\n                for (auto& p : sardine)\n                    if (p.first >= x1 && p.first <= x2 && p.second >= y1 && p.second <= y2)\n                        score--;\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_x1 = x1; best_y1 = y1;\n                    best_x2 = x2; best_y2 = y2;\n                }\n            }\n            if (best_score > 5) break;\n        }\n    }\n    \n    if (best_score <= 0) {\n        cout << \"4\\n0 0\\n1 0\\n1 1\\n0 1\\n\";\n        return 0;\n    }\n    \n    if (best_x1 == best_x2) { if (best_x2 < 100000) best_x2++; else best_x1--; }\n    if (best_y1 == best_y2) { if (best_y2 < 100000) best_y2++; else best_y1--; }\n    best_x1 = max(0, best_x1); best_y1 = max(0, best_y1);\n    best_x2 = min(100000, best_x2); best_y2 = min(100000, best_y2);\n    \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 <bits/stdc++.h>\n#include <random>\n#include <chrono>\n#include <set>\nusing namespace std;\n\nstruct Rectangle {\n    long long w, h;\n};\n\nint N, T, sigma;\nvector<Rectangle> rects;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n};\n\nstruct PlacedRect {\n    long long x1, y1, x2, y2;\n    int idx;\n};\n\n// Evaluate placement and return score\nlong long evaluate_placement(const vector<Placement>& placements,\n                            long long& width, long long& height) {\n    vector<PlacedRect> placed;\n    vector<bool> used(N, false);\n    \n    for (const auto& pl : placements) {\n        int idx = pl.p;\n        if (idx < 0 || idx >= N || used[idx]) continue;\n        used[idx] = true;\n        \n        long long rw = rects[idx].w;\n        long long rh = rects[idx].h;\n        if (pl.r) swap(rw, rh);\n        \n        if (pl.d == 'U') {\n            long long left_x = 0;\n            if (pl.b >= 0) {\n                for (const auto& pr : placed) {\n                    if (pr.idx == pl.b) {\n                        left_x = pr.x2;\n                        break;\n                    }\n                }\n            }\n            \n            long long bottom_y = 0;\n            for (const auto& pr : placed) {\n                if (left_x < pr.x2 && left_x + rw > pr.x1) {\n                    bottom_y = max(bottom_y, pr.y2);\n                }\n            }\n            \n            placed.push_back({left_x, bottom_y, left_x + rw, bottom_y + rh, idx});\n        } else {\n            long long top_y = 0;\n            if (pl.b >= 0) {\n                for (const auto& pr : placed) {\n                    if (pr.idx == pl.b) {\n                        top_y = pr.y2;\n                        break;\n                    }\n                }\n            }\n            \n            long long right_x = 0;\n            for (const auto& pr : placed) {\n                if (top_y < pr.y2 && top_y + rh > pr.y1) {\n                    right_x = max(right_x, pr.x2);\n                }\n            }\n            \n            placed.push_back({right_x, top_y, right_x + rw, top_y + rh, idx});\n        }\n    }\n    \n    width = 0;\n    height = 0;\n    for (const auto& pr : placed) {\n        width = max(width, pr.x2);\n        height = max(height, pr.y2);\n    }\n    \n    long long unplaced_sum = 0;\n    for (int i = 0; i < N; i++) {\n        if (!used[i]) {\n            unplaced_sum += rects[i].w + rects[i].h;\n        }\n    }\n    \n    return width + height + unplaced_sum;\n}\n\n// Generate packing using bottom-left strategy with best position\nvector<Placement> generate_best_fit_packing(const vector<bool>& use_rect,\n                                           bool prefer_wide, bool prefer_tall) {\n    vector<Placement> result;\n    vector<PlacedRect> placed;\n    \n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        \n        long long best_score = 1LL << 60;\n        int best_rot = 0;\n        long long best_x = 0, best_y = 0;\n        char best_d = 'U';\n        int best_b = -1;\n        \n        // Try both orientations\n        for (int rot = 0; rot < 2; rot++) {\n            long long rw = rects[i].w;\n            long long rh = rects[i].h;\n            if (rot) swap(rw, rh);\n            \n            // Try placing to the right of each existing rectangle\n            for (int b = -1; b < i; b++) {\n                if (b >= 0 && !use_rect[b]) continue;\n                \n                long long left_x = 0;\n                if (b >= 0) {\n                    for (const auto& pr : placed) {\n                        if (pr.idx == b) {\n                            left_x = pr.x2;\n                            break;\n                        }\n                    }\n                }\n                \n                long long bottom_y = 0;\n                for (const auto& pr : placed) {\n                    if (left_x < pr.x2 && left_x + rw > pr.x1) {\n                        bottom_y = max(bottom_y, pr.y2);\n                    }\n                }\n                \n                long long new_width = max(left_x + rw, \n                    placed.empty() ? 0LL : placed.back().x2);\n                long long new_height = max(bottom_y + rh, \n                    placed.empty() ? 0LL : placed.back().y2);\n                \n                long long score = new_width + new_height;\n                \n                // Preference biasing\n                if (prefer_wide) score -= new_height * 2;\n                if (prefer_tall) score -= new_width * 2;\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_rot = rot;\n                    best_x = left_x;\n                    best_y = bottom_y;\n                    best_d = 'U';\n                    best_b = b;\n                }\n            }\n            \n            // Try placing below each existing rectangle (using L)\n            for (int b = -1; b < i; b++) {\n                if (b >= 0 && !use_rect[b]) continue;\n                \n                long long top_y = 0;\n                if (b >= 0) {\n                    for (const auto& pr : placed) {\n                        if (pr.idx == b) {\n                            top_y = pr.y2;\n                            break;\n                        }\n                    }\n                }\n                \n                long long right_x = 0;\n                for (const auto& pr : placed) {\n                    if (top_y < pr.y2 && top_y + rh > pr.y1) {\n                        right_x = max(right_x, pr.x2);\n                    }\n                }\n                \n                long long new_width = max(right_x + rw, \n                    placed.empty() ? 0LL : placed.back().x2);\n                long long new_height = max(top_y + rh, \n                    placed.empty() ? 0LL : placed.back().y2);\n                \n                long long score = new_width + new_height;\n                \n                if (prefer_wide) score -= new_height * 2;\n                if (prefer_tall) score -= new_width * 2;\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_rot = rot;\n                    best_x = right_x;\n                    best_y = top_y;\n                    best_d = 'L';\n                    best_b = b;\n                }\n            }\n        }\n        \n        long long rw = rects[i].w;\n        long long rh = rects[i].h;\n        if (best_rot) swap(rw, rh);\n        \n        result.push_back({i, best_rot, best_d, best_b});\n        \n        // Update placed rectangles for future evaluations\n        placed.push_back({best_x, best_y, best_x + rw, best_y + rh, i});\n    }\n    \n    return result;\n}\n\n// Generate simple row packing (original working approach)\nvector<Placement> generate_row_packing(const vector<bool>& use_rect,\n                                      const vector<bool>& rotate_rect) {\n    vector<Placement> result;\n    \n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        \n        if (result.empty()) {\n            result.push_back({i, rotate_rect[i], 'U', -1});\n        } else {\n            result.push_back({i, rotate_rect[i], 'U', result.back().p});\n        }\n    }\n    \n    return result;\n}\n\n// Generate two-row packing\nvector<Placement> generate_two_row_packing(const vector<bool>& use_rect,\n                                          const vector<bool>& rotate_rect) {\n    vector<Placement> result;\n    int count_used = 0;\n    for (int i = 0; i < N; i++) if (use_rect[i]) count_used++;\n    int first_row_count = count_used / 2;\n    int placed_in_first = 0;\n    int last_first_row = -1;\n    \n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        \n        if (placed_in_first < first_row_count) {\n            if (result.empty()) {\n                result.push_back({i, rotate_rect[i], 'U', -1});\n            } else {\n                result.push_back({i, rotate_rect[i], 'U', result.back().p});\n            }\n            last_first_row = i;\n            placed_in_first++;\n        } else {\n            if (last_first_row >= 0 && last_first_row < i) {\n                result.push_back({i, rotate_rect[i], 'L', last_first_row});\n            } else {\n                result.push_back({i, rotate_rect[i], 'U', result.back().p});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Try all strategies and pick the best\nvector<Placement> find_best_packing() {\n    long long best_score = 1LL << 60;\n    vector<Placement> best_packing;\n    \n    // Strategy 1: Simple row, no rotation\n    {\n        vector<bool> use(N, true);\n        vector<bool> rot(N, false);\n        auto packing = generate_row_packing(use, rot);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 2: Simple row, smart rotation (make wider)\n    {\n        vector<bool> use(N, true);\n        vector<bool> rot(N, false);\n        for (int i = 0; i < N; i++) {\n            if (rects[i].w < rects[i].h) rot[i] = true;\n        }\n        auto packing = generate_row_packing(use, rot);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 3: Simple row, smart rotation (make taller)\n    {\n        vector<bool> use(N, true);\n        vector<bool> rot(N, false);\n        for (int i = 0; i < N; i++) {\n            if (rects[i].h < rects[i].w) rot[i] = true;\n        }\n        auto packing = generate_row_packing(use, rot);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 4: Two rows\n    {\n        vector<bool> use(N, true);\n        vector<bool> rot(N, false);\n        auto packing = generate_two_row_packing(use, rot);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 5: Best-fit packing (tries to balance width and height)\n    {\n        vector<bool> use(N, true);\n        auto packing = generate_best_fit_packing(use, false, false);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 6: Best-fit with width preference\n    {\n        vector<bool> use(N, true);\n        auto packing = generate_best_fit_packing(use, true, false);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 7: Best-fit with height preference\n    {\n        vector<bool> use(N, true);\n        auto packing = generate_best_fit_packing(use, false, true);\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n    }\n    \n    // Strategy 8-11: Try subsets with best-fit\n    for (int skip = 2; skip <= 3; skip++) {\n        for (int start = 0; start < skip; start++) {\n            vector<bool> use(N, false);\n            for (int i = start; i < N; i += skip) {\n                use[i] = true;\n            }\n            \n            auto packing = generate_best_fit_packing(use, false, false);\n            long long W, H;\n            long long score = evaluate_placement(packing, W, H);\n            if (score < best_score) {\n                best_score = score;\n                best_packing = packing;\n            }\n        }\n    }\n    \n    // Strategy 12-14: Skip large/small rectangles\n    {\n        vector<pair<long long, int>> areas;\n        for (int i = 0; i < N; i++) {\n            areas.push_back({rects[i].w * rects[i].h, i});\n        }\n        sort(areas.begin(), areas.end());\n        \n        // Try using only small rectangles\n        for (int fraction = 2; fraction <= 4; fraction++) {\n            vector<bool> use(N, false);\n            for (int i = 0; i < N / fraction; i++) {\n                use[areas[i].second] = true;\n            }\n            \n            auto packing = generate_best_fit_packing(use, false, false);\n            long long W, H;\n            long long score = evaluate_placement(packing, W, H);\n            if (score < best_score) {\n                best_score = score;\n                best_packing = packing;\n            }\n        }\n    }\n    \n    return best_packing;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    rects.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n    }\n    \n    vector<Placement> best_packing = find_best_packing();\n    \n    for (int turn = 0; turn < T; turn++) {\n        cout << (int)best_packing.size() << endl;\n        for (const auto& pl : best_packing) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << endl;\n        }\n        cout.flush();\n        \n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\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    // Pre\u2011sort adjacency by descending beauty for BFS\n    for (int i = 0; i < N; ++i) {\n        sort(adj[i].begin(), adj[i].end(), [&](int a, int b) {\n            return A[a] > A[b];\n        });\n    }\n    \n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    vector<bool> in_tree(N, false);\n    \n    // Determine root candidates: lowest beauty vertices\n    vector<int> order_asc(N);\n    iota(order_asc.begin(), order_asc.end(), 0);\n    sort(order_asc.begin(), order_asc.end(), [&](int i, int j) {\n        return A[i] < A[j];\n    });\n    // Take about 20% of vertices as potential roots (200)\n    int num_roots = min(N, 200);\n    for (int idx = 0; idx < num_roots; ++idx) {\n        int v = order_asc[idx];\n        if (in_tree[v]) continue;\n        // BFS from v\n        queue<int> q;\n        parent[v] = -1;\n        depth[v] = 0;\n        in_tree[v] = true;\n        q.push(v);\n        while (!q.empty()) {\n            int cur = q.front(); q.pop();\n            if (depth[cur] == H) continue;\n            for (int u : adj[cur]) {\n                if (!in_tree[u]) {\n                    parent[u] = cur;\n                    depth[u] = depth[cur] + 1;\n                    in_tree[u] = true;\n                    q.push(u);\n                }\n            }\n        }\n    }\n    \n    // Assign remaining vertices in descending beauty order\n    vector<int> order_desc(N);\n    iota(order_desc.begin(), order_desc.end(), 0);\n    sort(order_desc.begin(), order_desc.end(), [&](int i, int j) {\n        return A[i] > A[j];\n    });\n    for (int v : order_desc) {\n        if (in_tree[v]) continue;\n        int best_parent = -1;\n        int best_depth = -1;\n        for (int u : adj[v]) {\n            if (in_tree[u] && depth[u] < H) {\n                if (depth[u] > best_depth) {\n                    best_depth = depth[u];\n                    best_parent = u;\n                }\n            }\n        }\n        if (best_parent != -1) {\n            parent[v] = best_parent;\n            depth[v] = best_depth + 1;\n            in_tree[v] = true;\n        } else {\n            parent[v] = -1;\n            depth[v] = 0;\n            in_tree[v] = true;\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\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Convert to mutable 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    }\n    \n    vector<string> ans;\n    \n    // Perform a shift\n    auto shift = [&](char dir, int idx, bool record = true) {\n        if (record) {\n            ans.push_back(string(1, dir) + \" \" + to_string(idx));\n        }\n        \n        if (dir == 'L') {\n            for (int j = 0; j < N-1; j++) {\n                board[idx][j] = board[idx][j+1];\n            }\n            board[idx][N-1] = '.';\n        } else if (dir == 'R') {\n            for (int j = N-1; j > 0; j--) {\n                board[idx][j] = board[idx][j-1];\n            }\n            board[idx][0] = '.';\n        } else if (dir == 'U') {\n            for (int i = 0; i < N-1; i++) {\n                board[i][idx] = board[i+1][idx];\n            }\n            board[N-1][idx] = '.';\n        } else { // 'D'\n            for (int i = N-1; i > 0; i--) {\n                board[i][idx] = board[i-1][idx];\n            }\n            board[0][idx] = '.';\n        }\n    };\n    \n    // Check if a line has Fuku\n    auto has_fuku = [&](int idx, bool is_row) -> bool {\n        if (is_row) {\n            for (int j = 0; j < N; j++) {\n                if (board[idx][j] == 'o') return true;\n            }\n        } else {\n            for (int i = 0; i < N; i++) {\n                if (board[i][idx] == 'o') return true;\n            }\n        }\n        return false;\n    };\n    \n    // Count Oni in a line\n    auto count_oni = [&](int idx, bool is_row) -> int {\n        int cnt = 0;\n        if (is_row) {\n            for (int j = 0; j < N; j++) {\n                if (board[idx][j] == 'x') cnt++;\n            }\n        } else {\n            for (int i = 0; i < N; i++) {\n                if (board[i][idx] == 'x') cnt++;\n            }\n        }\n        return cnt;\n    };\n    \n    // Check if a line has Oni\n    auto has_oni = [&](int idx, bool is_row) -> bool {\n        return count_oni(idx, is_row) > 0;\n    };\n    \n    // Find the shortest clear direction for a batch of Oni\n    // Returns (direction, max_distance) where max_distance is how many times we can push\n    auto find_batch_direction = [&]() -> tuple<char, int, int> {\n        int best_score = 0;\n        char best_dir = ' ';\n        int best_idx = -1;\n        int best_dist = 0;\n        \n        // For each row, check left and right\n        for (int i = 0; i < N; i++) {\n            if (!has_fuku(i, true)) {\n                // Check left\n                int max_dist = 0;\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, j + 1);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(i, true) * 2 - max_dist; // Prefer removing many Oni with few shifts\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'L';\n                        best_idx = i;\n                        best_dist = max_dist;\n                    }\n                }\n                \n                // Check right\n                max_dist = 0;\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, N - j);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(i, true) * 2 - max_dist;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'R';\n                        best_idx = i;\n                        best_dist = max_dist;\n                    }\n                }\n            }\n        }\n        \n        // For each column, check up and down\n        for (int j = 0; j < N; j++) {\n            if (!has_fuku(j, false)) {\n                // Check up\n                int max_dist = 0;\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, i + 1);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(j, false) * 2 - max_dist;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'U';\n                        best_idx = j;\n                        best_dist = max_dist;\n                    }\n                }\n                \n                // Check down\n                max_dist = 0;\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, N - i);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(j, false) * 2 - max_dist;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'D';\n                        best_idx = j;\n                        best_dist = max_dist;\n                    }\n                }\n            }\n        }\n        \n        return {best_dir, best_idx, best_dist};\n    };\n    \n    // Main loop\n    while (true) {\n        // Check if there are any Oni\n        bool has_oni_remaining = false;\n        for (int i = 0; i < N && !has_oni_remaining; i++) {\n            for (int j = 0; j < N && !has_oni_remaining; j++) {\n                if (board[i][j] == 'x') has_oni_remaining = true;\n            }\n        }\n        \n        if (!has_oni_remaining) break;\n        \n        auto [dir, idx, dist] = find_batch_direction();\n        \n        if (dir == ' ') {\n            // No safe batch direction found - use individual Oni removal\n            // Find an Oni with clear direction\n            bool found = false;\n            for (int i = 0; i < N && !found; i++) {\n                for (int j = 0; j < N && !found; j++) {\n                    if (board[i][j] != 'x') continue;\n                    \n                    // Check each direction\n                    bool clear_up = true;\n                    bool clear_down = true;\n                    bool clear_left = true;\n                    bool clear_right = true;\n                    \n                    for (int k = i-1; k >= 0 && clear_up; k--) {\n                        if (board[k][j] == 'o') clear_up = false;\n                    }\n                    for (int k = i+1; k < N && clear_down; k++) {\n                        if (board[k][j] == 'o') clear_down = false;\n                    }\n                    for (int k = j-1; k >= 0 && clear_left; k--) {\n                        if (board[i][k] == 'o') clear_left = false;\n                    }\n                    for (int k = j+1; k < N && clear_right; k++) {\n                        if (board[i][k] == 'o') clear_right = false;\n                    }\n                    \n                    if (clear_up) {\n                        for (int t = 0; t < i + 1; t++) shift('U', j);\n                        for (int t = 0; t < i + 1; t++) shift('D', j);\n                        found = true;\n                    } else if (clear_down) {\n                        for (int t = 0; t < N - i; t++) shift('D', j);\n                        for (int t = 0; t < N - i; t++) shift('U', j);\n                        found = true;\n                    } else if (clear_left) {\n                        for (int t = 0; t < j + 1; t++) shift('L', i);\n                        for (int t = 0; t < j + 1; t++) shift('R', i);\n                        found = true;\n                    } else if (clear_right) {\n                        for (int t = 0; t < N - j; t++) shift('R', i);\n                        for (int t = 0; t < N - j; t++) shift('L', i);\n                        found = true;\n                    }\n                }\n            }\n        } else {\n            // Batch removal: push dist times in direction, then pull dist times back\n            char opposite;\n            if (dir == 'L') opposite = 'R';\n            else if (dir == 'R') opposite = 'L';\n            else if (dir == 'U') opposite = 'D';\n            else opposite = 'U';\n            \n            for (int t = 0; t < dist; t++) {\n                shift(dir, idx);\n            }\n            for (int t = 0; t < dist; t++) {\n                shift(opposite, idx);\n            }\n        }\n    }\n    \n    // Output\n    for (const string& s : ans) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#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 = 100;\n    const int L = 500000;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    // Create a solution that balances flow based on target frequencies\n    vector<int> a(N), b(N);\n    \n    // The key idea: For each employee i, the number of times they visit a_i vs b_i\n    // differs by at most 1. So the total outgoing flow to j depends on how many\n    // employees point to j with their a_i or b_i.\n    \n    // If we can make the incoming flow approximately proportional to T,\n    // we'll achieve low error.\n    \n    // Simple approach: Create a cyclic shift based on sorted order\n    vector<pair<int,int>> sorted;\n    for (int i = 0; i < N; i++) {\n        sorted.push_back({T[i], i});\n    }\n    sort(sorted.begin(), sorted.end(), greater<>());\n    \n    // Now assign successors: each employee points two steps ahead in sorted order\n    // This creates good mixing\n    for (int i = 0; i < N; i++) {\n        int emp = sorted[i].second;\n        int idx1 = (i + 1) % N;\n        int idx2 = (i + 2) % N;\n        a[emp] = sorted[idx1].second;\n        b[emp] = sorted[idx2].second;\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\n\nstruct City {\n    int lx, rx, ly, ry;\n    int cx, cy;\n    int id;\n};\n\nvector<City> cities;\n\n// Fast query function\nvector<pair<int,int>> make_query(const vector<int>& subset) {\n    cout << \"? \" << subset.size();\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int,int>> result;\n    for (int i = 0; i < (int)subset.size() - 1; i++) {\n        int a, b;\n        cin >> a >> b;\n        if (a > b) swap(a, b);\n        result.push_back({a, b});\n    }\n    return result;\n}\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n) : p(n), sz(n, 1) {\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        while (p[x] != x) {\n            p[x] = p[p[x]];\n            x = p[x];\n        }\n        return x;\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\n// Estimate if two cities could be close based on their rectangles\nint rect_dist(const City& a, const City& b) {\n    // Manhattan distance between rectangle boundaries\n    int dx = max(0, max(a.lx - b.rx, b.lx - a.rx));\n    int dy = max(0, max(a.ly - b.ry, b.ly - a.ry));\n    return dx + dy; // Rough estimate\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cities.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].cx = (cities[i].lx + cities[i].rx) / 2;\n        cities[i].cy = (cities[i].ly + cities[i].ry) / 2;\n        cities[i].id = i;\n    }\n    \n    // Build proximity graph based on rectangle overlap\n    vector<vector<int>> near_cities(N);\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            int dist = rect_dist(cities[i], cities[j]);\n            if (dist <= W / 2) { // Conservative threshold\n                near_cities[i].push_back(j);\n                near_cities[j].push_back(i);\n            }\n        }\n    }\n    \n    // Group cities using a greedy approach on proximity\n    vector<bool> used(N, false);\n    vector<vector<int>> groups(M);\n    vector<pair<int,int>> group_sizes; // (size, original_index)\n    for (int i = 0; i < M; i++) {\n        group_sizes.push_back({G[i], i});\n    }\n    sort(group_sizes.begin(), group_sizes.end(), greater<pair<int,int>>());\n    \n    // Process groups from largest to smallest\n    for (auto& [size, group_idx] : group_sizes) {\n        // Find the most central unused city\n        int best_center = -1;\n        int best_degree = -1;\n        \n        for (int i = 0; i < N; i++) {\n            if (!used[i]) {\n                int degree = 0;\n                for (int v : near_cities[i]) {\n                    if (!used[v]) degree++;\n                }\n                if (degree > best_degree) {\n                    best_degree = degree;\n                    best_center = i;\n                }\n            }\n        }\n        \n        if (best_center == -1) break;\n        \n        // BFS to collect nearby unused cities\n        vector<int> component;\n        queue<int> q;\n        q.push(best_center);\n        vector<bool> visited(N, false);\n        visited[best_center] = true;\n        \n        while (!q.empty() && (int)component.size() < size) {\n            int v = q.front(); q.pop();\n            if (!used[v] && (int)component.size() < size) {\n                component.push_back(v);\n                used[v] = true;\n                \n                // Add neighbors\n                for (int u : near_cities[v]) {\n                    if (!visited[u] && !used[u] && (int)component.size() < size) {\n                        visited[u] = true;\n                        q.push(u);\n                    }\n                }\n            }\n        }\n        \n        // If we couldn't fill the group, add any unused cities\n        if ((int)component.size() < size) {\n            for (int i = 0; i < N && (int)component.size() < size; i++) {\n                if (!used[i]) {\n                    component.push_back(i);\n                    used[i] = true;\n                }\n            }\n        }\n        \n        groups[group_idx] = component;\n    }\n    \n    // Now use queries to discover MST edges for each group\n    vector<vector<pair<int,int>>> group_edges(M);\n    set<pair<int,int>> global_known_edges;\n    int queries_used = 0;\n    \n    // Strategy: For each group, make queries of size min(L, group_size) \n    // Use nearly overlapping queries to maximize edge discovery\n    for (int k = 0; k < M && queries_used < Q; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g <= 1) continue;\n        if (g == 2) {\n            group_edges[k].push_back({group[0], group[1]});\n            continue;\n        }\n        \n        // Make queries of size L, trying all combinations that fit\n        int qsize = min(L, g);\n        \n        // Query all possible L-sized subsets (or as many as queries allow)\n        for (int start = 0; start < g && queries_used < Q; start += max(1, qsize - 2)) {\n            if (start + qsize > g) {\n                // Last query with whatever remains\n                if (g - start >= 2) {\n                    vector<int> subset;\n                    for (int j = start; j < g; j++) subset.push_back(group[j]);\n                    if ((int)subset.size() >= 2) {\n                        auto results = make_query(subset);\n                        queries_used++;\n                        \n                        for (auto& e : results) {\n                            if (global_known_edges.count(e) == 0) {\n                                global_known_edges.insert(e);\n                            }\n                        }\n                    }\n                }\n            } else {\n                vector<int> subset;\n                for (int j = start; j < start + qsize; j++) subset.push_back(group[j]);\n                \n                auto results = make_query(subset);\n                queries_used++;\n                \n                for (auto& e : results) {\n                    if (global_known_edges.count(e) == 0) {\n                        global_known_edges.insert(e);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Build MST for each group using known edges\n    for (int k = 0; k < M; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g <= 1) continue;\n        if (g == 2) {\n            if (group_edges[k].empty()) {\n                group_edges[k].push_back({group[0], group[1]});\n            }\n            continue;\n        }\n        \n        DSU dsu(N);\n        group_edges[k].clear();\n        \n        // Add known edges within this group\n        // Sort by some heuristic (we don't have actual distances, but can use rectangle overlap)\n        vector<pair<int,pair<int,int>>> candidate_edges;\n        \n        for (int i = 0; i < g; i++) {\n            for (int j = i + 1; j < g; j++) {\n                int u = group[i], v = group[j];\n                if (u > v) swap(u, v);\n                \n                int priority = 0;\n                if (global_known_edges.count({u, v})) {\n                    priority = -1; // Known edges get highest priority\n                } else {\n                    priority = rect_dist(cities[u], cities[v]);\n                }\n                candidate_edges.push_back({priority, {u, v}});\n            }\n        }\n        \n        sort(candidate_edges.begin(), candidate_edges.end());\n        \n        // Build MST\n        int edges_added = 0;\n        for (auto& [priority, edge] : candidate_edges) {\n            if (dsu.unite(edge.first, edge.second)) {\n                group_edges[k].push_back(edge);\n                edges_added++;\n                if (edges_added == g - 1) break;\n            }\n        }\n        \n        // Safety: ensure connectivity\n        if (edges_added < g - 1) {\n            for (int i = 0; i < g && edges_added < g - 1; i++) {\n                for (int j = i + 1; j < g && edges_added < g - 1; j++) {\n                    if (dsu.unite(group[i], group[j])) {\n                        group_edges[k].push_back({group[i], group[j]});\n                        edges_added++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    cout.flush();\n    \n    for (int k = 0; k < M; k++) {\n        for (int j = 0; j < G[k]; j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[k][j];\n        }\n        cout << endl;\n        \n        for (auto& e : group_edges[k]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Cell {\n    int r, c;\n    Cell(int r = 0, int c = 0) : r(r), c(c) {}\n};\n\nstring dirs = \"UDLR\";\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<Cell> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].r >> targets[i].c;\n    }\n    \n    // State tracking\n    vector<string> grid(N, string(N, '.'));\n    int posR = targets[0].r, posC = targets[0].c;\n    vector<string> actions;\n    \n    auto getBlock = [&](int r, int c) -> bool {\n        return !(r >= 0 && r < N && c >= 0 && c < N) || grid[r][c] == '#';\n    };\n    \n    // Simple strategy: Use Manhattan moves with occasional slides\n    for (int idx = 1; idx < M; idx++) {\n        int tr = targets[idx].r, tc = targets[idx].c;\n        \n        // While not at target, move towards it\n        while (posR != tr || posC != tc) {\n            // Try to find a good slide direction\n            int bestSlideDir = -1;\n            int bestSlideDist = abs(posR - tr) + abs(posC - tc);\n            \n            for (int d = 0; d < 4; d++) {\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Slide as far as possible in this direction\n                    int sr = nr, sc = nc;\n                    while (true) {\n                        int nnr = sr + dr[d], nnc = sc + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        sr = nnr; sc = nnc;\n                    }\n                    int dist = abs(sr - tr) + abs(sc - tc);\n                    if (dist < bestSlideDist) {\n                        bestSlideDist = dist;\n                        bestSlideDir = d;\n                    }\n                }\n            }\n            \n            bool usedSlide = false;\n            if (bestSlideDir >= 0) {\n                int d = bestSlideDir;\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Execute slide\n                    actions.push_back(\"S \" + string(1, dirs[d]));\n                    \n                    // Update position\n                    while (true) {\n                        int nnr = posR + dr[d], nnc = posC + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        posR = nnr; posC = nnc;\n                    }\n                    usedSlide = true;\n                }\n            }\n            \n            if (!usedSlide) {\n                // Simple move towards target\n                int bestDir = -1;\n                int bestDist = abs(posR - tr) + abs(posC - tc);\n                \n                for (int d = 0; d < 4; d++) {\n                    int nr = posR + dr[d], nc = posC + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                        int dist = abs(nr - tr) + abs(nc - tc);\n                        if (dist < bestDist) {\n                            bestDist = dist;\n                            bestDir = d;\n                        }\n                    }\n                }\n                \n                if (bestDir >= 0) {\n                    // Check if we can place a block to improve future slides\n                    // For simplicity, just move\n                    int nr = posR + dr[bestDir], nc = posC + dc[bestDir];\n                    actions.push_back(\"M \" + string(1, dirs[bestDir]));\n                    posR = nr; posC = nc;\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (const auto& a : actions) {\n        cout << a << \"\\n\";\n    }\n    \n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct XorShift {\n    uint64_t x = 88172645463325252ULL;\n    using result_type = uint64_t;\n    uint64_t operator()() {\n        x ^= x << 7;\n        x ^= x >> 9;\n        return x;\n    }\n    static constexpr uint64_t min() { return 0; }\n    static constexpr uint64_t max() { return ULLONG_MAX; }\n    int rand_int(int l, int r) { return l + operator()() % (r - l + 1); }\n    double rand_double() { return (double)operator()() / ULLONG_MAX; }\n} rng;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<int> x(n), y(n), r(n);\n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    vector<int> best_a(n), best_b(n), best_c(n), best_d(n);\n    double best_total = 0;\n    \n    for (int run = 0; run < 3; run++) {\n        vector<int> a(n), b(n), c(n), d(n);\n        vector<long long> s(n);\n        \n        // CRITICAL: Start with guaranteed non-overlapping 1x1 rectangles\n        for (int i = 0; i < n; i++) {\n            a[i] = x[i]; b[i] = y[i];\n            c[i] = x[i] + 1; d[i] = y[i] + 1;\n            s[i] = 1;\n        }\n        \n        // Overlap check\n        auto check_overlap = [&](int idx, int na, int nb, int nc, int nd) -> bool {\n            for (int j = 0; j < n; j++) {\n                if (j == idx) continue;\n                if (max(na, a[j]) < min(nc, c[j]) && \n                    max(nb, b[j]) < min(nd, d[j])) {\n                    return true;\n                }\n            }\n            return false;\n        };\n        \n        // Score function\n        auto get_score = [&](int i, int na, int nb, int nc, int nd) -> double {\n            if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) return 0.0;\n            long long ns = (long long)(nc - na) * (nd - nb);\n            if (ns == 0) return 0.0;\n            double min_s = min(r[i], (int)ns);\n            double max_s = max(r[i], (int)ns);\n            double ratio = min_s / max_s;\n            return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n        };\n        \n        // Phase 1: Careful expansion - one unit at a time, always checking overlap\n        vector<int> order(n);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return r[i] > r[j];\n        });\n        \n        for (int pass = 0; pass < 5; pass++) {\n            for (int i : order) {\n                // Expand step by step, always checking overlap\n                for (int step = 0; step < 30; step++) {\n                    int best_dir = -1;\n                    double best_gain = 0;\n                    \n                    for (int dir = 0; dir < 4; dir++) {\n                        int na = a[i], nb = b[i], nc = c[i], nd = d[i];\n                        \n                        if (dir == 0 && a[i] > 0) na = a[i] - 1;\n                        else if (dir == 1 && c[i] < 10000) nc = c[i] + 1;\n                        else if (dir == 2 && b[i] > 0) nb = b[i] - 1;\n                        else if (dir == 3 && d[i] < 10000) nd = d[i] + 1;\n                        else continue;\n                        \n                        // CRITICAL: Only expand if no overlap\n                        if (!check_overlap(i, na, nb, nc, nd)) {\n                            double old_score = get_score(i, a[i], b[i], c[i], d[i]);\n                            double new_score = get_score(i, na, nb, nc, nd);\n                            double gain = new_score - old_score;\n                            if (gain > best_gain) {\n                                best_gain = gain;\n                                best_dir = dir;\n                            }\n                        }\n                    }\n                    \n                    if (best_dir == -1 || best_gain <= 0) break;\n                    \n                    if (best_dir == 0) a[i]--;\n                    else if (best_dir == 1) c[i]++;\n                    else if (best_dir == 2) b[i]--;\n                    else d[i]++;\n                    \n                    s[i] = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n                }\n                \n                // If too big, shrink (only if it improves score)\n                double ratio = (double)s[i] / r[i];\n                if (ratio > 1.2) {\n                    for (int step = 0; step < 10; step++) {\n                        int best_dir = -1;\n                        double best_gain = 0;\n                        \n                        for (int dir = 0; dir < 4; dir++) {\n                            int na = a[i], nb = b[i], nc = c[i], nd = d[i];\n                            \n                            if (dir == 0 && c[i] - a[i] > 1) na = a[i] + 1;\n                            else if (dir == 1 && c[i] - a[i] > 1) nc = c[i] - 1;\n                            else if (dir == 2 && d[i] - b[i] > 1) nb = b[i] + 1;\n                            else if (dir == 3 && d[i] - b[i] > 1) nd = d[i] - 1;\n                            else continue;\n                            \n                            if (na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd) {\n                                double old_score = get_score(i, a[i], b[i], c[i], d[i]);\n                                double new_score = get_score(i, na, nb, nc, nd);\n                                double gain = new_score - old_score;\n                                if (gain > best_gain) {\n                                    best_gain = gain;\n                                    best_dir = dir;\n                                }\n                            }\n                        }\n                        \n                        if (best_dir == -1 || best_gain <= 0) break;\n                        \n                        if (best_dir == 0) a[i]++;\n                        else if (best_dir == 1) c[i]--;\n                        else if (best_dir == 2) b[i]++;\n                        else d[i]--;\n                        \n                        s[i] = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n                    }\n                }\n            }\n        }\n        \n        // Phase 2: Simulated annealing\n        const int iterations = 200000;\n        const double start_temp = 0.3;\n        const double end_temp = 0.0001;\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            double temp = start_temp + (end_temp - start_temp) * iter / iterations;\n            \n            int i = rng.rand_int(0, n - 1);\n            \n            int old_a = a[i], old_b = b[i], old_c = c[i], old_d = d[i];\n            double old_score = get_score(i, old_a, old_b, old_c, old_d);\n            \n            double ratio = (double)s[i] / r[i];\n            int na = a[i], nb = b[i], nc = c[i], nd = d[i];\n            \n            if (ratio < 0.9) {\n                // Too small - expand\n                int dir = rng.rand_int(0, 3);\n                int delta = rng.rand_int(1, min(50, (int)sqrt(r[i]) + 2));\n                if (dir == 0) na = max(0, a[i] - delta);\n                else if (dir == 1) nc = min(10000, c[i] + delta);\n                else if (dir == 2) nb = max(0, b[i] - delta);\n                else nd = min(10000, d[i] + delta);\n            } else if (ratio > 1.1) {\n                // Too big - shrink\n                int dir = rng.rand_int(0, 3);\n                int delta = rng.rand_int(1, min(20, (int)sqrt(s[i]) / 2 + 1));\n                if (dir == 0) na = min(c[i] - 1, a[i] + delta);\n                else if (dir == 1) nc = max(a[i] + 1, c[i] - delta);\n                else if (dir == 2) nb = min(d[i] - 1, b[i] + delta);\n                else nd = max(b[i] + 1, d[i] - delta);\n                if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n            } else {\n                // Near optimal - try both expand and shrink\n                int dir = rng.rand_int(0, 3);\n                int delta = rng.rand_int(1, 5);\n                if (rng.rand_double() < 0.5) {\n                    if (dir == 0) na = max(0, a[i] - delta);\n                    else if (dir == 1) nc = min(10000, c[i] + delta);\n                    else if (dir == 2) nb = max(0, b[i] - delta);\n                    else nd = min(10000, d[i] + delta);\n                } else {\n                    if (dir == 0) na = min(c[i] - 1, a[i] + delta);\n                    else if (dir == 1) nc = max(a[i] + 1, c[i] - delta);\n                    else if (dir == 2) nb = min(d[i] - 1, b[i] + delta);\n                    else nd = max(b[i] + 1, d[i] - delta);\n                    if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n                }\n            }\n            \n            // Validate\n            if (na >= nc || nb >= nd) continue;\n            if (!(na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd)) continue;\n            \n            // CRITICAL: Check overlap before accepting move\n            if (check_overlap(i, na, nb, nc, nd)) continue;\n            \n            double new_score = get_score(i, na, nb, nc, nd);\n            \n            if (new_score > old_score || rng.rand_double() < exp((new_score - old_score) * 500 / temp)) {\n                a[i] = na; b[i] = nb; c[i] = nc; d[i] = nd;\n                s[i] = (long long)(nc - na) * (nd - nb);\n            }\n        }\n        \n        // Phase 3: Greedy fine-tuning (always check overlap)\n        for (int pass = 0; pass < 3; pass++) {\n            for (int i = 0; i < n; i++) {\n                double old_score = get_score(i, a[i], b[i], c[i], d[i]);\n                double ratio = (double)s[i] / r[i];\n                \n                // Try to expand if too small\n                if (ratio < 0.95) {\n                    for (int attempt = 0; attempt < 20; attempt++) {\n                        int best_dir = -1;\n                        double best_new = old_score;\n                        \n                        for (int dir = 0; dir < 4; dir++) {\n                            int na = a[i], nb = b[i], nc = c[i], nd = d[i];\n                            if (dir == 0 && a[i] > 0) na = a[i] - 1;\n                            else if (dir == 1 && c[i] < 10000) nc = c[i] + 1;\n                            else if (dir == 2 && b[i] > 0) nb = b[i] - 1;\n                            else if (dir == 3 && d[i] < 10000) nd = d[i] + 1;\n                            else continue;\n                            \n                            if (!check_overlap(i, na, nb, nc, nd)) {\n                                double ns = get_score(i, na, nb, nc, nd);\n                                if (ns > best_new) { best_new = ns; best_dir = dir; }\n                            }\n                        }\n                        \n                        if (best_dir == -1 || best_new <= old_score) break;\n                        if (best_dir == 0) a[i]--;\n                        else if (best_dir == 1) c[i]++;\n                        else if (best_dir == 2) b[i]--;\n                        else d[i]++;\n                        s[i] = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n                        old_score = best_new;\n                    }\n                }\n                \n                // Try to shrink if too big\n                if (ratio > 1.05) {\n                    for (int attempt = 0; attempt < 10; attempt++) {\n                        int best_dir = -1;\n                        double best_new = old_score;\n                        \n                        for (int dir = 0; dir < 4; dir++) {\n                            int na = a[i], nb = b[i], nc = c[i], nd = d[i];\n                            if (dir == 0 && c[i] - a[i] > 1) na = a[i] + 1;\n                            else if (dir == 1 && c[i] - a[i] > 1) nc = c[i] - 1;\n                            else if (dir == 2 && d[i] - b[i] > 1) nb = b[i] + 1;\n                            else if (dir == 3 && d[i] - b[i] > 1) nd = d[i] - 1;\n                            else continue;\n                            \n                            if (na <= x[i] && x[i] < nc && nb <= y[i] && y[i] < nd) {\n                                double ns = get_score(i, na, nb, nc, nd);\n                                if (ns > best_new) { best_new = ns; best_dir = dir; }\n                            }\n                        }\n                        \n                        if (best_dir == -1 || best_new <= old_score) break;\n                        if (best_dir == 0) a[i]++;\n                        else if (best_dir == 1) c[i]--;\n                        else if (best_dir == 2) b[i]++;\n                        else d[i]--;\n                        s[i] = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n                        old_score = best_new;\n                    }\n                }\n            }\n        }\n        \n        // Compare with best\n        double total = 0;\n        for (int i = 0; i < n; i++) {\n            total += get_score(i, a[i], b[i], c[i], d[i]);\n        }\n        \n        if (total > best_total) {\n            best_total = total;\n            for (int i = 0; i < n; i++) {\n                best_a[i] = a[i]; best_b[i] = b[i];\n                best_c[i] = c[i]; best_d[i] = d[i];\n            }\n        }\n    }\n    \n    // Final verification - ensure no overlaps (shouldn't happen, but just in case)\n    bool has_overlap = true;\n    while (has_overlap) {\n        has_overlap = false;\n        for (int i = 0; i < n && !has_overlap; i++) {\n            for (int j = i + 1; j < n && !has_overlap; j++) {\n                if (max(best_a[i], best_a[j]) < min(best_c[i], best_c[j]) && \n                    max(best_b[i], best_b[j]) < min(best_d[i], best_d[j])) {\n                    has_overlap = true;\n                    // Shrink the one with worse score\n                    double si = 1.0 - (1.0 - min(r[i], (int)(best_c[i]-best_a[i])*(best_d[i]-best_b[i])) / \n                                      max(r[i], (int)(best_c[i]-best_a[i])*(best_d[i]-best_b[i]))) * \n                                      (1.0 - min(r[i], (int)(best_c[i]-best_a[i])*(best_d[i]-best_b[i])) / \n                                      max(r[i], (int)(best_c[i]-best_a[i])*(best_d[i]-best_b[i])));\n                    double sj = 1.0 - (1.0 - min(r[j], (int)(best_c[j]-best_a[j])*(best_d[j]-best_b[j])) / \n                                      max(r[j], (int)(best_c[j]-best_a[j])*(best_d[j]-best_b[j]))) * \n                                      (1.0 - min(r[j], (int)(best_c[j]-best_a[j])*(best_d[j]-best_b[j])) / \n                                      max(r[j], (int)(best_c[j]-best_a[j])*(best_d[j]-best_b[j])));\n                    \n                    if (si < sj) {\n                        best_a[i] = x[i]; best_b[i] = y[i];\n                        best_c[i] = x[i] + 1; best_d[i] = y[i] + 1;\n                    } else {\n                        best_a[j] = x[j]; best_b[j] = y[j];\n                        best_c[j] = x[j] + 1; best_d[j] = y[j] + 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < n; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \" \" \n             << best_c[i] << \" \" << best_d[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst string dirs = \"UDLR\";\n\nstruct State {\n    vector<int> used;\n    int i, j;\n    long long score;\n    string path;\n    \n    State() : used(), i(0), j(0), score(0), path(\"\") {}\n    State(const State& other) : used(other.used), i(other.i), j(other.j), \n                                score(other.score), path(other.path) {}\n};\n\nclass Solver {\nprivate:\n    int si, sj;\n    vector<vector<int>> t, p;\n    int M;\n    long long best_score;\n    string best_path;\n    vector<vector<pair<int,int>>> tile_cells;\n    vector<int> tile_size;\n    vector<vector<int>> tile_adjacent;\n    vector<long long> tile_total_value;\n    vector<vector<int>> tile_edge_count;\n    vector<double> tile_density;\n    vector<pair<int,int>> best_cell_in_tile;\n    vector<int> best_cell_value;\n    \n    // For adaptive lookahead\n    vector<vector<int>> distance_to_hotspot;\n    vector<pair<int,pair<int,int>>> hotspots;\n    \npublic:\n    Solver() {\n        cin >> si >> sj;\n        t.assign(N, vector<int>(N));\n        p.assign(N, vector<int>(N));\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> t[i][j];\n        \n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++)\n                cin >> p[i][j];\n        \n        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        tile_cells.resize(M);\n        tile_size.resize(M, 0);\n        tile_total_value.resize(M, 0);\n        tile_density.resize(M, 0);\n        tile_edge_count.assign(M, vector<int>(M, 0));\n        best_cell_in_tile.resize(M, {-1, -1});\n        best_cell_value.resize(M, -1);\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int tid = t[i][j];\n                tile_cells[tid].push_back({i, j});\n                tile_size[tid]++;\n                tile_total_value[tid] += p[i][j];\n                if (p[i][j] > best_cell_value[tid]) {\n                    best_cell_value[tid] = p[i][j];\n                    best_cell_in_tile[tid] = {i, j};\n                }\n                // Identify hotspots (high value cells)\n                if (p[i][j] >= 75) {\n                    hotspots.push_back({p[i][j], {i, j}});\n                }\n            }\n        }\n        \n        sort(hotspots.begin(), hotspots.end(), greater<pair<int,pair<int,int>>>());\n        if (hotspots.size() > 20) hotspots.resize(20);\n        \n        for (int i = 0; i < M; i++) {\n            if (tile_size[i] > 0) {\n                tile_density[i] = (double)tile_total_value[i] / tile_size[i];\n            }\n        }\n        \n        tile_adjacent.resize(M);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int tid = t[i][j];\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d];\n                    int nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                        int nid = t[ni][nj];\n                        if (tid != nid) {\n                            tile_adjacent[tid].push_back(nid);\n                            tile_edge_count[tid][nid]++;\n                        }\n                    }\n                }\n            }\n        }\n        \n        for (int i = 0; i < M; i++) {\n            sort(tile_adjacent[i].begin(), tile_adjacent[i].end());\n            tile_adjacent[i].erase(unique(tile_adjacent[i].begin(), tile_adjacent[i].end()), tile_adjacent[i].end());\n        }\n    }\n    \n    string solve() {\n        best_score = -1;\n        best_path = \"\";\n        \n        // Phase 1: Beam search with balanced lookahead\n        for (int attempt = 0; attempt < 40; attempt++) {\n            balanced_beam_search(attempt);\n        }\n        \n        // Phase 2: Aggressive search with more randomness\n        for (int attempt = 0; attempt < 30; attempt++) {\n            aggressive_random_search(attempt);\n        }\n        \n        return best_path;\n    }\n    \nprivate:\n    bool is_valid_move(const State& state, int ni, int nj) {\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (state.used[t[ni][nj]]) return false;\n        return true;\n    }\n    \n    long long compute_balanced_heuristic(const State& state, int ni, int nj, int attempt, int step) {\n        long long h = p[ni][nj];\n        int target_tile = t[ni][nj];\n        \n        // Adaptive lookahead: 2 levels deep, but focus more on immediate neighbors\n        for (int dd = 0; dd < 4; dd++) {\n            int nni = ni + di[dd];\n            int nnj = nj + dj[dd];\n            if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n            if (!state.used[t[nni][nnj]]) {\n                h += p[nni][nnj] * 0.5;  // 50% weight on immediate neighbors\n                \n                for (int ddd = 0; ddd < 4; ddd++) {\n                    int nnni = nni + di[ddd];\n                    int nnnj = nnj + dj[ddd];\n                    if (nnni < 0 || nnni >= N || nnnj < 0 || nnnj >= N) continue;\n                    if (!state.used[t[nnni][nnnj]]) {\n                        h += p[nnni][nnnj] * 0.15;  // 15% on 2-step\n                    }\n                }\n            }\n        }\n        \n        // Tile-level heuristics\n        int unvisited_adjacent = 0;\n        for (int adj : tile_adjacent[target_tile]) {\n            if (!state.used[adj]) unvisited_adjacent++;\n        }\n        h += unvisited_adjacent * 30;  // Strong connectivity bonus\n        \n        // Tile importance\n        h += (long long)(tile_density[target_tile] * 30);\n        h += tile_total_value[target_tile] * 0.08;\n        \n        // Edge connectivity\n        for (int adj : tile_adjacent[target_tile]) {\n            if (!state.used[adj]) {\n                h += tile_edge_count[target_tile][adj] * 3;\n            }\n        }\n        \n        // Deterministic randomness\n        h += (attempt * 7 + step * 13 + ni * 17 + nj * 19) % 20;\n        \n        return h;\n    }\n    \n    long long compute_aggressive_heuristic(const State& state, int ni, int nj, int attempt, int step) {\n        long long h = p[ni][nj];\n        int target_tile = t[ni][nj];\n        \n        // More focused lookahead - just immediate neighbors\n        for (int dd = 0; dd < 4; dd++) {\n            int nni = ni + di[dd];\n            int nnj = nj + dj[dd];\n            if (nni < 0 || nni >= N || nnj < 0 || nnj >= N) continue;\n            if (!state.used[t[nni][nnj]]) {\n                h += p[nni][nnj] * 0.6;\n            }\n        }\n        \n        // Aggressive tile exploration\n        int unvisited_adjacent = 0;\n        for (int adj : tile_adjacent[target_tile]) {\n            if (!state.used[adj]) unvisited_adjacent++;\n        }\n        h += unvisited_adjacent * 40;  // Very strong connectivity\n        \n        h += tile_total_value[target_tile] * 0.12;\n        \n        // More randomness for exploration\n        h += (attempt * 13 + step * 17 + ni * 19 + nj * 23) % 40;\n        \n        return h;\n    }\n    \n    void balanced_beam_search(int attempt) {\n        const int BEAM_WIDTH = 12;\n        const int MAX_STEPS = 500;\n        \n        State start;\n        start.used.assign(M, 0);\n        start.i = si;\n        start.j = sj;\n        start.score = p[si][sj];\n        start.used[t[si][sj]] = 1;\n        start.path = \"\";\n        \n        // Try different starting strategies\n        int strategy = attempt % 5;\n        if (strategy < 4) {\n            int dir = strategy;\n            int ni = si + di[dir];\n            int nj = sj + dj[dir];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N && !start.used[t[ni][nj]]) {\n                start.used[t[ni][nj]] = 1;\n                start.i = ni;\n                start.j = nj;\n                start.score += p[ni][nj];\n                start.path += dirs[dir];\n            }\n        }\n        \n        vector<State> beam = {start};\n        \n        for (int step = 0; step < MAX_STEPS && !beam.empty(); step++) {\n            vector<State> candidates;\n            \n            for (const auto& state : beam) {\n                struct Move {\n                    long long heuristic;\n                    int d, ni, nj;\n                };\n                vector<Move> valid_moves;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = state.i + di[d];\n                    int nj = state.j + dj[d];\n                    \n                    if (!is_valid_move(state, ni, nj)) continue;\n                    \n                    long long h = compute_balanced_heuristic(state, ni, nj, attempt, step);\n                    valid_moves.push_back({h, d, ni, nj});\n                }\n                \n                if (valid_moves.empty()) {\n                    if (state.score > best_score) {\n                        best_score = state.score;\n                        best_path = state.path;\n                    }\n                    continue;\n                }\n                \n                sort(valid_moves.begin(), valid_moves.end(),\n                     [](const Move& a, const Move& b) { return a.heuristic > b.heuristic; });\n                \n                int take;\n                if (valid_moves.size() <= 2) {\n                    take = (int)valid_moves.size();\n                } else if (valid_moves.size() <= 4) {\n                    take = 3;\n                } else {\n                    take = min((int)valid_moves.size(), BEAM_WIDTH / 2);\n                }\n                \n                for (int k = 0; k < take; k++) {\n                    Move& move = valid_moves[k];\n                    \n                    State new_state(state);\n                    new_state.used[t[move.ni][move.nj]] = 1;\n                    new_state.i = move.ni;\n                    new_state.j = move.nj;\n                    new_state.score += p[move.ni][move.nj];\n                    new_state.path += dirs[move.d];\n                    \n                    candidates.push_back(new_state);\n                }\n            }\n            \n            if (candidates.empty()) break;\n            \n            sort(candidates.begin(), candidates.end(),\n                 [](const State& a, const State& b) { return a.score > b.score; });\n            \n            beam.clear();\n            int keep = min((int)candidates.size(), BEAM_WIDTH);\n            for (int k = 0; k < keep; k++) {\n                beam.push_back(candidates[k]);\n                \n                if (candidates[k].score > best_score) {\n                    best_score = candidates[k].score;\n                    best_path = candidates[k].path;\n                }\n            }\n        }\n        \n        for (const auto& state : beam) {\n            if (state.score > best_score) {\n                best_score = state.score;\n                best_path = state.path;\n            }\n        }\n    }\n    \n    void aggressive_random_search(int attempt) {\n        const int BEAM_WIDTH = 10;\n        const int MAX_STEPS = 400;\n        \n        State start;\n        start.used.assign(M, 0);\n        start.i = si;\n        start.j = sj;\n        start.score = p[si][sj];\n        start.used[t[si][sj]] = 1;\n        start.path = \"\";\n        \n        int dir = attempt % 4;\n        int ni = si + di[dir];\n        int nj = sj + dj[dir];\n        \n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !start.used[t[ni][nj]]) {\n            start.used[t[ni][nj]] = 1;\n            start.i = ni;\n            start.j = nj;\n            start.score += p[ni][nj];\n            start.path += dirs[dir];\n        }\n        \n        vector<State> beam = {start};\n        \n        for (int step = 0; step < MAX_STEPS && !beam.empty(); step++) {\n            vector<State> candidates;\n            \n            for (const auto& state : beam) {\n                struct Move {\n                    long long heuristic;\n                    int d, ni, nj;\n                };\n                vector<Move> valid_moves;\n                \n                for (int d = 0; d < 4; d++) {\n                    int ni = state.i + di[d];\n                    int nj = state.j + dj[d];\n                    \n                    if (!is_valid_move(state, ni, nj)) continue;\n                    \n                    long long h = compute_aggressive_heuristic(state, ni, nj, attempt, step);\n                    valid_moves.push_back({h, d, ni, nj});\n                }\n                \n                if (valid_moves.empty()) {\n                    if (state.score > best_score) {\n                        best_score = state.score;\n                        best_path = state.path;\n                    }\n                    continue;\n                }\n                \n                sort(valid_moves.begin(), valid_moves.end(),\n                     [](const Move& a, const Move& b) { return a.heuristic > b.heuristic; });\n                \n                int take = min((int)valid_moves.size(), 3);\n                for (int k = 0; k < take; k++) {\n                    Move& move = valid_moves[k];\n                    \n                    State new_state(state);\n                    new_state.used[t[move.ni][move.nj]] = 1;\n                    new_state.i = move.ni;\n                    new_state.j = move.nj;\n                    new_state.score += p[move.ni][move.nj];\n                    new_state.path += dirs[move.d];\n                    \n                    candidates.push_back(new_state);\n                }\n            }\n            \n            if (candidates.empty()) break;\n            \n            sort(candidates.begin(), candidates.end(),\n                 [](const State& a, const State& b) { return a.score > b.score; });\n            \n            beam.clear();\n            int keep = min((int)candidates.size(), BEAM_WIDTH);\n            for (int k = 0; k < keep; k++) {\n                beam.push_back(candidates[k]);\n                if (candidates[k].score > best_score) {\n                    best_score = candidates[k].score;\n                    best_path = candidates[k].path;\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    string result = solver.solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\n\nstruct Graph {\n    vector<vector<pair<int, int>>> adj;\n    \n    // For each row/column, store observations to detect structure\n    vector<vector<double>> h_obs;  // [row][col] = observed values\n    vector<vector<double>> v_obs;  // [col][row] = observed values\n    \n    // Current best estimates for each edge\n    vector<double> edge_est;\n    vector<int> edge_type;  // 0 = horizontal, 1 = vertical  \n    vector<int> edge_ri;    // row index\n    vector<int> edge_ci;    // column index\n    \n    // Group-based estimates  \n    vector<double> h_base;  // [row] = base value\n    vector<double> v_base;  // [col] = base value\n    vector<int> h_cnt;      // [row] = observation count\n    vector<int> v_cnt;      // [col] = observation count\n    \n    Graph() {\n        adj.resize(N * N);\n        h_obs.assign(N, vector<double>());\n        v_obs.assign(N, vector<double>());\n        h_base.assign(N, 5000.0);\n        v_base.assign(N, 5000.0);\n        h_cnt.assign(N, 0);\n        v_cnt.assign(N, 0);\n        \n        // Horizontal edges\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                edge_type.push_back(0);\n                edge_ri.push_back(i);\n                edge_ci.push_back(j);\n                edge_est.push_back(5000.0);\n                adj[u].push_back({v, (int)edge_type.size() - 1});\n                adj[v].push_back({u, (int)edge_type.size() - 1});\n                h_obs[i].push_back(5000.0);\n            }\n        }\n        \n        // Vertical edges\n        for (int i = 0; i < N-1; i++) {\n            for (int j = 0; j < N; j++) {\n                int u = i * N + j;\n                int v = (i+1) * N + j;\n                edge_type.push_back(1);\n                edge_ri.push_back(i);\n                edge_ci.push_back(j);\n                edge_est.push_back(5000.0);\n                adj[u].push_back({v, (int)edge_type.size() - 1});\n                adj[v].push_back({u, (int)edge_type.size() - 1});\n                v_obs[j].push_back(5000.0);\n            }\n        }\n    }\n    \n    // Get estimate using group structure\n    double get_est(int eid) {\n        if (edge_type[eid] == 0) {\n            return h_base[edge_ri[eid]];\n        } else {\n            return v_base[edge_ci[eid]];\n        }\n    }\n    \n    string find_path(int si, int sj, int ti, int tj, vector<int>& used_edges) {\n        vector<double> dist(N*N, INF);\n        vector<int> prev(N*N, -1);\n        vector<int> prev_edge(N*N, -1);\n        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<>> pq;\n        \n        int s = si * N + sj;\n        int t = ti * N + tj;\n        dist[s] = 0;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == t) break;\n            \n            for (auto [v, eid] : adj[u]) {\n                double nd = d + get_est(eid);\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prev[v] = u;\n                    prev_edge[v] = eid;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        used_edges.clear();\n        int cur = t;\n        while (cur != s) {\n            int eid = prev_edge[cur];\n            used_edges.push_back(eid);\n            cur = prev[cur];\n        }\n        reverse(used_edges.begin(), used_edges.end());\n        \n        string path;\n        int ci = si, cj = sj;\n        for (int eid : used_edges) {\n            if (edge_type[eid] == 0) {\n                if (edge_ci[eid] == cj) {\n                    path += 'R'; cj++;\n                } else {\n                    path += 'L'; cj--;\n                }\n            } else {\n                if (edge_ri[eid] == ci) {\n                    path += 'D'; ci++;\n                } else {\n                    path += 'U'; ci--;\n                }\n            }\n        }\n        return path;\n    }\n    \n    void update_edges(const vector<int>& used_edges, double observed_length, int query_num) {\n        double predicted = 0;\n        for (int eid : used_edges) {\n            predicted += get_est(eid);\n        }\n        \n        if (used_edges.empty()) return;\n        \n        double error = observed_length - predicted;\n        \n        // Very aggressive learning rate\n        double lr;\n        if (query_num < 30) lr = 0.8;\n        else if (query_num < 60) lr = 0.6;\n        else if (query_num < 100) lr = 0.5;\n        else if (query_num < 200) lr = 0.4;\n        else lr = 0.3;\n        \n        // Group the errors by row/column\n        vector<double> h_err(N, 0);\n        vector<int> h_used(N, 0);\n        vector<double> v_err(N, 0);\n        vector<int> v_used(N, 0);\n        \n        for (int eid : used_edges) {\n            double contrib = get_est(eid) / predicted;\n            double err_share = error * contrib;\n            \n            if (edge_type[eid] == 0) {\n                int row = edge_ri[eid];\n                h_err[row] += err_share;\n                h_used[row]++;\n            } else {\n                int col = edge_ci[eid];\n                v_err[col] += err_share;\n                v_used[col]++;\n            }\n        }\n        \n        // Update row bases\n        for (int i = 0; i < N; i++) {\n            if (h_used[i] > 0) {\n                h_cnt[i]++;\n                double alpha = lr / (1.0 + h_cnt[i] * 0.02);\n                h_base[i] += alpha * h_err[i] / h_used[i];\n                h_base[i] = max(100.0, min(20000.0, h_base[i]));\n            }\n        }\n        \n        // Update column bases\n        for (int j = 0; j < N; j++) {\n            if (v_used[j] > 0) {\n                v_cnt[j]++;\n                double alpha = lr / (1.0 + v_cnt[j] * 0.02);\n                v_base[j] += alpha * v_err[j] / v_used[j];\n                v_base[j] = max(100.0, min(20000.0, v_base[j]));\n            }\n        }\n        \n        // Store observations for later structure detection\n        for (int idx = 0; idx < used_edges.size(); idx++) {\n            int eid = used_edges[idx];\n            double obs_val = get_est(eid) + error * get_est(eid) / predicted;\n            \n            if (edge_type[eid] == 0) {\n                h_obs[edge_ri[eid]][edge_ci[eid]] = obs_val;\n            } else {\n                v_obs[edge_ci[eid]][edge_ri[eid]] = obs_val;\n            }\n        }\n        \n        // Periodically detect if M=2 (split points)\n        if (query_num == 100 || query_num == 300 || query_num == 500) {\n            for (int i = 0; i < N; i++) {\n                // Look for natural split points in horizontal edges\n                // If we see two clusters, we might have M=2\n                // For simplicity, assume M=1 always (this is the simpler case)\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Graph g;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        vector<int> used_edges;\n        string path = g.find_path(si, sj, ti, tj, used_edges);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        double observed;\n        cin >> observed;\n        \n        g.update_edges(used_edges, observed, k);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nstruct Solver {\n    int N, M;\n    vector<string>& strings;\n    vector<string> ans;\n    \n    // Precomputed string data\n    vector<int> str_len;\n    vector<vector<pair<int,int>>> str_h_positions;  // (r, c) for each string horizontally\n    vector<vector<pair<int,int>>> str_v_positions;  // (r, c) for each string vertically\n    \n    Solver(int n, int m, vector<string>& s) : N(n), M(m), strings(s) {\n        ans.assign(N, string(N, '.'));\n        str_len.resize(M);\n        str_h_positions.resize(M);\n        str_v_positions.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            str_len[i] = strings[i].size();\n        }\n        \n        // Precompute all possible positions for each string\n        for (int i = 0; i < M; i++) {\n            string& str = strings[i];\n            int len = str_len[i];\n            \n            // Horizontal positions\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    str_h_positions[i].push_back({r, c});\n                }\n            }\n            \n            // Vertical positions\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    str_v_positions[i].push_back({r, c});\n                }\n            }\n        }\n    }\n    \n    // Check if string exists at given position\n    bool check_at(const string& str, int r, int c, bool hor) {\n        int len = str.size();\n        if (hor) {\n            for (int p = 0; p < len; p++) {\n                if (ans[r][(c + p) % N] != str[p]) return false;\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                if (ans[(r + p) % N][c] != str[p]) return false;\n            }\n        }\n        return true;\n    }\n    \n    // Place string at position (overwrites anyway)\n    void place_at(const string& str, int r, int c, bool hor) {\n        int len = str.size();\n        if (hor) {\n            for (int p = 0; p < len; p++) {\n                ans[r][(c + p) % N] = str[p];\n            }\n        } else {\n            for (int p = 0; p < len; p++) {\n                ans[(r + p) % N][c] = str[p];\n            }\n        }\n    }\n    \n    void solve() {\n        // Count character frequencies in all strings\n        vector<int> char_count(8, 0);\n        for (auto& s : strings) {\n            for (char c : s) char_count[c - 'A']++;\n        }\n        \n        // Find most common character\n        int best_char = 0;\n        for (int k = 1; k < 8; k++) {\n            if (char_count[k] > char_count[best_char]) best_char = k;\n        }\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            if (str_len[a] != str_len[b]) return str_len[a] > str_len[b];\n            return strings[a] < strings[b];\n        });\n        \n        // Place all strings in their first valid position\n        for (int idx : order) {\n            string& str = strings[idx];\n            \n            // Try horizontal positions\n            bool placed = false;\n            for (auto [r, c] : str_h_positions[idx]) {\n                // Quick check if position is compatible\n                bool ok = true;\n                for (int p = 0; p < str_len[idx]; p++) {\n                    int nc = (c + p) % N;\n                    if (ans[r][nc] != '.' && ans[r][nc] != str[p]) {\n                        ok = false;\n                        break;\n                    }\n                }\n                if (ok) {\n                    for (int p = 0; p < str_len[idx]; p++) {\n                        int nc = (c + p) % N;\n                        if (ans[r][nc] == '.') ans[r][nc] = str[p];\n                    }\n                    placed = true;\n                    break;\n                }\n            }\n            \n            if (!placed) {\n                // Try vertical positions\n                for (auto [r, c] : str_v_positions[idx]) {\n                    bool ok = true;\n                    for (int p = 0; p < str_len[idx]; p++) {\n                        int nr = (r + p) % N;\n                        if (ans[nr][c] != '.' && ans[nr][c] != str[p]) {\n                            ok = false;\n                            break;\n                        }\n                    }\n                    if (ok) {\n                        for (int p = 0; p < str_len[idx]; p++) {\n                            int nr = (r + p) % N;\n                            if (ans[nr][c] == '.') ans[nr][c] = str[p];\n                        }\n                        placed = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!placed) {\n                // Force place at first position\n                auto [r, c] = str_h_positions[idx][0];\n                for (int p = 0; p < str_len[idx]; p++) {\n                    ans[r][(c + p) % N] = str[p];\n                }\n            }\n        }\n        \n        // Fill remaining empty cells with most common nearby character\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (ans[r][c] != '.') continue;\n                \n                // Check neighbors for character frequency\n                vector<int> nearby_freq(8, 0);\n                \n                // Check four directions\n                int dirs[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};\n                for (auto [dr, dc] : dirs) {\n                    int nr = (r + dr + N) % N;\n                    int nc = (c + dc + N) % N;\n                    if (ans[nr][nc] != '.') {\n                        nearby_freq[ans[nr][nc] - 'A']++;\n                    }\n                }\n                \n                // Also consider global frequency for tie-breaking\n                int best = 0;\n                int best_freq = -1;\n                for (int k = 0; k < 8; k++) {\n                    int score = nearby_freq[k] * 3 + char_count[k]; // weight local higher\n                    if (score > best_freq) {\n                        best_freq = score;\n                        best = k;\n                    }\n                }\n                \n                ans[r][c] = 'A' + (best_freq >= 0 ? best : best_char);\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Solver solver(N, M, strings);\n    solver.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << solver.ans[i] << endl;\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> c;\nconst int di[4] = {-1, 1, 0, 0};\nconst int dj[4] = {0, 0, -1, 1};\n\nstruct Edge { int to, w; };\nvector<vector<Edge>> graph;\n\nvoid buildGraph() {\n    graph.resize(N*N);\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        int id = i*N+j;\n        int w = c[i][j]-'0';\n        if (i>0 && c[i-1][j]!='#') graph[id].push_back({(i-1)*N+j, w});\n        if (i<N-1 && c[i+1][j]!='#') graph[id].push_back({(i+1)*N+j, w});\n        if (j>0 && c[i][j-1]!='#') graph[id].push_back({i*N+j-1, w});\n        if (j<N-1 && c[i][j+1]!='#') graph[id].push_back({i*N+j+1, w});\n    }\n}\n\npair<vector<int>, vector<int>> dijkstraWithParent(int start) {\n    vector<int> dist(N*N, 1e9), parent(N*N, -1);\n    dist[start] = 0;\n    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;\n    pq.push({0, start});\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d > dist[v]) continue;\n        for (auto [to, w] : graph[v]) {\n            if (dist[to] > dist[v] + w) {\n                dist[to] = dist[v] + w;\n                parent[to] = v;\n                pq.push({dist[to], to});\n            }\n        }\n    }\n    return {dist, parent};\n}\n\nstring reconstruct(int start, int target, const vector<int>& parent) {\n    if (start == target) return \"\";\n    string path;\n    int cur = target;\n    while (cur != start) {\n        int p = parent[cur];\n        if (p == -1) return \"\";\n        int pi = p/N, pj = p%N;\n        int ci = cur/N, cj = cur%N;\n        if (ci == pi+1) path += 'D';\n        else if (ci == pi-1) path += 'U';\n        else if (cj == pj+1) path += 'R';\n        else path += 'L';\n        cur = p;\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 >> N >> si >> sj;\n    c.resize(N);\n    for (int i=0; i<N; i++) cin >> c[i];\n    buildGraph();\n    \n    // Collect road cells and visibility\n    vector<pair<int,int>> roadCells;\n    vector<vector<vector<pair<int,int>>>> visible(N, vector<vector<pair<int,int>>>(N));\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        roadCells.push_back({i,j});\n        for (int nj=j-1; nj>=0 && c[i][nj]!='#'; nj--) visible[i][j].push_back({i,nj});\n        for (int nj=j+1; nj<N && c[i][nj]!='#'; nj++) visible[i][j].push_back({i,nj});\n        for (int ni=i-1; ni>=0 && c[ni][j]!='#'; ni--) visible[i][j].push_back({ni,j});\n        for (int ni=i+1; ni<N && c[ni][j]!='#'; ni++) visible[i][j].push_back({ni,j});\n    }\n    int R = roadCells.size();\n    map<pair<int,int>, int> cellToIdx;\n    for (int i=0; i<R; i++) cellToIdx[roadCells[i]] = i;\n    \n    // Count how many unseen cells each cell can reveal\n    vector<vector<int>> revealCount(N, vector<int>(N, 0));\n    vector<vector<bool>> seen(N, vector<bool>(N, false));\n    \n    // Initialize with start\n    seen[si][sj] = true;\n    for (auto [vi,vj] : visible[si][sj]) seen[vi][vj] = true;\n    \n    // Precompute initial reveal counts\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#') {\n        int cnt = 0;\n        for (auto [vi,vj] : visible[i][j]) if (!seen[vi][vj]) cnt++;\n        if (i==si && j==sj) cnt = 0; // already visited\n        revealCount[i][j] = cnt;\n    }\n    \n    int cur_i = si, cur_j = sj;\n    vector<pair<int,int>> visited;\n    visited.push_back({si,sj});\n    \n    while (true) {\n        // BFS distances from current\n        vector<vector<int>> dist(N, vector<int>(N, 1e9));\n        queue<pair<int,int>> q;\n        dist[cur_i][cur_j] = 0;\n        q.push({cur_i,cur_j});\n        while (!q.empty()) {\n            auto [i,j] = q.front(); q.pop();\n            for (int d=0; d<4; d++) {\n                int ni = i+di[d], nj = j+dj[d];\n                if (ni>=0 && ni<N && nj>=0 && nj<N && c[ni][nj]!='#' && dist[ni][nj] > dist[i][j]+1) {\n                    dist[ni][nj] = dist[i][j]+1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        \n        // Find best cell: prefer cells with high reveal count, then by distance\n        int bestDist = 1e9, bestReveal = -1, bestI = -1, bestJ = -1;\n        for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n            if (c[i][j]!='#' && !seen[i][j] && revealCount[i][j] > 0) {\n                // Only consider cells that actually reveal something new\n                if (bestI == -1 || \n                    revealCount[i][j] > bestReveal || \n                    (revealCount[i][j] == bestReveal && dist[i][j] < bestDist)) {\n                    bestReveal = revealCount[i][j];\n                    bestDist = dist[i][j];\n                    bestI = i; bestJ = j;\n                }\n            }\n        }\n        \n        // If no cell reveals anything new, just pick the closest unseen cell\n        if (bestI == -1) {\n            for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n                if (c[i][j]!='#' && !seen[i][j] && dist[i][j] < bestDist) {\n                    bestDist = dist[i][j];\n                    bestI = i; bestJ = j;\n                }\n            }\n        }\n        \n        if (bestI == -1) break;\n        \n        cur_i = bestI; cur_j = bestJ;\n        visited.push_back({cur_i,cur_j});\n        seen[cur_i][cur_j] = true;\n        for (auto [vi,vj] : visible[cur_i][cur_j]) seen[vi][vj] = true;\n        \n        // Update reveal counts\n        for (int i=0; i<N; i++) for (int j=0; j<N; j++) if (c[i][j]!='#' && !seen[i][j]) {\n            int cnt = 0;\n            for (auto [vi,vj] : visible[i][j]) if (!seen[vi][vj]) cnt++;\n            revealCount[i][j] = cnt;\n        }\n    }\n    \n    int M = visited.size();\n    // Precompute Dijkstra from each visited cell\n    vector<vector<int>> distMat(M, vector<int>(M, 1e9));\n    vector<vector<int>> parentMat(M);\n    for (int i=0; i<M; i++) {\n        int id = visited[i].first*N + visited[i].second;\n        auto [dist, parent] = dijkstraWithParent(id);\n        parentMat[i] = parent;\n        for (int j=0; j<M; j++) {\n            int jid = visited[j].first*N + visited[j].second;\n            distMat[i][j] = dist[jid];\n        }\n    }\n    \n    // Initial order (BFS-based)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    \n    // 2-opt optimization\n    for (int pass = 0; pass < 3; pass++) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i=0; i+2 < M; i++) {\n                for (int j=i+2; j+1 < M; j++) {\n                    long long before = distMat[order[i]][order[i+1]] + distMat[order[j]][order[j+1]];\n                    long long after = distMat[order[i]][order[j]] + distMat[order[i+1]][order[j+1]];\n                    if (after < before) {\n                        reverse(order.begin()+i+1, order.begin()+j+1);\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Build final path\n    string ans;\n    for (int k = 0; k+1 < M; k++) {\n        int fromIdx = order[k];\n        int toIdx = order[k+1];\n        int fromId = visited[fromIdx].first * N + visited[fromIdx].second;\n        int toId = visited[toIdx].first * N + visited[toIdx].second;\n        ans += reconstruct(fromId, toId, parentMat[fromIdx]);\n    }\n    \n    // Return to start\n    int lastIdx = order.back();\n    int lastId = visited[lastIdx].first * N + visited[lastIdx].second;\n    int startId = si * N + sj;\n    ans += reconstruct(lastId, startId, parentMat[lastIdx]);\n    \n    cout << ans << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\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>> diff(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < K; j++)\n            cin >> diff[i][j];\n    \n    vector<vector<int>> deps(N);\n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        deps[v-1].push_back(u-1);\n    }\n    \n    // State\n    vector<int> status(N, 0);\n    vector<int> worker_free_day(M, 0);\n    vector<int> worker_task(M, -1);\n    vector<vector<int>> skills(M, vector<int>(K, 30));\n    \n    for (int day = 1; day <= 2000; day++) {\n        // Assign tasks to available workers\n        int assign_cnt = 0;\n        int assign_buf[20][2];\n        bool worker_used[20] = {false};\n        \n        // Try to assign tasks in order (respects topological order naturally)\n        for (int t = 0; t < N && assign_cnt < M; t++) {\n            if (status[t] != 0) continue;\n            \n            // Check dependencies\n            bool ok = true;\n            for (int dep : deps[t]) {\n                if (status[dep] != 2) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (!ok) continue;\n            \n            // Find best available worker\n            int best_w = -1;\n            int best_est = INT_MAX;\n            \n            for (int w = 0; w < M; w++) {\n                if (worker_free_day[w] >= day) continue;\n                if (worker_task[w] >= 0) continue;\n                if (worker_used[w]) continue;\n                \n                int est = 1;\n                for (int k = 0; k < K; k++) {\n                    int gap = diff[t][k] - skills[w][k];\n                    if (gap > 0) est += gap;\n                }\n                \n                if (est < best_est) {\n                    best_est = est;\n                    best_w = w;\n                }\n            }\n            \n            if (best_w >= 0) {\n                assign_buf[assign_cnt][0] = best_w;\n                assign_buf[assign_cnt][1] = t;\n                assign_cnt++;\n                \n                worker_used[best_w] = true;\n                status[t] = 1;\n                worker_task[best_w] = t;\n                worker_free_day[best_w] = day + best_est;\n            }\n        }\n        \n        // Output\n        cout << assign_cnt;\n        for (int i = 0; i < assign_cnt; i++) {\n            cout << ' ' << assign_buf[i][0] + 1 << ' ' << assign_buf[i][1] + 1;\n        }\n        cout << '\\n' << flush;\n        \n        // Read completions\n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int w;\n            cin >> w;\n            w--;\n            \n            int t = worker_task[w];\n            if (t >= 0) {\n                status[t] = 2;\n                \n                // Update skills\n                for (int k = 0; k < K; k++) {\n                    if (diff[t][k] > skills[w][k]) {\n                        skills[w][k] = (skills[w][k] + diff[t][k] + 1) / 2;\n                    } else {\n                        skills[w][k] = max(skills[w][k], diff[t][k]);\n                    }\n                }\n                \n                worker_task[w] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <random>\nusing namespace std;\n\nconst int DEPOT_X = 400, DEPOT_Y = 400;\nconst int N_ORDERS = 1000;\nconst int PICK = 50;\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nstruct Order {\n    int a, b, c, d;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<Order> orders(N_ORDERS);\n    for (int i = 0; i < N_ORDERS; ++i) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n    }\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    // Select 50 orders\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < N_ORDERS; ++i) {\n        int rt = manhattan(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b)\n               + manhattan(orders[i].a, orders[i].b, orders[i].c, orders[i].d)\n               + manhattan(orders[i].c, orders[i].d, DEPOT_X, DEPOT_Y);\n        candidates.emplace_back(rt, i);\n    }\n    sort(candidates.begin(), candidates.end());\n    \n    vector<int> selectedIdx(PICK);\n    for (int i = 0; i < PICK; ++i) {\n        selectedIdx[i] = candidates[i].second;\n    }\n\n    // Build nodes: restaurant then destination for each selected order\n    struct Node {\n        int x, y;\n        int orderIdx; // index in selectedIdx (0..PICK-1)\n        bool isRestaurant;\n    };\n    vector<Node> nodes(2 * PICK);\n    for (int i = 0; i < PICK; ++i) {\n        int o = selectedIdx[i];\n        nodes[2*i] = {orders[o].a, orders[o].b, i, true};\n        nodes[2*i+1] = {orders[o].c, orders[o].d, i, false};\n    }\n\n    // Build valid initial route: all restaurants first, then all destinations\n    vector<int> route(2 * PICK);\n    for (int i = 0; i < PICK; ++i) route[i] = 2*i;          // restaurants\n    for (int i = 0; i < PICK; ++i) route[PICK + i] = 2*i+1; // destinations\n    \n    // Shuffle within restaurant group and destination group\n    shuffle(route.begin(), route.begin() + PICK, rng);\n    shuffle(route.begin() + PICK, route.end(), rng);\n\n    auto calcDist = [&](const vector<int>& r) {\n        int total = manhattan(DEPOT_X, DEPOT_Y, nodes[r[0]].x, nodes[r[0]].y);\n        for (int i = 0; i < 2*PICK - 1; ++i) {\n            total += manhattan(nodes[r[i]].x, nodes[r[i]].y, nodes[r[i+1]].x, nodes[r[i+1]].y);\n        }\n        total += manhattan(nodes[r[2*PICK-1]].x, nodes[r[2*PICK-1]].y, DEPOT_X, DEPOT_Y);\n        return total;\n    };\n\n    // Validate that all orders are properly completed\n    auto isValid = [&](const vector<int>& r) {\n        vector<int> restPos(PICK, -1), destPos(PICK, -1);\n        for (int i = 0; i < 2*PICK; ++i) {\n            if (nodes[r[i]].isRestaurant) restPos[nodes[r[i]].orderIdx] = i;\n            else destPos[nodes[r[i]].orderIdx] = i;\n        }\n        for (int i = 0; i < PICK; ++i) {\n            if (restPos[i] == -1 || destPos[i] == -1) return false;\n            if (restPos[i] >= destPos[i]) return false;\n        }\n        return true;\n    };\n\n    // Always valid because each order has restaurant before destination\n    assert(isValid(route));\n\n    int bestT = calcDist(route);\n    vector<int> bestRoute = route;\n\n    // 2-opt local search with strict precedence preservation\n    for (int restart = 0; restart < 5; ++restart) {\n        // Shuffle but keep restaurants before destinations\n        shuffle(route.begin(), route.begin() + PICK, rng);\n        shuffle(route.begin() + PICK, route.end(), rng);\n        \n        int curT = calcDist(route);\n        bool improved = true;\n        \n        while (improved) {\n            improved = false;\n            for (int i = 0; i < 2*PICK - 1; ++i) {\n                for (int j = i + 1; j < 2*PICK; ++j) {\n                    // Strict check: reversal cannot put any destination before its restaurant\n                    bool ok = true;\n                    for (int k = i; k <= j; ++k) {\n                        int other = j - (k - i);\n                        if (nodes[route[k]].isRestaurant && !nodes[route[other]].isRestaurant) {\n                            // Restaurant moving to destination's old position\n                            // Check if its destination is also in segment\n                            auto& rnode = nodes[route[k]];\n                            auto& dnode = nodes[route[other]];\n                            if (rnode.orderIdx == dnode.orderIdx) { ok = false; break; }\n                        } else if (!nodes[route[k]].isRestaurant && nodes[route[other]].isRestaurant) {\n                            // Destination moving to restaurant's old position\n                            auto& dnode = nodes[route[k]];\n                            auto& rnode = nodes[route[other]];\n                            if (dnode.orderIdx == rnode.orderIdx) { ok = false; break; }\n                        }\n                    }\n                    if (!ok) continue;\n                    \n                    // Compute delta distance\n                    int oldDist = 0, newDist = 0;\n                    if (i > 0) {\n                        oldDist += manhattan(nodes[route[i-1]].x, nodes[route[i-1]].y, nodes[route[i]].x, nodes[route[i]].y);\n                        newDist += manhattan(nodes[route[i-1]].x, nodes[route[i-1]].y, nodes[route[j]].x, nodes[route[j]].y);\n                    }\n                    if (j < 2*PICK - 1) {\n                        oldDist += manhattan(nodes[route[j]].x, nodes[route[j]].y, nodes[route[j+1]].x, nodes[route[j+1]].y);\n                        newDist += manhattan(nodes[route[i]].x, nodes[route[i]].y, nodes[route[j+1]].x, nodes[route[j+1]].y);\n                    }\n                    \n                    if (curT - oldDist + newDist >= curT) continue;\n                    \n                    // Apply reversal\n                    reverse(route.begin() + i, route.begin() + j + 1);\n                    curT = curT - oldDist + newDist;\n                    improved = true;\n                    break; // Only one improvement per iteration\n                }\n                if (improved) break;\n            }\n        }\n        \n        if (curT < bestT) {\n            bestT = curT;\n            bestRoute = route;\n        }\n    }\n\n    // Final validation\n    if (!isValid(bestRoute)) {\n        // Fallback: simple route with all restaurants first\n        bestRoute.resize(2*PICK);\n        for (int i = 0; i < PICK; ++i) bestRoute[i] = 2*i;\n        for (int i = 0; i < PICK; ++i) bestRoute[PICK + i] = 2*i+1;\n    }\n\n    // Output\n    cout << PICK;\n    for (int idx : selectedIdx) cout << \" \" << idx + 1;\n    cout << \"\\n\";\n    \n    cout << 2*PICK + 2 << \" \" << DEPOT_X << \" \" << DEPOT_Y;\n    for (int idx : bestRoute) cout << \" \" << nodes[idx].x << \" \" << nodes[idx].y;\n    cout << \" \" << DEPOT_X << \" \" << DEPOT_Y << \"\\n\";\n\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\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    vector<pair<int,int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges\n    vector<tuple<int,int,int>> edges(M);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges[i] = {u, v, i};\n    }\n    \n    // Precompute Euclidean distances\n    vector<int> euclidean_dist(M);\n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        euclidean_dist[i] = (int)round(sqrt(dx*dx + dy*dy));\n    }\n    \n    // Compute multiple MST candidates with different perturbations\n    const int NUM_MST = 7;  // Use more MSTs for better consensus\n    vector<vector<int>> mst_membership(M, vector<int>(NUM_MST, 0));\n    \n    for (int trial = 0; trial < NUM_MST; trial++) {\n        vector<tuple<int,int,int>> all_pairs;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                double dx = coords[i].first - coords[j].first;\n                double dy = coords[i].second - coords[j].second;\n                int d = (int)round(sqrt(dx*dx + dy*dy));\n                // Use primes for perturbation to get diverse MSTs\n                int perturb = ((trial + 1) * 10007 + i * 10009 + j * 10013) % 5;\n                all_pairs.push_back({d + perturb, i, j});\n            }\n        }\n        sort(all_pairs.begin(), all_pairs.end());\n        \n        dsu mst_dsu(N);\n        vector<vector<bool>> in_mst(N, vector<bool>(N, false));\n        \n        for (auto [d, i, j] : all_pairs) {\n            if (!mst_dsu.same(i, j)) {\n                mst_dsu.merge(i, j);\n                in_mst[i][j] = true;\n                in_mst[j][i] = true;\n                if (mst_dsu.groups().size() == 1) break;\n            }\n        }\n        \n        for (int k = 0; k < M; k++) {\n            auto [u, v, idx] = edges[k];\n            if (in_mst[u][v]) {\n                mst_membership[k][trial] = 1;\n            }\n        }\n    }\n    \n    // Compute MST consensus score for each edge\n    vector<int> mst_count(M, 0);\n    vector<double> mst_score(M, 0.0);\n    for (int i = 0; i < M; i++) {\n        for (int t = 0; t < NUM_MST; t++) {\n            mst_count[i] += mst_membership[i][t];\n        }\n        mst_score[i] = (double)mst_count[i] / NUM_MST;\n    }\n    \n    // Initialize DSU for tracking adopted edges\n    dsu dsu_uf(N);\n    \n    // Track statistics\n    double running_sum = 0;\n    int count = 0;\n    \n    for (int i = 0; i < M; i++) {\n        auto [u, v, idx] = edges[i];\n        \n        // Read actual cost\n        long long actual_cost;\n        cin >> actual_cost;\n        \n        // Update statistics\n        double ratio = (double)actual_cost / euclidean_dist[i];\n        running_sum += ratio;\n        count++;\n        double avg_ratio = count > 0 ? running_sum / count : 2.0;\n        \n        // If already connected, reject immediately\n        if (dsu_uf.same(u, v)) {\n            cout << 0 << endl;\n            continue;\n        }\n        \n        int components = dsu_uf.groups().size();\n        int edges_needed = components - 1;\n        int remaining = M - i - 1;\n        \n        // Fast connectivity check\n        bool can_connect_without = true;\n        {\n            dsu check_uf = dsu_uf;\n            int merges_needed = edges_needed;\n            int merges_done = 0;\n            \n            for (int j = i + 1; j < M && merges_done < merges_needed; j++) {\n                auto [uj, vj, idxj] = edges[j];\n                if (!check_uf.same(uj, vj)) {\n                    check_uf.merge(uj, vj);\n                    merges_done++;\n                }\n            }\n            can_connect_without = (check_uf.groups().size() == 1);\n        }\n        \n        bool accept = false;\n        \n        // Compute edge importance based on MST consensus and distance\n        double importance = mst_score[i] * (1.0 - (double)euclidean_dist[i] / 800.0);\n        \n        if (!can_connect_without) {\n            // MUST accept this edge\n            accept = true;\n        }\n        // Very high MST consensus (appears in 6+ of 7 MSTs)\n        else if (mst_count[i] >= 6 && ratio <= 2.0) {\n            accept = true;\n        }\n        // High MST consensus\n        else if (mst_count[i] >= 5 && ratio <= 1.8) {\n            accept = true;\n        }\n        // Moderate-high consensus\n        else if (mst_count[i] >= 4 && ratio <= 1.6) {\n            accept = true;\n        }\n        // Moderate consensus\n        else if (mst_count[i] >= 3 && ratio <= 1.4) {\n            accept = true;\n        }\n        // Excellent deal (regardless of MST status)\n        else if (ratio <= 1.1) {\n            accept = true;\n        }\n        // Very good deal\n        else if (ratio <= 1.2 && euclidean_dist[i] < 150) {\n            accept = true;\n        }\n        // Short edges are extremely valuable for MST quality\n        else if (euclidean_dist[i] < 30 && ratio <= 1.6) {\n            accept = true;\n        }\n        else if (euclidean_dist[i] < 50 && ratio <= 1.4) {\n            accept = true;\n        }\n        else if (euclidean_dist[i] < 80 && ratio <= 1.3) {\n            accept = true;\n        }\n        else if (euclidean_dist[i] < 120 && ratio <= 1.2) {\n            accept = true;\n        }\n        // Accept if running out of options (with cost consideration)\n        else if (remaining < edges_needed * 2) {\n            if (ratio <= 2.0) accept = true;\n        }\n        else if (remaining < edges_needed * 3) {\n            if (ratio <= 1.7 && euclidean_dist[i] < 150) accept = true;\n        }\n        else if (remaining < edges_needed * 5) {\n            if (ratio <= 1.5 && euclidean_dist[i] < 100) accept = true;\n        }\n        // If ratio is significantly below average, consider accepting\n        else if (ratio < avg_ratio * 0.8 && importance > 0.3) {\n            accept = true;\n        }\n        \n        if (accept) {\n            dsu_uf.merge(u, v);\n            cout << 1 << endl;\n        } else {\n            cout << 0 << endl;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int SIZE = 30;\nconst int TURNS = 300;\nconst int INF = 1e9;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Position& other) const {\n        return !(*this == other);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;  // Start of turn positions\n    vector<vector<bool>> wall;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char moveChar[4] = {'U', 'D', 'L', 'R'};\n    const char wallChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n    }\n    \n    bool isWall(int x, int y) {\n        if (!isValid(x, y)) return true;\n        return wall[x][y];\n    }\n    \n    bool hasPet(int x, int y) {\n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return true;\n        }\n        return false;\n    }\n    \n    // Check if a position is occupied by any human (start of turn or planned)\n    bool hasHuman(int x, int y, const vector<Position>& currentPositions,\n                  const vector<Position>& plannedPositions) {\n        // Check start of turn positions\n        for (const auto& h : currentPositions) {\n            if (h.x == x && h.y == y) return true;\n        }\n        // Check positions humans are moving to this turn\n        for (const auto& p : plannedPositions) {\n            if (p.x == x && p.y == y) return true;\n        }\n        return false;\n    }\n    \n    // Check if a position is occupied by any human (start of turn only)\n    bool hasHumanAtStart(int x, int y) {\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return true;\n        }\n        return false;\n    }\n    \n    bool canPlaceWallAt(int x, int y, const vector<vector<bool>>& tempWalls,\n                        const vector<Position>& currentPositions,\n                        const vector<Position>& plannedPositions) {\n        if (!isValid(x, y) || wall[x][y] || tempWalls[x][y]) return false;\n        \n        // Can't place wall on pets\n        if (hasPet(x, y)) return false;\n        \n        // Can't place wall on humans (start of turn)\n        if (hasHumanAtStart(x, y)) return false;\n        \n        // Can't place wall where a human is moving to this turn\n        for (const auto& p : plannedPositions) {\n            if (p.x == x && p.y == y) return false;\n        }\n        \n        // Can't place wall adjacent to pets\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && hasPet(nx, ny)) {\n                return false;\n            }\n        }\n        \n        return true;\n    }\n    \n    bool canMoveTo(int x, int y, const vector<vector<bool>>& tempWalls,\n                   const vector<Position>& plannedPositions) {\n        if (!isValid(x, y)) return false;\n        if (wall[x][y] || tempWalls[x][y]) return false;\n        \n        // Can't move to a square another human is moving to\n        for (const auto& p : plannedPositions) {\n            if (p.x == x && p.y == y) return false;\n        }\n        \n        return true;\n    }\n    \n    // Find best wall position for a human\n    Position findBestWallPosition(int humanIdx, const vector<vector<bool>>& tempWalls,\n                                   const vector<Position>& currentPositions,\n                                   const vector<Position>& plannedPositions) {\n        auto& human = currentPositions[humanIdx];\n        double bestScore = -INF;\n        Position bestPos = {-1, -1};\n        \n        // Search in concentric squares around the human\n        for (int radius = 1; radius <= 10; radius++) {\n            for (int x = max(0, human.x - radius); x <= min(SIZE-1, human.x + radius); x++) {\n                // Check top and bottom rows\n                for (int sign = -1; sign <= 1; sign += 2) {\n                    int y = human.y + sign * radius;\n                    if (y >= 0 && y < SIZE && abs(x - human.x) <= radius) {\n                        if (canPlaceWallAt(x, y, tempWalls, currentPositions, plannedPositions)) {\n                            double score = evaluateWall(x, y, currentPositions);\n                            if (score > bestScore) {\n                                bestScore = score;\n                                bestPos = {x, y};\n                            }\n                        }\n                    }\n                }\n            }\n            for (int y = max(0, human.y - radius + 1); y <= min(SIZE-1, human.y + radius - 1); y++) {\n                // Check left and right columns\n                for (int sign = -1; sign <= 1; sign += 2) {\n                    int x = human.x + sign * radius;\n                    if (x >= 0 && x < SIZE) {\n                        if (canPlaceWallAt(x, y, tempWalls, currentPositions, plannedPositions)) {\n                            double score = evaluateWall(x, y, currentPositions);\n                            if (score > bestScore) {\n                                bestScore = score;\n                                bestPos = {x, y};\n                            }\n                        }\n                    }\n                }\n            }\n            if (bestScore > 100) break; // Found excellent position\n        }\n        \n        return bestPos;\n    }\n    \n    double evaluateWall(int x, int y, const vector<Position>& currentPositions) {\n        double score = 0;\n        \n        // Calculate center of humans\n        int cx = 0, cy = 0;\n        for (const auto& h : currentPositions) {\n            cx += h.x;\n            cy += h.y;\n        }\n        cx /= M;\n        cy /= M;\n        \n        // Distance from center\n        int distFromCenter = abs(x - cx) + abs(y - cy);\n        \n        // Ideal distance for enclosure (not too close, not too far)\n        if (distFromCenter >= 4 && distFromCenter <= 8) {\n            score += 200;\n        } else if (distFromCenter >= 2 && distFromCenter <= 12) {\n            score += 100;\n        }\n        \n        // Prefer walls close to humans (easier to reach)\n        for (const auto& h : currentPositions) {\n            double dist = sqrt((x - h.x) * (x - h.x) + (y - h.y) * (y - h.y));\n            score += 20.0 / (1 + dist);\n        }\n        \n        // Avoid walls too close to pets\n        for (const auto& p : petPos) {\n            double dist = sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));\n            if (dist < 3) score -= 500;\n            else if (dist < 5) score -= 100;\n        }\n        \n        // Prefer walls that are adjacent to existing walls (continuity)\n        int adjacentWalls = 0;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny) && wall[nx][ny]) adjacentWalls++;\n        }\n        score += adjacentWalls * 50;\n        \n        return score;\n    }\n    \n    char getNextMove(const Position& from, const Position& to,\n                     const vector<vector<bool>>& tempWalls,\n                     const vector<Position>& plannedPositions) {\n        if (from == to) return '.';\n        \n        // Simple greedy: move in direction that reduces distance\n        vector<pair<int, char>> possibleMoves;\n        \n        // Try direct directions first\n        if (to.x < from.x) possibleMoves.push_back({0, 'U'});\n        if (to.x > from.x) possibleMoves.push_back({1, 'D'});\n        if (to.y < from.y) possibleMoves.push_back({2, 'L'});\n        if (to.y > from.y) possibleMoves.push_back({3, 'R'});\n        \n        // Filter valid moves\n        for (auto& move : possibleMoves) {\n            int nx = from.x;\n            int ny = from.y;\n            if (move.second == 'U') nx--;\n            else if (move.second == 'D') nx++;\n            else if (move.second == 'L') ny--;\n            else if (move.second == 'R') ny++;\n            \n            if (!canMoveTo(nx, ny, tempWalls, plannedPositions)) {\n                move.first = -1;\n            }\n        }\n        \n        // Choose first valid move\n        for (auto& move : possibleMoves) {\n            if (move.first != -1) return move.second;\n        }\n        \n        // Try orthogonal directions as fallback\n        possibleMoves.clear();\n        if (canMoveTo(from.x - 1, from.y, tempWalls, plannedPositions))\n            possibleMoves.push_back({0, 'U'});\n        if (canMoveTo(from.x + 1, from.y, tempWalls, plannedPositions))\n            possibleMoves.push_back({1, 'D'});\n        if (canMoveTo(from.x, from.y - 1, tempWalls, plannedPositions))\n            possibleMoves.push_back({2, 'L'});\n        if (canMoveTo(from.x, from.y + 1, tempWalls, plannedPositions))\n            possibleMoves.push_back({3, 'R'});\n        \n        if (!possibleMoves.empty()) {\n            // Prefer move that gets closer to target\n            auto best = possibleMoves[0];\n            int bestDist = INF;\n            for (auto& move : possibleMoves) {\n                int nx = from.x;\n                int ny = from.y;\n                if (move.second == 'U') nx--;\n                else if (move.second == 'D') nx++;\n                else if (move.second == 'L') ny--;\n                else if (move.second == 'R') ny++;\n                int dist = abs(nx - to.x) + abs(ny - to.y);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    best = move;\n                }\n            }\n            return best.second;\n        }\n        \n        return '.';\n    }\n    \npublic:\n    Solver() {\n        wall = vector<vector<bool>>(SIZE, vector<bool>(SIZE, false));\n    }\n    \n    void readInput() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n            petPos[i].x--;\n            petPos[i].y--;\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n            humanPos[i].x--;\n            humanPos[i].y--;\n        }\n    }\n    \n    void solve() {\n        for (int turn = 0; turn < TURNS; turn++) {\n            string output;\n            vector<vector<bool>> tempWalls(SIZE, vector<bool>(SIZE, false));\n            vector<Position> plannedPositions;  // Where humans will be after this turn\n            vector<Position> currentPositions = humanPos;  // Start of turn positions\n            \n            for (int i = 0; i < M; i++) {\n                char action = '.';\n                auto& human = humanPos[i];\n                \n                // Find best wall position\n                Position wallTarget = findBestWallPosition(i, tempWalls, currentPositions, plannedPositions);\n                \n                if (wallTarget.x != -1) {\n                    int dist = abs(wallTarget.x - human.x) + abs(wallTarget.y - human.y);\n                    \n                    if (dist == 1) {\n                        // Adjacent to wall position - place the wall\n                        for (int d = 0; d < 4; d++) {\n                            if (human.x + dx[d] == wallTarget.x && human.y + dy[d] == wallTarget.y) {\n                                if (canPlaceWallAt(wallTarget.x, wallTarget.y, tempWalls, currentPositions, plannedPositions)) {\n                                    action = wallChar[d];\n                                    tempWalls[wallTarget.x][wallTarget.y] = true;\n                                }\n                                break;\n                            }\n                        }\n                    } else {\n                        // Need to move closer\n                        action = getNextMove(human, wallTarget, tempWalls, plannedPositions);\n                    }\n                }\n                \n                // If no action determined, try to stay safe and maybe build a nearby wall\n                if (action == '.') {\n                    // Try to find an adjacent wall to build\n                    for (int d = 0; d < 4; d++) {\n                        int nx = human.x + dx[d];\n                        int ny = human.y + dy[d];\n                        if (canPlaceWallAt(nx, ny, tempWalls, currentPositions, plannedPositions)) {\n                            action = wallChar[d];\n                            tempWalls[nx][ny] = true;\n                            break;\n                        }\n                    }\n                }\n                \n                // If still no action, move to expand territory\n                if (action == '.') {\n                    // Try to move in any valid direction\n                    if (canMoveTo(human.x - 1, human.y, tempWalls, plannedPositions)) action = 'U';\n                    else if (canMoveTo(human.x + 1, human.y, tempWalls, plannedPositions)) action = 'D';\n                    else if (canMoveTo(human.x, human.y - 1, tempWalls, plannedPositions)) action = 'L';\n                    else if (canMoveTo(human.x, human.y + 1, tempWalls, plannedPositions)) action = 'R';\n                }\n                \n                output += action;\n                \n                // Track planned position\n                Position plannedPos = human;\n                if (action == 'U') plannedPos.x--;\n                else if (action == 'D') plannedPos.x++;\n                else if (action == 'L') plannedPos.y--;\n                else if (action == 'R') plannedPos.y++;\n                plannedPositions.push_back(plannedPos);\n            }\n            \n            // Apply all walls\n            for (int x = 0; x < SIZE; x++) {\n                for (int y = 0; y < SIZE; y++) {\n                    if (tempWalls[x][y]) {\n                        wall[x][y] = true;\n                    }\n                }\n            }\n            \n            // Update human positions\n            for (int i = 0; i < M; i++) {\n                char action = output[i];\n                if (action == 'U') humanPos[i].x--;\n                else if (action == 'D') humanPos[i].x++;\n                else if (action == 'L') humanPos[i].y--;\n                else if (action == 'R') humanPos[i].y++;\n                // Wall placing actions don't change position\n            }\n            \n            // Output\n            cout << output << endl;\n            cout.flush();\n            \n            // Read pet movements\n            string line;\n            getline(cin, line);\n            if (line.empty()) {\n                getline(cin, line);\n            }\n            \n            vector<string> petMovements(N);\n            stringstream ss(line);\n            for (int i = 0; i < N; i++) {\n                ss >> petMovements[i];\n            }\n            \n            // Update pet positions\n            for (int i = 0; i < N; i++) {\n                for (char c : petMovements[i]) {\n                    if (c == 'U') petPos[i].x--;\n                    else if (c == 'D') petPos[i].x++;\n                    else if (c == 'L') petPos[i].y--;\n                    else if (c == 'R') petPos[i].y++;\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.readInput();\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> h, v;\n    \n    bool canMove(int i, int j, int d) const {\n        if (d == 0 && i > 0 && !v[i-1][j]) return true;\n        if (d == 1 && i < 19 && !v[i][j]) return true;\n        if (d == 2 && j > 0 && !h[i][j-1]) return true;\n        if (d == 3 && j < 19 && !h[i][j]) return true;\n        return false;\n    }\n};\n\n// Full DP for expected score\ndouble calculateExpectedScore(const string& s, int si, int sj, int ti, int tj,\n                             const Grid& grid, double p) {\n    const int L = min((int)s.size(), 400);\n    vector<double> dp(400, 0.0);\n    dp[si * 20 + sj] = 1.0;\n    double expected = 0.0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dirs[] = {'U', 'D', 'L', 'R'};\n    \n    for (int step = 0; step < L; ++step) {\n        vector<double> ndp(400, 0.0);\n        double goalProb = 0.0;\n        \n        for (int idx = 0; idx < 400; ++idx) {\n            if (dp[idx] < 1e-12) continue;\n            int i = idx / 20, j = idx % 20;\n            \n            if (i == ti && j == tj) {\n                goalProb += dp[idx];\n                continue;\n            }\n            \n            ndp[idx] += dp[idx] * p;\n            \n            int d = 0;\n            for (; d < 4; ++d) if (s[step] == dirs[d]) break;\n            if (grid.canMove(i, j, d)) {\n                ndp[(i + di[d]) * 20 + (j + dj[d])] += dp[idx] * (1.0 - p);\n            } else {\n                ndp[idx] += dp[idx] * (1.0 - p);\n            }\n        }\n        \n        expected += goalProb * (401.0 - step);\n        dp = ndp;\n    }\n    \n    return expected;\n}\n\n// Compute distance to goal from all positions\nvector<vector<int>> computeDistToGoal(int ti, int tj, const Grid& grid) {\n    const int INF = 1e9;\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \n    vector<vector<int>> dist(20, vector<int>(20, INF));\n    queue<pair<int,int>> q;\n    q.push({ti, tj});\n    dist[ti][tj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; ++d) {\n            int revd = (d == 0) ? 1 : (d == 1) ? 0 : (d == 2) ? 3 : 2;\n            if (!grid.canMove(i, j, revd)) continue;\n            int ni = i + di[revd], nj = j + dj[revd];\n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    return dist;\n}\n\n// Count bottlenecks in the path\nint countBottlenecks(const vector<char>& path, int si, int sj,\n                    const vector<vector<int>>& distToGoal, const Grid& grid) {\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    int bottlenecks = 0;\n    \n    for (int i = 0; i < (int)path.size(); ++i) {\n        int px = si, py = sj;\n        for (int j = 0; j < i; ++j) {\n            int d = 0;\n            if (path[j] == 'U') d = 0;\n            else if (path[j] == 'D') d = 1;\n            else if (path[j] == 'L') d = 2;\n            else d = 3;\n            if (grid.canMove(px, py, d)) {\n                px += di[d]; py += dj[d];\n            }\n        }\n        \n        int alternatives = 0;\n        for (int d = 0; d < 4; ++d) {\n            if (!grid.canMove(px, py, d)) continue;\n            int nx = px + di[d], ny = py + dj[d];\n            if (distToGoal[nx][ny] < distToGoal[px][py]) {\n                alternatives++;\n            }\n        }\n        if (alternatives <= 1) bottlenecks++;\n    }\n    \n    return bottlenecks;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    Grid grid;\n    grid.h.resize(20, vector<int>(19));\n    grid.v.resize(19, vector<int>(20));\n    \n    for (int i = 0; i < 20; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 19; ++j) grid.h[i][j] = s[j] - '0';\n    }\n    for (int i = 0; i < 19; ++i) {\n        string s; cin >> s;\n        for (int j = 0; j < 20; ++j) grid.v[i][j] = s[j] - '0';\n    }\n    \n    // BFS for shortest path\n    const int INF = 1e9;\n    vector<vector<int>> dist(20, vector<int>(20, INF));\n    vector<vector<pair<int,int>>> prev(20, vector<pair<int,int>>(20, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj] = 0;\n    q.push({si, sj});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dir_char[] = {'U', 'D', 'L', 'R'};\n    \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            if (!grid.canMove(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                prev[ni][nj] = {i, j};\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<char> path;\n    int ci = ti, cj = tj;\n    while (!(ci == si && cj == sj)) {\n        auto [pi, pj] = prev[ci][cj];\n        if (pi == ci - 1) path.push_back('D');\n        else if (pi == ci + 1) path.push_back('U');\n        else if (pj == cj - 1) path.push_back('R');\n        else path.push_back('L');\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    \n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    int pathLen = (int)path.size();\n    auto distToGoal = computeDistToGoal(ti, tj, grid);\n    \n    const int maxLen = 200;\n    int baseRepeat = max(1, (int)(1.0 / (1.0 - p) + 0.5));\n    \n    // Detect if this is a bottleneck map\n    int bottlenecks = countBottlenecks(path, si, sj, distToGoal, grid);\n    bool isBottleneckMap = (bottlenecks > pathLen * 0.3); // >30% positions are bottlenecks\n    \n    string bestPath;\n    double bestScore = -1.0;\n    \n    // Strategy 1: Uniform repetition (baseline)\n    for (int rep = max(1, baseRepeat - 1); rep <= baseRepeat + 3; ++rep) {\n        string candidate;\n        candidate.reserve(maxLen);\n        for (char c : path) {\n            for (int r = 0; r < rep && candidate.size() < (size_t)maxLen; ++r) {\n                candidate.push_back(c);\n            }\n        }\n        while (candidate.size() < (size_t)maxLen && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n        \n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Strategy 2: Pattern-based repetition (windows 1-5)\n    for (int window : {1, 2, 3, 4, 5}) {\n        for (int rep : {1, 2, 3}) {\n            string candidate;\n            candidate.reserve(maxLen);\n            for (int i = 0; i < pathLen && candidate.size() < (size_t)maxLen; i += window) {\n                string pattern;\n                for (int w = 0; w < window && i + w < pathLen; ++w) {\n                    pattern += path[i + w];\n                }\n                for (int r = 0; r < rep && candidate.size() + pattern.size() <= (size_t)maxLen; ++r) {\n                    candidate += pattern;\n                }\n            }\n            while (candidate.size() < (size_t)maxLen && !path.empty()) {\n                candidate.push_back(path.back());\n            }\n            if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n            \n            double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n            if (score > bestScore) {\n                bestScore = score;\n                bestPath = candidate;\n            }\n        }\n    }\n    \n    // Strategy 3: Entire path repetition\n    for (int rep : {1, 2, 3}) {\n        string candidate;\n        candidate.reserve(maxLen);\n        for (int r = 0; r < rep && candidate.size() < (size_t)maxLen; ++r) {\n            for (char c : path) {\n                if (candidate.size() < (size_t)maxLen) {\n                    candidate.push_back(c);\n                }\n            }\n        }\n        while (candidate.size() < (size_t)maxLen && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n        \n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Strategy 4: Aggressive repetition for high p\n    if (p > 0.3) {\n        int highRep = (int)(1.5 / (1.0 - p) + 0.5);\n        string candidate;\n        candidate.reserve(maxLen);\n        for (char c : path) {\n            for (int r = 0; r < highRep && candidate.size() < (size_t)maxLen; ++r) {\n                candidate.push_back(c);\n            }\n        }\n        while (candidate.size() < (size_t)maxLen && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n        \n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Strategy 5: Variable repetition based on importance\n    vector<double> importance(pathLen, 1.0);\n    for (int i = 0; i < pathLen; ++i) {\n        int px = si, py = sj;\n        for (int j = 0; j < i; ++j) {\n            int d = 0;\n            if (path[j] == 'U') d = 0;\n            else if (path[j] == 'D') d = 1;\n            else if (path[j] == 'L') d = 2;\n            else d = 3;\n            if (grid.canMove(px, py, d)) {\n                px += di[d]; py += dj[d];\n            }\n        }\n        \n        int alternatives = 0;\n        double curDist = distToGoal[px][py];\n        for (int d = 0; d < 4; ++d) {\n            if (!grid.canMove(px, py, d)) continue;\n            int nx = px + di[d], ny = py + dj[d];\n            if (distToGoal[nx][ny] <= curDist) {\n                alternatives++;\n            }\n        }\n        \n        importance[i] = 1.0 / (alternatives + 0.1);\n        if (i < 5) importance[i] *= 1.5;\n        if (i >= pathLen - 5) importance[i] *= 1.5;\n    }\n    \n    double sumImp = accumulate(importance.begin(), importance.end(), 0.0);\n    for (auto& imp : importance) imp /= sumImp;\n    \n    for (double budgetMult : {0.5, 1.0, 1.5, 2.0, 2.5}) {\n        string candidate;\n        candidate.reserve(maxLen);\n        double remaining = budgetMult * pathLen;\n        \n        for (int i = 0; i < pathLen && candidate.size() < (size_t)maxLen; ++i) {\n            candidate.push_back(path[i]);\n            \n            int extra = (int)(importance[i] * remaining * maxLen / pathLen);\n            extra = min(extra, max(2, baseRepeat + 1));\n            \n            for (int r = 0; r < extra && candidate.size() < (size_t)maxLen; ++r) {\n                candidate.push_back(path[i]);\n            }\n            remaining -= extra;\n        }\n        \n        while (candidate.size() < (size_t)maxLen && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n        \n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Strategy 6: Mixed pattern with variable repeats\n    for (int window : {2, 3, 4}) {\n        for (double baseRep : {0.5, 1.0, 1.5}) {\n            string candidate;\n            candidate.reserve(maxLen);\n            double remaining = baseRep * pathLen;\n            \n            for (int i = 0; i < pathLen && candidate.size() < (size_t)maxLen; i += window) {\n                string pattern;\n                for (int w = 0; w < window && i + w < pathLen; ++w) {\n                    pattern += path[i + w];\n                }\n                \n                int rep = max(1, (int)(importance[i] * remaining * 3.0));\n                rep = min(rep, 3);\n                \n                for (int r = 0; r < rep && candidate.size() + pattern.size() <= (size_t)maxLen; ++r) {\n                    candidate += pattern;\n                }\n            }\n            \n            while (candidate.size() < (size_t)maxLen && !path.empty()) {\n                candidate.push_back(path.back());\n            }\n            if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n            \n            double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n            if (score > bestScore) {\n                bestScore = score;\n                bestPath = candidate;\n            }\n        }\n    }\n    \n    // Strategy 7: Varying target lengths\n    for (int len = pathLen; len <= maxLen; len += 10) {\n        int rep = max(1, len / pathLen);\n        string candidate;\n        candidate.reserve(maxLen);\n        for (char c : path) {\n            for (int r = 0; r < rep && candidate.size() < (size_t)len; ++r) {\n                candidate.push_back(c);\n            }\n        }\n        while (candidate.size() < (size_t)len && !path.empty()) {\n            candidate.push_back(path.back());\n        }\n        if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n        \n        double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n        if (score > bestScore) {\n            bestScore = score;\n            bestPath = candidate;\n        }\n    }\n    \n    // Strategy 8: Bottleneck-specific (only for bottleneck maps)\n    if (isBottleneckMap) {\n        // Extra aggressive repetition at bottlenecks\n        for (int bottleneckRep : {3, 4, 5}) {\n            string candidate;\n            candidate.reserve(maxLen);\n            \n            for (int i = 0; i < pathLen && candidate.size() < (size_t)maxLen; ++i) {\n                candidate.push_back(path[i]);\n                \n                // Check if this position is a bottleneck\n                int px = si, py = sj;\n                for (int j = 0; j < i; ++j) {\n                    int d = 0;\n                    if (path[j] == 'U') d = 0;\n                    else if (path[j] == 'D') d = 1;\n                    else if (path[j] == 'L') d = 2;\n                    else d = 3;\n                    if (grid.canMove(px, py, d)) {\n                        px += di[d]; py += dj[d];\n                    }\n                }\n                \n                int alternatives = 0;\n                for (int d = 0; d < 4; ++d) {\n                    if (!grid.canMove(px, py, d)) continue;\n                    int nx = px + di[d], ny = py + dj[d];\n                    if (distToGoal[nx][ny] < distToGoal[px][py]) {\n                        alternatives++;\n                    }\n                }\n                \n                // Repeat more at bottlenecks\n                int rep = (alternatives <= 1) ? bottleneckRep : 1;\n                for (int r = 1; r < rep && candidate.size() < (size_t)maxLen; ++r) {\n                    candidate.push_back(path[i]);\n                }\n            }\n            \n            while (candidate.size() < (size_t)maxLen && !path.empty()) {\n                candidate.push_back(path.back());\n            }\n            if (candidate.size() > (size_t)maxLen) candidate.resize(maxLen);\n            \n            double score = calculateExpectedScore(candidate, si, sj, ti, tj, grid, p);\n            if (score > bestScore) {\n                bestScore = score;\n                bestPath = candidate;\n            }\n        }\n    }\n    \n    cout << bestPath << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // 0\n    {3, -1, -1, 0},  // 1\n    {-1, -1, 3, 2},  // 2\n    {-1, 2, 1, -1},  // 3\n    {1, 0, 3, 2},    // 4\n    {3, 2, 1, 0},    // 5\n    {2, -1, 0, -1},  // 6\n    {-1, 3, -1, 1},  // 7\n};\n\n// Ultra-fast heuristic: count connected components and their sizes\n// Returns product of two largest components\nint fastHeuristic(const int tiles[30][30]) {\n    bool visited[30][30] = {false};\n    \n    // Count degree of each tile (how many directions it connects)\n    int degreeSum = 0;\n    int goodConnections = 0;\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int deg = 0;\n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] != -1) deg++;\n            }\n            degreeSum += deg;\n            \n            // Check if adjacent tiles connect\n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] == -1) continue;\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni < 0 || ni >= 30 || nj < 0 || nj >= 30) continue;\n                \n                int nd = (to[tiles[i][j]][d] + 2) % 4;\n                if (to[tiles[ni][nj]][nd] != -1) goodConnections++;\n            }\n        }\n    }\n    \n    // Heuristic: good connections / 2 (each connection counted twice)\n    return goodConnections;\n}\n\n// Fast loop tracer - just returns length, no visited marking overhead\nint traceLoopFast(const int tiles[30][30], int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (length < 900) {\n        int d2 = to[tiles[i][j]][d];\n        if (d2 == -1) return 0;\n        \n        i += di[d2];\n        j += dj[d2];\n        if (i < 0 || i >= 30 || j < 0 || j >= 30) return 0;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\n// Compute score for final evaluation only\nlong long computeScore(const int tiles[30][30]) {\n    bool visited[30][30] = {false};\n    int L1 = 0, L2 = 0;\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            if (visited[i][j]) continue;\n            \n            for (int d = 0; d < 4; d++) {\n                if (to[tiles[i][j]][d] == -1) continue;\n                \n                // Quick check: is this a potential loop?\n                int len = traceLoopFast(tiles, i, j, d);\n                if (len > 0) {\n                    // Mark tiles in this loop as visited\n                    int ci = i, cj = j, cd = d;\n                    for (int k = 0; k < len; k++) {\n                        visited[ci][cj] = true;\n                        int d2 = to[tiles[ci][cj]][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                    \n                    if (len > L1) { L2 = L1; L1 = len; }\n                    else if (len > L2) { L2 = len; }\n                }\n            }\n        }\n    }\n    \n    return (long long)L1 * L2;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    int tiles[30][30];\n    for (int i = 0; i < 30; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < 30; j++) {\n            tiles[i][j] = line[j] - '0';\n        }\n    }\n    \n    int best[30][30];\n    memcpy(best, tiles, sizeof(tiles));\n    long long bestScore = computeScore(best);\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> posDist(0, 29);\n    uniform_int_distribution<int> rotDist(1, 3);\n    \n    // Single pass greedy optimization\n    int current[30][30];\n    memcpy(current, tiles, sizeof(tiles));\n    \n    // Phase 1: Fast local improvements using heuristic\n    for (int iter = 0; iter < 500; iter++) {\n        int i = posDist(rng);\n        int j = posDist(rng);\n        int oldVal = current[i][j];\n        \n        // Try all rotations, use heuristic for quick evaluation\n        int bestRot = 0;\n        int bestHeur = -1;\n        \n        for (int r = 0; r < 4; r++) {\n            current[i][j] = (oldVal + r) % 8;\n            int h = fastHeuristic(current);\n            if (h > bestHeur) {\n                bestHeur = h;\n                bestRot = r;\n            }\n        }\n        \n        current[i][j] = (oldVal + bestRot) % 8;\n    }\n    \n    // Evaluate once\n    long long score = computeScore(current);\n    if (score > bestScore) {\n        memcpy(best, current, sizeof(best));\n        bestScore = score;\n    }\n    \n    // Phase 2: Targeted improvements on found loops\n    memcpy(current, best, sizeof(best));\n    for (int iter = 0; iter < 100; iter++) {\n        int i = posDist(rng);\n        int j = posDist(rng);\n        int oldVal = current[i][j];\n        \n        // Quick local evaluation\n        int bestRot = 0;\n        long long bestLocal = -1;\n        \n        for (int r = 0; r < 4; r++) {\n            current[i][j] = (oldVal + r) % 8;\n            long long s = computeScore(current);\n            if (s > bestLocal) {\n                bestLocal = s;\n                bestRot = r;\n            }\n        }\n        \n        current[i][j] = (oldVal + bestRot) % 8;\n        \n        if (bestLocal > bestScore) {\n            memcpy(best, current, sizeof(best));\n            bestScore = bestLocal;\n        }\n    }\n    \n    // Phase 3: Try 2x2 block rotations\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 29; j++) {\n            // Save these 4 tiles\n            int saved[4] = {current[i][j], current[i][j+1], \n                           current[i+1][j], current[i+1][j+1]};\n            \n            // Try rotating all 4 tiles together\n            for (int r = 1; r < 4; r++) {\n                current[i][j] = (saved[0] + r) % 8;\n                current[i][j+1] = (saved[1] + r) % 8;\n                current[i+1][j] = (saved[2] + r) % 8;\n                current[i+1][j+1] = (saved[3] + r) % 8;\n                \n                long long s = computeScore(current);\n                if (s > bestScore) {\n                    memcpy(best, current, sizeof(best));\n                    bestScore = s;\n                }\n            }\n            \n            // Restore\n            current[i][j] = saved[0];\n            current[i][j+1] = saved[1];\n            current[i+1][j] = saved[2];\n            current[i+1][j+1] = saved[3];\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 30; j++) {\n            int rot = (best[i][j] - tiles[i][j] + 8) % 8;\n            cout << (rot % 4);\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int dy[] = {-1, 1, 0, 0};  // U, D, L, R\nconst int dx[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\n\nint N, T;\nvector<vector<int>> board;\nint empty_y, empty_x;\nint current_ops;\n\nint hex_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nbool valid(int y, int x) {\n    return y >= 0 && y < N && x >= 0 && x < N;\n}\n\nvoid apply_move(int dir_idx) {\n    if (current_ops >= T) return;\n    int ty = empty_y + dy[dir_idx];\n    int tx = empty_x + dx[dir_idx];\n    if (!valid(ty, tx)) return;\n    swap(board[empty_y][empty_x], board[ty][tx]);\n    empty_y = ty;\n    empty_x = tx;\n    current_ops++;\n}\n\nvoid apply_moves(const string& moves) {\n    for (char c : moves) {\n        if (current_ops >= T) break;\n        if (c == 'U') apply_move(0);\n        else if (c == 'D') apply_move(1);\n        else if (c == 'L') apply_move(2);\n        else apply_move(3);\n    }\n}\n\nint remaining_ops() {\n    return T - current_ops;\n}\n\n// Calculate size of largest tree\nint calc_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]) continue;\n            \n            queue<pair<int,int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int size = 0;\n            \n            while (!q.empty()) {\n                auto [y, x] = q.front(); q.pop();\n                size++;\n                int tile = board[y][x];\n                \n                if ((tile & UP) && y > 0 && (board[y-1][x] & DOWN) && !visited[y-1][x]) {\n                    visited[y-1][x] = true;\n                    q.push({y-1, x});\n                }\n                if ((tile & DOWN) && y < N-1 && (board[y+1][x] & UP) && !visited[y+1][x]) {\n                    visited[y+1][x] = true;\n                    q.push({y+1, x});\n                }\n                if ((tile & LEFT) && x > 0 && (board[y][x-1] & RIGHT) && !visited[y][x-1]) {\n                    visited[y][x-1] = true;\n                    q.push({y, x-1});\n                }\n                if ((tile & RIGHT) && x < N-1 && (board[y][x+1] & LEFT) && !visited[y][x+1]) {\n                    visited[y][x+1] = true;\n                    q.push({y, x+1});\n                }\n            }\n            max_size = max(max_size, size);\n        }\n    }\n    return max_size;\n}\n\n// Check if two specific tiles should be connected based on their patterns\nbool should_connect(int tile1, int tile2, int dy, int dx) {\n    if (dx == 1) { // tile1 is left, tile2 is right\n        return (tile1 & RIGHT) && (tile2 & LEFT);\n    }\n    if (dx == -1) { // tile1 is right, tile2 is left\n        return (tile1 & LEFT) && (tile2 & RIGHT);\n    }\n    if (dy == 1) { // tile1 is up, tile2 is down\n        return (tile1 & DOWN) && (tile2 & UP);\n    }\n    if (dy == -1) { // tile1 is down, tile2 is up\n        return (tile1 & UP) && (tile2 & DOWN);\n    }\n    return false;\n}\n\n// Calculate score for current board (number of connected adjacent pairs)\nint calculate_connection_score() {\n    int score = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            \n            // Check right\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((tile & RIGHT) && (board[i][j+1] & LEFT)) {\n                    score++;\n                }\n            }\n            \n            // Check down\n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((tile & DOWN) && (board[i+1][j] & UP)) {\n                    score++;\n                }\n            }\n        }\n    }\n    return score;\n}\n\n// Find all adjacent pairs that should be connected but aren't\nvector<pair<pair<int,int>, pair<int,int>>> find_missing_connections() {\n    vector<pair<pair<int,int>, pair<int,int>>> missing;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            \n            // Check right\n            if (j < N-1 && board[i][j+1] != 0) {\n                int right_tile = board[i][j+1];\n                if ((tile & RIGHT) && (right_tile & LEFT)) {\n                    // They should connect but check if they already do\n                    if (!((tile & RIGHT) && (right_tile & LEFT))) {\n                        missing.push_back({{i, j}, {i, j+1}});\n                    }\n                }\n            }\n            \n            // Check down\n            if (i < N-1 && board[i+1][j] != 0) {\n                int down_tile = board[i+1][j];\n                if ((tile & DOWN) && (down_tile & UP)) {\n                    // They should connect but check if they already do\n                    if (!((tile & DOWN) && (down_tile & UP))) {\n                        missing.push_back({{i, j}, {i+1, j}});\n                    }\n                }\n            }\n        }\n    }\n    \n    return missing;\n}\n\n// Find a tile that would connect better somewhere else\n// Returns {source_pos, target_pos} where swapping source with target would help\npair<pair<int,int>, pair<int,int>> find_swap_opportunity() {\n    int best_improvement = 0;\n    pair<pair<int,int>, pair<int,int>> best_swap = {{-1, -1}, {-1, -1}};\n    \n    int original_score = calculate_connection_score();\n    \n    // For each pair of tiles (non-empty), consider swapping them\n    for (int i1 = 0; i1 < N; i1++) {\n        for (int j1 = 0; j1 < N; j1++) {\n            if (board[i1][j1] == 0) continue;\n            \n            for (int i2 = 0; i2 < N; i2++) {\n                for (int j2 = 0; j2 < N; j2++) {\n                    if (board[i2][j2] == 0) continue;\n                    if (i1 == i2 && j1 == j2) continue;\n                    \n                    // Simulate swap\n                    swap(board[i1][j1], board[i2][j2]);\n                    int new_score = calculate_connection_score();\n                    \n                    if (new_score > original_score + best_improvement) {\n                        best_improvement = new_score - original_score;\n                        best_swap = {{i1, j1}, {i2, j2}};\n                    }\n                    \n                    // Undo swap\n                    swap(board[i1][j1], board[i2][j2]);\n                }\n            }\n        }\n    }\n    \n    return best_swap;\n}\n\n// BFS to find path from empty to target, returning moves to bring target tile to empty\nstring bfs_path_to(int ty, int tx) {\n    if (ty == empty_y && tx == empty_x) return \"\";\n    if (board[ty][tx] == 0) return \"\";\n    \n    // Use Manhattan distance as lower bound\n    int min_dist = abs(ty - empty_y) + abs(tx - empty_x);\n    if (min_dist > remaining_ops()) return \"\";\n    \n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> dir_to(N, vector<int>(N, -1));\n    \n    queue<pair<int,int>> q;\n    q.push({empty_y, empty_x});\n    vis[empty_y][empty_x] = true;\n    \n    while (!q.empty()) {\n        auto [y, x] = q.front(); q.pop();\n        if (y == ty && x == tx) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int ny = y + dy[d], nx = x + dx[d];\n            if (!valid(ny, nx) || vis[ny][nx]) continue;\n            vis[ny][nx] = true;\n            parent[ny][nx] = {y, x};\n            dir_to[ny][nx] = d;\n            q.push({ny, nx});\n        }\n    }\n    \n    if (!vis[ty][tx]) return \"\";\n    \n    // Reconstruct path\n    string path;\n    int cy = ty, cx = tx;\n    while (cy != empty_y || cx != empty_x) {\n        int d = dir_to[cy][cx];\n        path += dir_char[d];  // The tile at (cy,cx) moved in direction d\n        auto [py, px] = parent[cy][cx];\n        cy = py; cx = px;\n    }\n    reverse(path.begin(), path.end());\n    \n    // Check if path is too long\n    if ((int)path.length() > remaining_ops()) return \"\";\n    \n    return path;\n}\n\n// Move empty to a specific position to swap tiles\nstring move_empty_to(int ty, int tx) {\n    return bfs_path_to(ty, tx);\n}\n\nstring solve() {\n    // Read input\n    string line;\n    getline(cin, line);\n    stringstream ss(line);\n    ss >> N >> T;\n    \n    board.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        string row;\n        getline(cin, row);\n        row.erase(remove(row.begin(), row.end(), ' '), row.end());\n        for (int j = 0; j < N; j++) {\n            board[i][j] = hex_to_int(row[j]);\n            if (board[i][j] == 0) {\n                empty_y = i;\n                empty_x = j;\n            }\n        }\n    }\n    \n    current_ops = 0;\n    string total_moves;\n    \n    int initial_tree = calc_tree_size();\n    if (initial_tree == N * N - 1) return \"\";\n    \n    int best_tree = initial_tree;\n    int original_missing = calculate_connection_score();\n    int no_improve = 0;\n    \n    // Main improvement loop\n    while (current_ops < T && no_improve < 10) {\n        // Find swap opportunities\n        auto swap_opp = find_swap_opportunity();\n        \n        if (swap_opp.first.first != -1 && remaining_ops() >= 3) {\n            auto [y1, x1] = swap_opp.first;\n            auto [y2, x2] = swap_opp.second;\n            \n            // Move empty to first position\n            string path1 = move_empty_to(y1, x1);\n            if (!path1.empty()) {\n                total_moves += path1;\n                apply_moves(path1);\n                \n                // Now empty is at (y1,x1), tile1 is at old empty position\n                // Move empty to second position\n                string path2 = move_empty_to(y2, x2);\n                if (!path2.empty()) {\n                    total_moves += path2;\n                    apply_moves(path2);\n                    \n                    // Now empty is at (y2,x2), tile2 is somewhere else\n                    // Move empty back to first position to complete the swap\n                    string path3 = move_empty_to(y1, x1);\n                    if (!path3.empty() && remaining_ops() >= (int)path3.length()) {\n                        total_moves += path3;\n                        apply_moves(path3);\n                        \n                        int new_tree = calc_tree_size();\n                        if (new_tree > best_tree) {\n                            best_tree = new_tree;\n                            no_improve = 0;\n                            if (best_tree == N * N - 1) break;\n                        } else {\n                            no_improve++;\n                        }\n                    }\n                }\n            }\n        } else {\n            // No swap opportunity found, do efficient shuffle\n            no_improve++;\n            if (remaining_ops() < 2) break;\n            \n            string shuffle;\n            int shuffle_len = min(remaining_ops(), N * 2);\n            \n            for (int i = 0; i < shuffle_len && current_ops < T; i++) {\n                // Try to move in a direction that's different from previous\n                int d = i % 4;\n                int ny = empty_y + dy[d];\n                int nx = empty_x + dx[d];\n                if (valid(ny, nx) && board[ny][nx] != 0) {\n                    shuffle += dir_char[d];\n                    apply_move(d);\n                }\n            }\n            \n            if (!shuffle.empty()) {\n                total_moves += shuffle;\n                int new_tree = calc_tree_size();\n                if (new_tree > best_tree) {\n                    best_tree = new_tree;\n                    no_improve = 0;\n                }\n            }\n        }\n    }\n    \n    return total_moves;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    string answer = solve();\n    cout << answer << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing ld = long double;\n\nconst ll CAKE_RADIUS = 10000LL;\n\nstruct Point {\n    ll x, y;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for (int d = 1; d <= 10; ++d) cin >> a[d];\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n\n    // Build target counts\n    vector<int> targets;\n    for (int d = 10; d >= 1; --d) {\n        for (int j = 0; j < a[d]; ++j) {\n            targets.push_back(d);\n        }\n    }\n\n    vector<pair<Point,Point>> cuts;\n    vector<bool> used(N, false);\n    \n    // Sort by x for vertical cuts\n    vector<int> sorted_by_x(N);\n    iota(sorted_by_x.begin(), sorted_by_x.end(), 0);\n    sort(sorted_by_x.begin(), sorted_by_x.end(), [&](int i, int j) {\n        return strawberries[i].x < strawberries[j].x;\n    });\n    \n    // Calculate optimal number of vertical cuts\n    int num_vertical = min(K * 4 / 10 + 1, N / 3);\n    num_vertical = min(num_vertical, K - 2);\n    \n    // Place vertical cuts to create strips with ~5 strawberries each\n    vector<ll> vertical_cuts;\n    int target_per_strip = max(1, N / (num_vertical + 1));\n    \n    int cur_x = 0;\n    while (cur_x < N && (int)vertical_cuts.size() < num_vertical) {\n        int next_x = min(cur_x + target_per_strip, N);\n        if (next_x < N) {\n            // Place cut between strawberries\n            ll cut_x = (strawberries[sorted_by_x[next_x - 1]].x + strawberries[sorted_by_x[next_x]].x) / 2;\n            \n            // Only add if not too close to any strawberry\n            bool safe = true;\n            for (int k = max(0, next_x - 2); k <= min(N - 1, next_x + 1); ++k) {\n                if (abs(strawberries[sorted_by_x[k]].x - cut_x) <= 2) {\n                    safe = false;\n                    break;\n                }\n            }\n            \n            if (safe && cut_x > -CAKE_RADIUS && cut_x < CAKE_RADIUS) {\n                vertical_cuts.push_back(cut_x);\n            }\n        }\n        cur_x = next_x;\n    }\n    \n    sort(vertical_cuts.begin(), vertical_cuts.end());\n    vertical_cuts.erase(unique(vertical_cuts.begin(), vertical_cuts.end()), vertical_cuts.end());\n    \n    // Determine strip for each strawberry\n    vector<int> strip_id(N, 0);\n    for (int i = 0; i < N; ++i) {\n        int sid = 0;\n        for (ll cx : vertical_cuts) {\n            if (strawberries[i].x > cx) sid++;\n        }\n        strip_id[i] = sid;\n    }\n    \n    // Add vertical cuts\n    for (ll x : vertical_cuts) {\n        if ((int)cuts.size() >= K) break;\n        cuts.emplace_back(Point{x, -CAKE_RADIUS}, Point{x, CAKE_RADIUS});\n    }\n    \n    // For each strip, add horizontal cuts\n    int strips = (int)vertical_cuts.size() + 1;\n    int remaining = K - (int)cuts.size();\n    \n    // Calculate total horizontal cuts we can place\n    int total_horizontal = remaining;\n    \n    for (int s = 0; s < strips && total_horizontal > 0; ++s) {\n        // Get strawberries in this strip\n        vector<int> strip_straws;\n        for (int i = 0; i < N; ++i) {\n            if (strip_id[i] == s) {\n                strip_straws.push_back(i);\n            }\n        }\n        \n        if (strip_straws.empty()) continue;\n        \n        // Sort by y\n        sort(strip_straws.begin(), strip_straws.end(), [&](int i, int j) {\n            return strawberries[i].y < strawberries[j].y;\n        });\n        \n        // Calculate cuts for this strip\n        int strip_size = (int)strip_straws.size();\n        int cuts_for_strip = max(1, min(total_horizontal, strip_size / 4));\n        cuts_for_strip = min(cuts_for_strip, total_horizontal / (strips - s) + 1);\n        \n        if (cuts_for_strip > 0) {\n            for (int h = 0; h < cuts_for_strip && total_horizontal > 0; ++h) {\n                int pos = ((h + 1) * strip_size) / (cuts_for_strip + 1);\n                if (pos >= strip_size) pos = strip_size - 1;\n                \n                ll cut_y = strawberries[strip_straws[pos]].y;\n                \n                // Place between strawberries if possible\n                if (pos + 1 < strip_size) {\n                    cut_y = (strawberries[strip_straws[pos]].y + strawberries[strip_straws[pos + 1]].y) / 2;\n                }\n                \n                cut_y = max(-CAKE_RADIUS + 1LL, min(CAKE_RADIUS - 1LL, cut_y));\n                \n                // Check safety\n                bool safe = true;\n                for (int k = max(0, pos - 1); k <= min(strip_size - 1, pos + 1); ++k) {\n                    if (abs(strawberries[strip_straws[k]].y - cut_y) <= 2) {\n                        safe = false;\n                        break;\n                    }\n                }\n                \n                if (safe) {\n                    cuts.emplace_back(Point{-CAKE_RADIUS, cut_y}, Point{CAKE_RADIUS, cut_y});\n                    total_horizontal--;\n                }\n            }\n        }\n    }\n    \n    // Evaluate grid\n    vector<ll> h_cuts, v_cuts;\n    for (const auto& cut : cuts) {\n        if (cut.first.x == cut.second.x) v_cuts.push_back(cut.first.x);\n        else h_cuts.push_back(cut.first.y);\n    }\n    \n    int rows = (int)h_cuts.size() + 1;\n    int cols = (int)v_cuts.size() + 1;\n    vector<vector<vector<int>>> cell_straws(rows, vector<vector<int>>(cols));\n    \n    for (int i = 0; i < N; ++i) {\n        int r = 0, c = 0;\n        for (ll y : h_cuts) if (strawberries[i].y > y) r++;\n        for (ll x : v_cuts) if (strawberries[i].x > x) c++;\n        cell_straws[r][c].push_back(i);\n    }\n    \n    // Form pieces\n    int target_pos = 0;\n    \n    // Phase 1: Cells with exactly matching size\n    for (int r = 0; r < rows && target_pos < (int)targets.size(); ++r) {\n        for (int c = 0; c < cols && target_pos < (int)targets.size(); ++c) {\n            int size = (int)cell_straws[r][c].size();\n            if (size == 0) continue;\n            \n            // Try to match with targets that are <= size\n            int best_match = -1;\n            int best_diff = 100;\n            \n            for (int t = target_pos; t < (int)targets.size(); ++t) {\n                if (targets[t] <= size && size - targets[t] < best_diff) {\n                    best_match = t;\n                    best_diff = size - targets[t];\n                }\n            }\n            \n            if (best_match != -1) {\n                int need = targets[best_match];\n                int taken = 0;\n                for (int idx : cell_straws[r][c]) {\n                    if (taken < need) {\n                        used[idx] = true;\n                        taken++;\n                    }\n                }\n                swap(targets[best_match], targets[target_pos]);\n                target_pos++;\n            }\n        }\n    }\n    \n    // Phase 2: Larger cells, try to split into multiple pieces\n    for (int r = 0; r < rows && target_pos < (int)targets.size(); ++r) {\n        for (int c = 0; c < cols && target_pos < (int)targets.size(); ++c) {\n            int size = (int)cell_straws[r][c].size();\n            if (size <= 10 || size > 20) continue; // Skip very large cells\n            \n            // Try to create as many pieces as possible from this cell\n            vector<int> cell_indices = cell_straws[r][c];\n            int ci = 0;\n            \n            while (ci < size && target_pos < (int)targets.size()) {\n                int remaining_in_cell = size - ci;\n                \n                int best_match = -1;\n                int best_diff = 100;\n                for (int t = target_pos; t < (int)targets.size(); ++t) {\n                    if (targets[t] <= remaining_in_cell && remaining_in_cell - targets[t] < best_diff) {\n                        best_match = t;\n                        best_diff = remaining_in_cell - targets[t];\n                    }\n                }\n                \n                if (best_match != -1) {\n                    int need = targets[best_match];\n                    for (int k = 0; k < need; ++k) {\n                        used[cell_indices[ci + k]] = true;\n                    }\n                    swap(targets[best_match], targets[target_pos]);\n                    target_pos++;\n                    ci += need;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Column merging\n    if (target_pos < (int)targets.size()) {\n        for (int c = 0; c < cols && target_pos < (int)targets.size(); ++c) {\n            vector<int> col_unused;\n            for (int r = 0; r < rows; ++r) {\n                for (int idx : cell_straws[r][c]) {\n                    if (!used[idx]) col_unused.push_back(idx);\n                }\n            }\n            \n            if (col_unused.empty()) continue;\n            \n            sort(col_unused.begin(), col_unused.end(), [&](int i, int j) {\n                return strawberries[i].y < strawberries[j].y;\n            });\n            \n            int cu_idx = 0;\n            while (cu_idx < (int)col_unused.size() && target_pos < (int)targets.size()) {\n                int available = (int)col_unused.size() - cu_idx;\n                \n                int best_match = -1;\n                int best_diff = 100;\n                for (int t = target_pos; t < (int)targets.size(); ++t) {\n                    if (targets[t] <= available && available - targets[t] < best_diff) {\n                        best_match = t;\n                        best_diff = available - targets[t];\n                    }\n                }\n                \n                if (best_match != -1) {\n                    int need = targets[best_match];\n                    for (int k = 0; k < need; ++k) {\n                        used[col_unused[cu_idx + k]] = true;\n                    }\n                    swap(targets[best_match], targets[target_pos]);\n                    target_pos++;\n                    cu_idx += need;\n                } else {\n                    cu_idx = (int)col_unused.size();\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Row merging\n    if (target_pos < (int)targets.size()) {\n        for (int r = 0; r < rows && target_pos < (int)targets.size(); ++r) {\n            vector<int> row_unused;\n            for (int c = 0; c < cols; ++c) {\n                for (int idx : cell_straws[r][c]) {\n                    if (!used[idx]) row_unused.push_back(idx);\n                }\n            }\n            \n            if (row_unused.empty()) continue;\n            \n            sort(row_unused.begin(), row_unused.end(), [&](int i, int j) {\n                return strawberries[i].x < strawberries[j].x;\n            });\n            \n            int ru_idx = 0;\n            while (ru_idx < (int)row_unused.size() && target_pos < (int)targets.size()) {\n                int available = (int)row_unused.size() - ru_idx;\n                \n                int best_match = -1;\n                int best_diff = 100;\n                for (int t = target_pos; t < (int)targets.size(); ++t) {\n                    if (targets[t] <= available && available - targets[t] < best_diff) {\n                        best_match = t;\n                        best_diff = available - targets[t];\n                    }\n                }\n                \n                if (best_match != -1) {\n                    int need = targets[best_match];\n                    for (int k = 0; k < need; ++k) {\n                        used[row_unused[ru_idx + k]] = true;\n                    }\n                    swap(targets[best_match], targets[target_pos]);\n                    target_pos++;\n                    ru_idx += need;\n                } else {\n                    ru_idx = (int)row_unused.size();\n                }\n            }\n        }\n    }\n    \n    // Output\n    int out_k = min((int)cuts.size(), K);\n    cout << out_k << \"\\n\";\n    for (int idx = 0; idx < out_k; ++idx) {\n        cout << cuts[idx].first.x << \" \" << cuts[idx].first.y << \" \"\n             << cuts[idx].second.x << \" \" << cuts[idx].second.y << \"\\n\";\n    }\n\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> hasDot;\nvector<vector<bool>> horizSegment;\nvector<vector<bool>> vertSegment;\nvector<bool> diagSegment;\nvector<array<int, 8>> operations;\nint center;\n\nint get_weight(int x, int y) {\n    return (x-center)*(x-center) + (y-center)*(y-center) + 1;\n}\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Check if this is a valid rectangle shape\nbool isValidRectangleShape(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check axis-aligned case\n    if (x1 == x2 && x3 == x4 && y1 == y4 && y2 == y3) {\n        return (x1 != x3 && y1 != y2);  // Non-zero size\n    }\n    if (y1 == y2 && y3 == y4 && x1 == x4 && x2 == x3) {\n        return (x1 != x3 && y1 != y3);  // Non-zero size\n    }\n    \n    // Check 45-degree rectangle (diamond shape)\n    int dx12 = abs(x2 - x1), dy12 = abs(y2 - y1);\n    int dx23 = abs(x3 - x2), dy23 = abs(y3 - y2);\n    int dx34 = abs(x4 - x3), dy34 = abs(y4 - y3);\n    int dx41 = abs(x1 - x4), dy41 = abs(y1 - y4);\n    \n    if (dx12 == dy12 && dx12 > 0 && dx23 == dy23 && dx23 > 0 && \n        dx34 == dy34 && dx34 > 0 && dx41 == dy41 && dx41 > 0) {\n        int len12 = dx12 * dx12 + dy12 * dy12;\n        int len23 = dx23 * dx23 + dy23 * dy23;\n        int len34 = dx34 * dx34 + dy34 * dy34;\n        int len41 = dx41 * dx41 + dy41 * dy41;\n        return (len12 == len23 && len23 == len34 && len34 == len41);\n    }\n    \n    return false;\n}\n\n// Check if we can use a segment\nbool canUseSegment(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) { // vertical\n        int sy = min(y1, y2), ey = max(y1, y2);\n        for (int y = sy; y < ey; y++) {\n            if (vertSegment[x1][y]) return false;\n        }\n    } else if (y1 == y2) { // horizontal\n        int sx = min(x1, x2), ex = max(x1, x2);\n        for (int x = sx; x < ex; x++) {\n            if (horizSegment[x][y1]) return false;\n        }\n    } else { // diagonal\n        int dx = (x2 > x1) ? 1 : -1;\n        int dy = (y2 > y1) ? 1 : -1;\n        int x = x1, y = y1;\n        while (x != x2) {\n            int idx = min(x, x + dx) * N + min(y, y + dy);\n            if (diagSegment[idx]) return false;\n            x += dx; \n            y += dy;\n        }\n    }\n    return true;\n}\n\n// Mark a segment as used\nvoid markSegment(int x1, int y1, int x2, int y2) {\n    if (x1 == x2) { // vertical\n        int sy = min(y1, y2), ey = max(y1, y2);\n        for (int y = sy; y < ey; y++) {\n            vertSegment[x1][y] = true;\n        }\n    } else if (y1 == y2) { // horizontal\n        int sx = min(x1, x2), ex = max(x1, x2);\n        for (int x = sx; x < ex; x++) {\n            horizSegment[x][y1] = true;\n        }\n    } else { // diagonal\n        int dx = (x2 > x1) ? 1 : -1;\n        int dy = (y2 > y1) ? 1 : -1;\n        int x = x1, y = y1;\n        while (x != x2) {\n            int idx = min(x, x + dx) * N + min(y, y + dy);\n            diagSegment[idx] = true;\n            x += dx; \n            y += dy;\n        }\n    }\n}\n\n// Check if rectangle placement is valid\nbool canPlaceRectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check bounds\n    if (!in_bounds(x1, y1) || !in_bounds(x2, y2) || \n        !in_bounds(x3, y3) || !in_bounds(x4, y4)) {\n        return false;\n    }\n    \n    // Check rectangle shape\n    if (!isValidRectangleShape(x1, y1, x2, y2, x3, y3, x4, y4)) {\n        return false;\n    }\n    \n    // p1 must be empty\n    if (hasDot[x1][y1]) return false;\n    \n    // p2, p3, p4 must have dots\n    if (!hasDot[x2][y2] || !hasDot[x3][y3] || !hasDot[x4][y4]) return false;\n    \n    // Check all four points are distinct\n    if (x1 == x2 && y1 == y2) return false;\n    if (x1 == x3 && y1 == y3) return false;\n    if (x1 == x4 && y1 == y4) return false;\n    if (x2 == x3 && y2 == y3) return false;\n    if (x2 == x4 && y2 == y4) return false;\n    if (x3 == x4 && y3 == y4) return false;\n    \n    // Check all segments are available\n    if (!canUseSegment(x1, y1, x2, y2)) return false;\n    if (!canUseSegment(x2, y2, x3, y3)) return false;\n    if (!canUseSegment(x3, y3, x4, y4)) return false;\n    if (!canUseSegment(x4, y4, x1, y1)) return false;\n    \n    // Check no other dots on the perimeter\n    auto checkSide = [&](int ax, int ay, int bx, int by) {\n        int steps = max(abs(bx - ax), abs(by - ay));\n        if (steps <= 1) return true;\n        \n        for (int i = 1; i < steps; i++) {\n            int px = ax + (bx - ax) * i / steps;\n            int py = ay + (by - ay) * i / steps;\n            if (hasDot[px][py] && \n                !(px == x1 && py == y1) &&\n                !(px == x2 && py == y2) &&\n                !(px == x3 && py == y3) &&\n                !(px == x4 && py == y4)) {\n                return false;\n            }\n        }\n        return true;\n    };\n    \n    return checkSide(x1, y1, x2, y2) && checkSide(x2, y2, x3, y3) &&\n           checkSide(x3, y3, x4, y4) && checkSide(x4, y4, x1, y1);\n}\n\n// Try to place a rectangle centered at (x,y) as p1\nbool tryPlaceRectangle(int x, int y, int& best_weight, array<int, 8>& best_op) {\n    // Try axis-aligned rectangles\n    int maxSize = min(10, N - max(x, y));\n    for (int dx = 1; dx <= maxSize && x + dx < N; dx++) {\n        for (int dy = 1; dy <= maxSize && y + dy < N; dy++) {\n            int x2 = x + dx, y2 = y;\n            int x3 = x + dx, y3 = y + dy;\n            int x4 = x, y4 = y + dy;\n            \n            if (canPlaceRectangle(x, y, x2, y2, x3, y3, x4, y4)) {\n                best_weight = get_weight(x, y);\n                best_op = {x, y, x2, y2, x3, y3, x4, y4};\n                return true;\n            }\n        }\n    }\n    \n    // Try 45-degree rectangles\n    int maxD = min(10, min(N - x, min(y + 1, N - y)));\n    for (int d = 1; d <= maxD; d++) {\n        // Horizontal diamond: p1=(x,y), p2=(x+d,y+d), p3=(x,y+2d), p4=(x-d,y+d)\n        if (x + d < N && y + d < N && x - d >= 0 && y + 2*d < N) {\n            int x2 = x + d, y2 = y + d;\n            int x3 = x, y3 = y + 2*d;\n            int x4 = x - d, y4 = y + d;\n            \n            if (canPlaceRectangle(x, y, x2, y2, x3, y3, x4, y4)) {\n                best_weight = get_weight(x, y);\n                best_op = {x, y, x2, y2, x3, y3, x4, y4};\n                return true;\n            }\n        }\n        \n        // Vertical diamond: p1=(x,y), p2=(x+d,y), p3=(x+d,y-d), p4=(x,y-d)\n        if (x + d < N && y - d >= 0) {\n            int x2 = x + d, y2 = y;\n            int x3 = x + d, y3 = y - d;\n            int x4 = x, y4 = y - d;\n            \n            if (canPlaceRectangle(x, y, x2, y2, x3, y3, x4, y4)) {\n                best_weight = get_weight(x, y);\n                best_op = {x, y, x2, y2, x3, y3, x4, y4};\n                return true;\n            }\n        }\n    }\n    \n    return false;\n}\n\nvoid solve() {\n    bool improved = true;\n    int iterations = 0;\n    \n    while (improved && iterations < 5000) {\n        improved = false;\n        iterations++;\n        \n        int best_weight = -1;\n        array<int, 8> best_op;\n        \n        // Search in high-weight areas first\n        int minX = max(0, center - N/2);\n        int maxX = min(N-1, center + N/2);\n        int minY = max(0, center - N/2);\n        int maxY = min(N-1, center + N/2);\n        \n        for (int x = minX; x <= maxX && !improved; x++) {\n            for (int y = minY; y <= maxY && !improved; y++) {\n                if (hasDot[x][y]) continue;\n                \n                int w = get_weight(x, y);\n                if (w <= best_weight) continue;\n                \n                if (tryPlaceRectangle(x, y, best_weight, best_op)) {\n                    improved = true;\n                }\n            }\n        }\n        \n        if (improved) {\n            operations.push_back(best_op);\n            hasDot[best_op[0]][best_op[1]] = true;\n            \n            markSegment(best_op[0], best_op[1], best_op[2], best_op[3]);\n            markSegment(best_op[2], best_op[3], best_op[4], best_op[5]);\n            markSegment(best_op[4], best_op[5], best_op[6], best_op[7]);\n            markSegment(best_op[6], best_op[7], best_op[0], best_op[1]);\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    center = (N-1)/2;\n    \n    hasDot.assign(N, vector<bool>(N, false));\n    horizSegment.assign(N, vector<bool>(N, false));\n    vertSegment.assign(N, vector<bool>(N, false));\n    diagSegment.assign(N * N, false);\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        hasDot[x][y] = true;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            cout << op[i] << (i < 7 ? \" \" : \"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int T = 100;\n\nstruct State {\n    int grid[N][N] = {};\n    \n    State() {}\n    State(const State& other) {\n        memcpy(grid, other.grid, sizeof(grid));\n    }\n    \n    bool valid(int x, int y) const {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void place(int p, int flavor) {\n        int count = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) {\n                    count++;\n                    if (count == p) {\n                        grid[x][y] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    State tilt(int d) const {\n        State res(*this);\n        \n        if (d == 0) {\n            for (int x = 0; x < N; x++) {\n                for (int y = 1; y < N; y++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny > 0 && res.grid[x][ny-1] == 0) ny--;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 1) {\n            for (int x = 0; x < N; x++) {\n                for (int y = N-2; y >= 0; y--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int ny = y;\n                    while (ny < N-1 && res.grid[x][ny+1] == 0) ny++;\n                    if (ny != y) {\n                        res.grid[x][ny] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else if (d == 2) {\n            for (int y = 0; y < N; y++) {\n                for (int x = 1; x < N; x++) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx > 0 && res.grid[nx-1][y] == 0) nx--;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        else {\n            for (int y = 0; y < N; y++) {\n                for (int x = N-2; x >= 0; x--) {\n                    if (res.grid[x][y] == 0) continue;\n                    int nx = x;\n                    while (nx < N-1 && res.grid[nx+1][y] == 0) nx++;\n                    if (nx != x) {\n                        res.grid[nx][y] = res.grid[x][y];\n                        res.grid[x][y] = 0;\n                    }\n                }\n            }\n        }\n        \n        return res;\n    }\n    \n    double evaluate(const vector<int>& future_flavors, int remaining) const {\n        double score = 0.0;\n        \n        // 1. Adjacent pairs (same as best version)\n        int pairs = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int f = grid[x][y];\n                if (x + 1 < N && grid[x+1][y] == f) pairs++;\n                if (y + 1 < N && grid[x][y+1] == f) pairs++;\n            }\n        }\n        score += pairs * 10.0;\n        \n        // 2. Component sizes (quadratic for scoring formula)\n        bool visited[N][N] = {};\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0 || visited[x][y]) continue;\n                int flavor = grid[x][y];\n                int size = 0;\n                \n                queue<pair<int,int>> q;\n                q.push({x, y});\n                visited[x][y] = true;\n                \n                while (!q.empty()) {\n                    auto [cx, cy] = q.front(); q.pop();\n                    size++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = cx + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                        int ny = cy + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                        if (valid(nx, ny) && !visited[nx][ny] && grid[nx][ny] == flavor) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                \n                score += size * size * 0.5;\n            }\n        }\n        \n        // 3. Future potential with improved analysis\n        int future_counts[4] = {};\n        for (int i = 0; i < remaining; i++) {\n            future_counts[future_flavors[i]]++;\n        }\n        \n        // Find which flavors will appear most\n        int max_future = 0, second_max_future = 0;\n        for (int f = 1; f <= 3; f++) {\n            if (future_counts[f] >= future_counts[max_future]) {\n                second_max_future = max_future;\n                max_future = f;\n            } else if (future_counts[f] >= future_counts[second_max_future]) {\n                second_max_future = f;\n            }\n        }\n        \n        // Check each empty cell's expansion potential\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0) continue;\n                \n                int neighbor_flavors[4] = {};\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] > 0) {\n                        neighbor_flavors[grid[nx][ny]]++;\n                    }\n                }\n                \n                // Extra bonus for expanding the most abundant future flavor\n                for (int f = 1; f <= 3; f++) {\n                    if (neighbor_flavors[f] > 0 && future_counts[f] > 0) {\n                        double boost = (f == max_future) ? 4.0 : 3.0;\n                        score += neighbor_flavors[f] * boost;\n                    }\n                }\n            }\n        }\n        \n        // 4. Empty space cluster bonus with better analysis\n        int empty_visited[N][N] = {};\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] != 0 || empty_visited[x][y]) continue;\n                \n                int empty_size = 0;\n                queue<pair<int,int>> q;\n                q.push({x, y});\n                empty_visited[x][y] = true;\n                \n                while (!q.empty()) {\n                    auto [cx, cy] = q.front(); q.pop();\n                    empty_size++;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = cx + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                        int ny = cy + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                        if (valid(nx, ny) && !empty_visited[nx][ny] && grid[nx][ny] == 0) {\n                            empty_visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n                \n                if (empty_size >= 3) {\n                    int adjacent_flavors[4] = {};\n                    for (int dy = -1; dy <= 1; dy++) {\n                        for (int dx = -1; dx <= 1; dx++) {\n                            int nx = x + dx;\n                            int ny = y + dy;\n                            if (valid(nx, ny) && grid[nx][ny] > 0) {\n                                adjacent_flavors[grid[nx][ny]]++;\n                            }\n                        }\n                    }\n                    \n                    for (int f = 1; f <= 3; f++) {\n                        if (adjacent_flavors[f] > 0 && future_counts[f] > 0) {\n                            double boost = (f == max_future) ? 1.0 : 0.5;\n                            double bonus = min(empty_size, future_counts[f]) * boost;\n                            score += bonus;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // 5. Isolation penalty\n        int isolated = 0;\n        for (int y = 0; y < N; y++) {\n            for (int x = 0; x < N; x++) {\n                if (grid[x][y] == 0) continue;\n                int flavor = grid[x][y];\n                bool has_same = false;\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + (d < 2 ? 0 : (d == 2 ? -1 : 1));\n                    int ny = y + (d < 2 ? (d == 0 ? 1 : -1) : 0);\n                    if (valid(nx, ny) && grid[nx][ny] == flavor) {\n                        has_same = true;\n                        break;\n                    }\n                }\n                if (!has_same) isolated++;\n            }\n        }\n        score -= isolated * 5.0;\n        \n        // 6. 2x2 block bonus\n        for (int y = 0; y < N - 1; y++) {\n            for (int x = 0; x < N - 1; x++) {\n                int cells = (grid[x][y] > 0) + (grid[x+1][y] > 0) + \n                           (grid[x][y+1] > 0) + (grid[x+1][y+1] > 0);\n                if (cells >= 3) {\n                    int flavors_present[4] = {};\n                    if (grid[x][y] > 0) flavors_present[grid[x][y]]++;\n                    if (grid[x+1][y] > 0) flavors_present[grid[x+1][y]]++;\n                    if (grid[x][y+1] > 0) flavors_present[grid[x][y+1]]++;\n                    if (grid[x+1][y+1] > 0) flavors_present[grid[x+1][y+1]]++;\n                    \n                    for (int f = 1; f <= 3; f++) {\n                        if (flavors_present[f] >= 3) {\n                            score += 2.0;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(T);\n    for (int i = 0; i < T; i++) {\n        cin >> flavors[i];\n    }\n    \n    // Precompute flavor distribution\n    int total_counts[4] = {};\n    for (int i = 0; i < T; i++) {\n        total_counts[flavors[i]]++;\n    }\n    \n    State current_state;\n    const char dir_names[] = {'F', 'B', 'L', 'R'};\n    \n    for (int t = 0; t < T; t++) {\n        int p;\n        cin >> p;\n        \n        current_state.place(p, flavors[t]);\n        \n        if (t == T - 1) break;\n        \n        double best_score = -1e18;\n        int best_dir = 0;\n        \n        vector<int> remaining(flavors.begin() + t + 1, flavors.end());\n        \n        for (int d = 0; d < 4; d++) {\n            State new_state = current_state.tilt(d);\n            double score = new_state.evaluate(remaining, T - t - 1);\n            if (score > best_score) {\n                best_score = score;\n                best_dir = d;\n            }\n        }\n        \n        current_state = current_state.tilt(best_dir);\n        cout << dir_names[best_dir] << '\\n';\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <chrono>\n#include <random>\nusing namespace std;\nusing namespace std::chrono;\n\nconst int QUERIES = 100;\nint M;\ndouble eps;\n\nstruct Graph {\n    vector<vector<bool>> adj;\n    string str;\n    int N, edges;\n    vector<int> degSeq;\n    \n    Graph() : N(0), edges(0) {}\n    Graph(int n) : N(n), adj(n, vector<bool>(n, false)), edges(0) {}\n    \n    void computeDegrees() {\n        degSeq.resize(N);\n        for (int i = 0; i < N; i++) {\n            int deg = 0;\n            for (int j = 0; j < N; j++) {\n                if (adj[i][j]) deg++;\n            }\n            degSeq[i] = deg;\n        }\n        sort(degSeq.begin(), degSeq.end());\n    }\n    \n    // O(N^2) string generation\n    void makeString() {\n        str.clear();\n        str.reserve(N * (N-1) / 2);\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                str += (adj[i][j] ? '1' : '0');\n            }\n        }\n    }\n};\n\n// Fast string to graph - no unnecessary operations\nGraph strToGraphFast(const string& s) {\n    int N = 0;\n    while (N * (N-1) / 2 < (int)s.size()) N++;\n    \n    Graph g(N);\n    int idx = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            g.adj[i][j] = g.adj[j][i] = (s[idx++] == '1');\n            if (g.adj[i][j]) g.edges++;\n        }\n    }\n    \n    g.computeDegrees();\n    g.str = s;\n    return g;\n}\n\nstruct Features {\n    double edges;\n    double degMean, degStd;\n    double isolatedRatio, leafRatio;\n    \n    Features(const Graph& g) {\n        int N = g.N;\n        int maxEdges = N * (N-1) / 2;\n        edges = maxEdges > 0 ? (double)g.edges / maxEdges : 0;\n        \n        if (N == 0) return;\n        \n        double degSum = 0;\n        for (int d : g.degSeq) degSum += d;\n        degMean = degSum / N;\n        \n        double var = 0;\n        for (int d : g.degSeq) var += (d - degMean) * (d - degMean);\n        degStd = sqrt(var / N);\n        \n        int isolated = 0, leaves = 0;\n        for (int d : g.degSeq) {\n            if (d == 0) isolated++;\n            if (d == 1) leaves++;\n        }\n        isolatedRatio = (double)isolated / N;\n        leafRatio = (double)leaves / N;\n    }\n};\n\n// Distance metric - optimized\ninline double featureDist(const Features& a, const Features& b, double eps) {\n    double d = 0;\n    double wEdge = 1.0 + 10.0 * eps;\n    d += wEdge * abs(a.edges - b.edges) * 4.0;\n    \n    double wDeg = 1.0 / (1.0 + eps * 5.0);\n    d += wDeg * abs(a.degMean - b.degMean) * 2.0;\n    d += wDeg * abs(a.degStd - b.degStd);\n    \n    double wStruct = max(0.0, 1.0 - 3.0 * eps);\n    d += wStruct * abs(a.isolatedRatio - b.isolatedRatio) * 2.0;\n    d += wStruct * abs(a.leafRatio - b.leafRatio);\n    \n    return d;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto startTime = high_resolution_clock::now();\n    \n    cin >> M >> eps;\n    \n    // Ultra-fast N selection\n    // For low epsilon: use moderate N\n    // For high epsilon: use small N\n    int N;\n    if (eps <= 0.01) N = min(30, max(8, 8 + M/4));\n    else if (eps <= 0.03) N = min(25, max(8, 7 + M/5));\n    else if (eps <= 0.05) N = min(20, max(7, 6 + M/6));\n    else if (eps <= 0.10) N = min(16, max(7, 5 + M/7));\n    else if (eps <= 0.20) N = min(12, max(6, 4 + M/10));\n    else if (eps <= 0.30) N = min(10, max(6, 4 + M/12));\n    else N = min(8, max(6, 4 + M/15));\n    \n    int maxEdges = N * (N-1) / 2;\n    \n    // Generate graphs with deterministic, O(N^2) total construction\n    vector<Graph> graphs(M);\n    \n    for (int k = 0; k < M; k++) {\n        auto now = high_resolution_clock::now();\n        auto elapsed = duration_cast<milliseconds>(now - startTime).count();\n        if (elapsed > 4900) {\n            // Just use the last good graph for remaining\n            for (int r = k; r < M; r++) {\n                graphs[r] = graphs[k-1];\n            }\n            break;\n        }\n        \n        Graph g(N);\n        \n        // Deterministic edge count: equally spaced\n        // This ensures maximum discriminability\n        int targetEdges;\n        if (M == 1) {\n            targetEdges = maxEdges / 2;\n        } else {\n            targetEdges = max(0, min(maxEdges, (int)((double)k * maxEdges / (M - 1))));\n        }\n        \n        // O(N^2) construction: fill adjacency in one pass\n        double p = maxEdges > 0 ? (double)targetEdges / maxEdges : 0;\n        int count = 0;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                // Deterministic: use k and (i,j) to decide\n                int hash = (k * 10007 + i * 9973 + j * 7919) % 10000;\n                bool addEdge = (hash < (int)(p * 10000));\n                \n                // Also ensure we hit exact target\n                if (addEdge && count < targetEdges) {\n                    g.adj[i][j] = g.adj[j][i] = true;\n                    count++;\n                } else if (!addEdge && count > targetEdges) {\n                    // This shouldn't happen with proper p\n                }\n            }\n        }\n        \n        // Adjust to exact target (very fast - O(N) average)\n        // Add missing edges\n        for (int i = 0; i < N && count < targetEdges; i++) {\n            for (int j = i+1; j < N && count < targetEdges; j++) {\n                if (!g.adj[i][j]) {\n                    g.adj[i][j] = g.adj[j][i] = true;\n                    count++;\n                }\n            }\n        }\n        \n        // Remove extra edges\n        for (int i = 0; i < N && count > targetEdges; i++) {\n            for (int j = i+1; j < N && count > targetEdges; j++) {\n                if (g.adj[i][j]) {\n                    g.adj[i][j] = g.adj[j][i] = false;\n                    count--;\n                }\n            }\n        }\n        \n        g.edges = count;\n        g.computeDegrees();\n        g.makeString();\n        g.N = N;\n        graphs[k] = g;\n    }\n    \n    // Precompute features (fast O(M*N))\n    vector<Features> refFeatures;\n    refFeatures.reserve(M);\n    for (int k = 0; k < M; k++) {\n        refFeatures.emplace_back(graphs[k]);\n    }\n    \n    // Output\n    cout << N << endl;\n    for (const auto& g : graphs) {\n        cout << g.str << endl;\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < QUERIES; q++) {\n        string H_str;\n        cin >> H_str;\n        \n        Graph observed = strToGraphFast(H_str);\n        Features obsFeat(observed);\n        \n        // Simple linear scan - O(M) per query, M <= 100\n        int best = 0;\n        double bestDist = 1e18;\n        int edgeBest = 0;\n        double bestEdgeDist = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double dist = featureDist(refFeatures[k], obsFeat, eps);\n            double edgeDist = abs(refFeatures[k].edges - obsFeat.edges);\n            \n            if (dist < bestDist) {\n                bestDist = dist;\n                best = k;\n            }\n            if (edgeDist < bestEdgeDist) {\n                bestEdgeDist = edgeDist;\n                edgeBest = k;\n            }\n        }\n        \n        // For high noise, rely on edge count\n        if (eps > 0.1) {\n            double edgeDiff = abs(refFeatures[best].edges - obsFeat.edges);\n            double edgeDiffBest = abs(refFeatures[edgeBest].edges - obsFeat.edges);\n            if (edgeDiff > edgeDiffBest * 1.1) {\n                best = edgeBest;\n            }\n        }\n        \n        cout << best << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\n\nint N, M, D, K;\nvector<tuple<int, int, int>> edges;\nvector<vector<pair<int, int>>> graph;\n\ndouble quick_evaluate(const vector<int>& schedule) {\n    double cost = 0;\n    vector<double> day_cost(D+1, 0);\n    vector<vector<int>> day_edges(D+1);\n    \n    // Group edges by day\n    for (int e = 0; e < M; e++) {\n        day_edges[schedule[e]].push_back(e);\n    }\n    \n    // Compute cost for each day\n    for (int day = 1; day <= D; day++) {\n        if (day_edges[day].empty()) continue;\n        \n        double total_importance = 0;\n        // Check vertex conflicts among edges on this day\n        unordered_map<int, int> vertex_usage;\n        \n        for (int e : day_edges[day]) {\n            auto [u, v, w] = edges[e];\n            vertex_usage[u]++;\n            vertex_usage[v]++;\n            // Heuristic: heavier edges cause more frustration\n            total_importance += w * 0.001; // Scale down weight\n        }\n        \n        // Penalty: vertices with multiple incident edges being repaired on same day\n        double vertex_conflict_penalty = 0;\n        for (auto& [v, count] : vertex_usage) {\n            if (count > 1) {\n                vertex_conflict_penalty += (count - 1) * (count - 1) * 1000;\n            }\n        }\n        \n        cost += total_importance + vertex_conflict_penalty;\n    }\n    \n    return cost;\n}\n\nvector<int> solve() {\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    // Simple edge importance: weight * degree_factor\n    vector<double> edge_importance(M);\n    vector<int> degree(N, 0);\n    for (auto& [u, v, w] : edges) {\n        degree[u]++;\n        degree[v]++;\n    }\n    for (int e = 0; e < M; e++) {\n        auto [u, v, w] = edges[e];\n        edge_importance[e] = w * (1.0 / degree[u] + 1.0 / degree[v]);\n    }\n    \n    // Sort by importance\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    vector<int> best_schedule;\n    double best_cost = INF;\n    \n    // Multiple attempts (reduced from 15 to 10)\n    for (int trial = 0; trial < 10; trial++) {\n        vector<int> schedule(M);\n        vector<int> day_count(D+1, 0);\n        \n        // Fast greedy: spread important edges across days\n        // Use a round-robin approach for important edges\n        int day_idx = 1;\n        for (int idx = 0; idx < M; idx++) {\n            int e = edge_order[idx];\n            \n            // Find least loaded valid day\n            int best_day = -1;\n            double best_score = INF;\n            \n            // Try days in order, prefer less loaded days\n            vector<pair<int, int>> day_load;\n            for (int d = 1; d <= D; d++) {\n                day_load.push_back({day_count[d], d});\n            }\n            sort(day_load.begin(), day_load.end());\n            \n            for (auto& [load, d] : day_load) {\n                if (load >= K) continue;\n                \n                auto [u, v, w] = edges[e];\n                double score = load * 100;\n                \n                // Add penalty for vertex conflicts with already assigned important edges\n                for (int other = 0; other < M; other++) {\n                    if (other != e && schedule[other] == d) {\n                        auto [ou, ov, ow] = edges[other];\n                        if (ou == u || ou == v || ov == u || ov == v) {\n                            score += edge_importance[other] * 0.1;\n                        }\n                    }\n                }\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_day = d;\n                }\n            }\n            \n            schedule[e] = best_day;\n            day_count[best_day]++;\n        }\n        \n        // Lightweight local search (reduced iterations)\n        double current_cost = quick_evaluate(schedule);\n        double temp = 1.0;\n        \n        for (int iter = 0; iter < 500 && temp > 0.1; iter++) {\n            int e1 = rng() % M;\n            int old_day = schedule[e1];\n            int new_day = rng() % D + 1;\n            \n            if (new_day == old_day || day_count[new_day] >= K) continue;\n            \n            // Quick check: minimize vertex conflicts\n            auto [u, v, w] = edges[e1];\n            \n            // Count conflicts on old day (excluding this edge)\n            int old_conflicts = 0;\n            for (int other = 0; other < M; other++) {\n                if (other != e1 && schedule[other] == old_day) {\n                    auto [ou, ov, ow] = edges[other];\n                    if (ou == u || ou == v || ov == u || ov == v) {\n                        old_conflicts++;\n                    }\n                }\n            }\n            \n            // Count conflicts on new day\n            int new_conflicts = 0;\n            for (int other = 0; other < M; other++) {\n                if (other != e1 && schedule[other] == new_day) {\n                    auto [ou, ov, ow] = edges[other];\n                    if (ou == u || ou == v || ov == u || ov == v) {\n                        new_conflicts++;\n                    }\n                }\n            }\n            \n            double delta = (new_conflicts - old_conflicts) * w * 0.001;\n            \n            if (delta < 0 || exp(-delta / temp) > (double)rng() / RAND_MAX) {\n                schedule[e1] = new_day;\n                day_count[old_day]--;\n                day_count[new_day]++;\n                current_cost += delta;\n            }\n            \n            temp *= 0.99;\n        }\n        \n        double cost = quick_evaluate(schedule);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_schedule = schedule;\n        }\n    }\n    \n    return best_schedule;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\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        graph[u].push_back({v, w});\n        graph[v].push_back({u, w});\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Generate schedule (no expensive precomputation)\n    vector<int> schedule = solve();\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << schedule[i] << (i+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nint D;\nint dx[] = {1, -1, 0, 0, 0, 0};\nint dy[] = {0, 0, 1, -1, 0, 0};\nint dz[] = {0, 0, 0, 0, 1, -1};\n\nstruct Pos {\n    int x, y, z;\n    Pos(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}\n    bool operator<(const Pos& other) const {\n        if (x != other.x) return x < other.x;\n        if (y != other.y) return y < other.y;\n        return z < other.z;\n    }\n    bool operator==(const Pos& other) const {\n        return x == other.x && y == other.y && z == other.z;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read silhouettes\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    \n    for (int i = 0; i < 2; i++) {\n        for (int k = 0; k < D; k++) cin >> f[i][k];\n        for (int k = 0; k < D; k++) cin >> r[i][k];\n    }\n    \n    // Store cubes for each object\n    vector<vector<Pos>> cubes(2);\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                        cubes[i].push_back({x, y, z});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find shared cubes (used in both objects)\n    map<Pos, int> shared_idx;\n    for (auto p : cubes[0]) {\n        if (find(cubes[1].begin(), cubes[1].end(), p) != cubes[1].end()) {\n            shared_idx[p] = shared_idx.size();\n        }\n    }\n    \n    // Assign block IDs greedily\n    // For each object, assign block IDs using BFS/DFS to merge adjacent cubes\n    vector<vector<int>> result(2, vector<int>(D * D * D, 0));\n    vector<set<int>> block_sizes; // Track which object uses which block\n    int block_cnt = 0;\n    map<pair<int, int>, int> block_id_map; // Maps (object_id, cube_position_index) to block_id\n    \n    for (int obj = 0; obj < 2; obj++) {\n        set<Pos> visited;\n        for (auto start : cubes[obj]) {\n            if (visited.count(start)) continue;\n            \n            // BFS to find connected component\n            queue<Pos> q;\n            q.push(start);\n            visited.insert(start);\n            vector<Pos> component;\n            \n            while (!q.empty()) {\n                auto p = q.front(); q.pop();\n                component.push_back(p);\n                \n                for (int d = 0; d < 6; d++) {\n                    Pos np = {p.x + dx[d], p.y + dy[d], p.z + dz[d]};\n                    if (np.x < 0 || np.x >= D || np.y < 0 || np.y >= D || np.z < 0 || np.z >= D) continue;\n                    if (visited.count(np)) continue;\n                    if (find(cubes[obj].begin(), cubes[obj].end(), np) == cubes[obj].end()) continue;\n                    visited.insert(np);\n                    q.push(np);\n                }\n            }\n            \n            // Assign block ID\n            block_cnt++;\n            for (auto p : component) {\n                int idx = p.x * D * D + p.y * D + p.z;\n                result[obj][idx] = block_cnt;\n            }\n        }\n    }\n    \n    // Now try to merge blocks that appear in both objects\n    // For simplicity, we'll keep the current blocks\n    // Output\n    cout << block_cnt << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        for (int j = 0; j < D * D * D; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <cmath>\n#include <random>\nusing namespace std;\n\nstruct Edge {\n    int u, v;\n    long long w;\n};\n\nint N, M, K;\nvector<pair<int,int>> vertices;\nvector<Edge> edges;\nvector<pair<int,int>> residents;\nvector<vector<int>> adj;\nvector<vector<long long>> dist_sq_resident;\nvector<vector<long long>> all_pair_dist;\nvector<vector<long long>> dist_between_stations;\nrandom_device rd;\nmt19937 gen(rd());\n\nvoid read_input() {\n    cin >> N >> M >> K;\n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    edges.resize(M);\n    adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        cin >> edges[j].u >> edges[j].v >> edges[j].w;\n        edges[j].u--; edges[j].v--;\n        adj[edges[j].u].push_back(j);\n        adj[edges[j].v].push_back(j);\n    }\n    residents.resize(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n    \n    dist_sq_resident.assign(N, vector<long long>(K));\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < K; k++) {\n            long long dx = vertices[i].first - residents[k].first;\n            long long dy = vertices[i].second - residents[k].second;\n            dist_sq_resident[i][k] = dx*dx + dy*dy;\n        }\n    }\n    \n    // Precompute Euclidean distances between stations\n    dist_between_stations.assign(N, vector<long long>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            long long dx = vertices[i].first - vertices[j].first;\n            long long dy = vertices[i].second - vertices[j].second;\n            dist_between_stations[i][j] = dx*dx + dy*dy;\n        }\n    }\n}\n\nstruct Solution {\n    vector<int> P;\n    vector<bool> edge_on;\n    vector<bool> reachable;\n    long long total_cost;\n    bool valid;\n    \n    Solution() : P(N, 0), edge_on(M, false), reachable(N, false), total_cost(LLONG_MAX), valid(false) {}\n    \n    void compute_reachable() {\n        fill(reachable.begin(), reachable.end(), false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for (int e_idx : adj[u]) {\n                if (!edge_on[e_idx]) continue;\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                if (!reachable[v]) {\n                    reachable[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n    }\n    \n    bool check_coverage() {\n        for (int k = 0; k < K; k++) {\n            bool ok = false;\n            for (int i = 0; i < N && !ok; i++) {\n                if (!reachable[i] || P[i] == 0) continue;\n                if (dist_sq_resident[i][k] <= (long long)P[i] * P[i]) {\n                    ok = true;\n                }\n            }\n            if (!ok) return false;\n        }\n        return true;\n    }\n    \n    long long get_total_cost() {\n        long long cost = 0;\n        for (int i = 0; i < N; i++) {\n            cost += (long long)P[i] * P[i];\n        }\n        for (int j = 0; j < M; j++) {\n            if (edge_on[j]) cost += edges[j].w;\n        }\n        return cost;\n    }\n    \n    bool is_valid() {\n        for (int i = 0; i < N; i++) {\n            if (P[i] < 0 || P[i] > 5000) return false;\n        }\n        compute_reachable();\n        if (!check_coverage()) return false;\n        total_cost = get_total_cost();\n        valid = true;\n        return true;\n    }\n};\n\nint clamp_power(long long val) {\n    if (val < 0) return 0;\n    if (val > 5000) return 5000;\n    return (int)val;\n}\n\nint compute_required_power(long long dist_sq) {\n    if (dist_sq <= 0) return 0;\n    if (dist_sq >= 5000LL * 5000) return 5000;\n    long long p = (long long)ceil(sqrt((double)dist_sq));\n    return clamp_power(p);\n}\n\n// Compute all-pair shortest paths\nvector<vector<long long>> compute_all_pair_dist() {\n    vector<vector<long long>> dist(N, vector<long long>(N, LLONG_MAX));\n    for (int start = 0; start < N; start++) {\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        dist[start][start] = 0;\n        pq.push({0, start});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[start][u]) continue;\n            for (int e_idx : adj[u]) {\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                long long nd = d + edges[e_idx].w;\n                if (nd < dist[start][v]) {\n                    dist[start][v] = nd;\n                    pq.push({nd, v});\n                }\n            }\n        }\n    }\n    return dist;\n}\n\n// Optimize power levels for a set of active stations\nvoid optimize_powers(Solution& sol, const vector<int>& active_stations) {\n    // First pass: assign residents to nearest reachable station\n    vector<vector<int>> station_residents(N);\n    vector<int> current_assignments(K, -1);\n    \n    for (int k = 0; k < K; k++) {\n        int best_i = -1;\n        long long best_dist = LLONG_MAX;\n        for (int i : active_stations) {\n            if (!sol.reachable[i]) continue;\n            if (dist_sq_resident[i][k] < best_dist) {\n                best_dist = dist_sq_resident[i][k];\n                best_i = i;\n            }\n        }\n        if (best_i != -1) {\n            station_residents[best_i].push_back(k);\n            current_assignments[k] = best_i;\n        }\n    }\n    \n    // Set powers based on assigned residents\n    for (int i : active_stations) {\n        if (!sol.reachable[i] || station_residents[i].empty()) {\n            sol.P[i] = 0;\n            continue;\n        }\n        long long max_sq = 0;\n        for (int k : station_residents[i]) {\n            max_sq = max(max_sq, dist_sq_resident[i][k]);\n        }\n        sol.P[i] = compute_required_power(max_sq);\n    }\n    \n    // Second pass: try to reduce power by sharing with nearby stations\n    for (int iter = 0; iter < 3; iter++) {\n        for (int i : active_stations) {\n            if (sol.P[i] == 0) continue;\n            \n            // Try to give some residents to nearby station\n            for (int j : active_stations) {\n                if (i == j || sol.P[j] == 0) continue;\n                if (dist_between_stations[i][j] > 40000000LL) continue; // too far\n                \n                // Check if j can help cover residents of i\n                long long max_i_sq = 0, max_j_sq = 0;\n                vector<int> new_j_residents;\n                \n                for (int k : station_residents[i]) {\n                    if (dist_sq_resident[j][k] <= (long long)sol.P[j] * sol.P[j]) {\n                        new_j_residents.push_back(k);\n                    } else {\n                        max_i_sq = max(max_i_sq, dist_sq_resident[i][k]);\n                    }\n                }\n                \n                for (int k : station_residents[j]) {\n                    max_j_sq = max(max_j_sq, dist_sq_resident[j][k]);\n                }\n                \n                // If we can reduce i's power\n                if (new_j_residents.size() > 0 && sol.P[i] >= (int)ceil(sqrt(max_i_sq))) {\n                    int new_p_i = compute_required_power(max_i_sq);\n                    if (new_p_i < sol.P[i]) {\n                        sol.P[i] = new_p_i;\n                        // Update station_residents\n                        for (int k : new_j_residents) {\n                            station_residents[j].push_back(k);\n                            station_residents[i].erase(\n                                remove(station_residents[i].begin(), \n                                       station_residents[i].end(), k), \n                                station_residents[i].end());\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Build solution with given active stations\nSolution build_solution(vector<int>& active_stations) {\n    Solution sol;\n    auto shortest = compute_all_pair_dist();\n    \n    // Ensure station 1 is included\n    if (find(active_stations.begin(), active_stations.end(), 0) == active_stations.end()) {\n        active_stations.insert(active_stations.begin(), 0);\n    }\n    \n    // Build tree connecting stations using Prim's\n    vector<bool> in_tree(N, false);\n    in_tree[0] = true;\n    \n    vector<long long> min_dist(N, LLONG_MAX);\n    vector<int> parent_edge(N, -1);\n    \n    auto update_dist = [&](int u) {\n        for (int e_idx : adj[u]) {\n            int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n            if (edges[e_idx].w < min_dist[v]) {\n                min_dist[v] = edges[e_idx].w;\n                parent_edge[v] = e_idx;\n            }\n        }\n    };\n    \n    update_dist(0);\n    \n    // Connect active stations\n    vector<int> remaining;\n    for (int i : active_stations) {\n        if (!in_tree[i]) remaining.push_back(i);\n    }\n    \n    while (!remaining.empty()) {\n        int best = -1;\n        long long best_cost = LLONG_MAX;\n        \n        for (int i : remaining) {\n            if (min_dist[i] < best_cost) {\n                best_cost = min_dist[i];\n                best = i;\n            }\n        }\n        \n        if (best == -1) break;\n        \n        int e_idx = parent_edge[best];\n        if (e_idx != -1) {\n            sol.edge_on[e_idx] = true;\n        }\n        in_tree[best] = true;\n        update_dist(best);\n        \n        remaining.erase(remove(remaining.begin(), remaining.end(), best), remaining.end());\n    }\n    \n    // Connect any remaining stations via shortest paths\n    for (int i : active_stations) {\n        if (in_tree[i]) continue;\n        \n        long long best_dist = LLONG_MAX;\n        int best_start = -1;\n        for (int s : active_stations) {\n            if (in_tree[s] && shortest[s][i] < best_dist) {\n                best_dist = shortest[s][i];\n                best_start = s;\n            }\n        }\n        \n        if (best_start == -1) continue;\n        \n        // Find path\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> parent(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        \n        dist[best_start] = 0;\n        pq.push({0, best_start});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            if (d != dist[u]) continue;\n            if (u == i) break;\n            \n            for (int e_idx : adj[u]) {\n                int v = (edges[e_idx].u == u) ? edges[e_idx].v : edges[e_idx].u;\n                long long nd = d + edges[e_idx].w;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    parent[v] = e_idx;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        int cur = i;\n        while (parent[cur] != -1) {\n            int e_idx = parent[cur];\n            sol.edge_on[e_idx] = true;\n            in_tree[cur] = true;\n            int prev = (edges[e_idx].u == cur) ? edges[e_idx].v : edges[e_idx].u;\n            cur = prev;\n        }\n    }\n    \n    sol.compute_reachable();\n    \n    // Optimize powers\n    vector<int> reachable_stations;\n    for (int i : active_stations) {\n        if (sol.reachable[i]) {\n            reachable_stations.push_back(i);\n        }\n    }\n    \n    optimize_powers(sol, reachable_stations);\n    \n    // Try to reduce by removing unnecessary stations\n    for (int i : active_stations) {\n        if (i == 0) continue;\n        if (!sol.reachable[i] || sol.P[i] == 0) continue;\n        \n        int old_p = sol.P[i];\n        sol.P[i] = 0;\n        \n        if (!sol.check_coverage()) {\n            sol.P[i] = old_p;\n        }\n    }\n    \n    sol.is_valid();\n    return sol;\n}\n\n// Local search to improve solution\nSolution local_search(Solution base_sol, const vector<int>& base_stations) {\n    Solution best_sol = base_sol;\n    vector<int> best_stations = base_stations;\n    long long best_cost = base_sol.total_cost;\n    \n    uniform_int_distribution<int> station_dist(1, N-1);\n    uniform_int_distribution<int> power_dist(100, 500);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    int no_improve = 0;\n    double temperature = 1000.0;\n    \n    for (int iter = 0; iter < 500; iter++) {\n        vector<int> new_stations = best_stations;\n        \n        // Random operation\n        int op = uniform_int_distribution<int>(0, 2)(gen);\n        \n        if (op == 0 && new_stations.size() > 1) {\n            // Remove random station (except 0)\n            int idx = uniform_int_distribution<int>(1, new_stations.size()-1)(gen);\n            new_stations.erase(new_stations.begin() + idx);\n        } else if (op == 1 && new_stations.size() < N) {\n            // Add random station\n            int s = station_dist(gen);\n            if (find(new_stations.begin(), new_stations.end(), s) == new_stations.end()) {\n                new_stations.push_back(s);\n            }\n        } else {\n            // Replace a station\n            if (new_stations.size() > 1) {\n                int idx = uniform_int_distribution<int>(1, new_stations.size()-1)(gen);\n                int old_s = new_stations[idx];\n                int new_s = station_dist(gen);\n                if (find(new_stations.begin(), new_stations.end(), new_s) == new_stations.end()) {\n                    new_stations[idx] = new_s;\n                }\n            }\n        }\n        \n        Solution new_sol = build_solution(new_stations);\n        \n        if (new_sol.valid && new_sol.total_cost < best_cost) {\n            best_sol = new_sol;\n            best_stations = new_stations;\n            best_cost = new_sol.total_cost;\n            no_improve = 0;\n            \n            // Also try to refine further by removing redundant stations\n            for (int i : new_stations) {\n                if (i == 0) continue;\n                int old_p = best_sol.P[i];\n                best_sol.P[i] = 0;\n                if (!best_sol.check_coverage()) {\n                    best_sol.P[i] = old_p;\n                }\n            }\n            best_sol.is_valid();\n            if (best_sol.valid && best_sol.total_cost < best_cost) {\n                best_cost = best_sol.total_cost;\n            }\n        } else if (new_sol.valid && prob_dist(gen) < exp(-(new_sol.total_cost - best_cost) / temperature)) {\n            best_sol = new_sol;\n            best_stations = new_stations;\n        }\n        \n        temperature *= 0.995;\n        no_improve++;\n        if (no_improve > 100) break;\n    }\n    \n    return best_sol;\n}\n\nSolution solve() {\n    auto shortest = compute_all_pair_dist();\n    \n    // Greedy station selection\n    vector<bool> resident_covered(K, false);\n    vector<int> active_stations = {0};\n    \n    // Cover with station 1\n    for (int k = 0; k < K; k++) {\n        if (dist_sq_resident[0][k] <= 5000LL * 5000) {\n            resident_covered[k] = true;\n        }\n    }\n    \n    // Greedy selection\n    while (true) {\n        bool all_covered = true;\n        for (int k = 0; k < K; k++) {\n            if (!resident_covered[k]) { all_covered = false; break; }\n        }\n        if (all_covered) break;\n        \n        int best_i = -1;\n        double best_score = 0;\n        \n        for (int i = 1; i < N; i++) {\n            if (find(active_stations.begin(), active_stations.end(), i) != active_stations.end()) \n                continue;\n            \n            int new_residents = 0;\n            long long max_sq = 0;\n            \n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k]) {\n                    long long d = dist_sq_resident[i][k];\n                    if (d <= 5000LL * 5000) {\n                        new_residents++;\n                        max_sq = max(max_sq, d);\n                    }\n                }\n            }\n            \n            if (new_residents == 0) continue;\n            \n            long long min_edge = LLONG_MAX;\n            for (int s : active_stations) {\n                min_edge = min(min_edge, shortest[s][i]);\n            }\n            \n            if (min_edge >= LLONG_MAX / 2) continue;\n            \n            int power_needed = compute_required_power(max_sq);\n            double score = (double)new_residents * new_residents / \n                          (power_needed * power_needed + min_edge + 1);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_i = i;\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        active_stations.push_back(best_i);\n        for (int k = 0; k < K; k++) {\n            if (!resident_covered[k] && dist_sq_resident[best_i][k] <= 5000LL * 5000) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    Solution sol = build_solution(active_stations);\n    \n    // Try local search for improvement\n    sol = local_search(sol, active_stations);\n    \n    return sol;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    read_input();\n    Solution sol = solve();\n    \n    // Final validation\n    if (!sol.valid) {\n        // Fallback: use all stations with all edges\n        sol.edge_on.assign(M, true);\n        sol.compute_reachable();\n        vector<int> all_stations(N);\n        iota(all_stations.begin(), all_stations.end(), 0);\n        optimize_powers(sol, all_stations);\n        sol.is_valid();\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << clamp_power(sol.P[i]) << (i+1 == N ? '\\n' : ' ');\n    }\n    for (int j = 0; j < M; j++) {\n        cout << (sol.edge_on[j] ? 1 : 0) << (j+1 == M ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint grid[N][N];\nvector<tuple<int,int,int,int>> ops;\n\nvoid my_swap(int x1, int y1, int x2, int y2) {\n    ops.push_back({x1, y1, x2, y2});\n    swap(grid[x1][y1], grid[x2][y2]);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j <= i; j++)\n            cin >> grid[i][j];\n    \n    // Phase 1: Single bottom-up pass (catches most violations)\n    for (int x = N - 2; x >= 0 && ops.size() < 9900; x--) {\n        for (int y = 0; y <= x && ops.size() < 9900; y++) {\n            int val = grid[x][y];\n            int left = grid[x+1][y];\n            int right = grid[x+1][y+1];\n            \n            if (val > left || val > right) {\n                // Swap with smaller child\n                if (left <= right) {\n                    my_swap(x, y, x+1, y);\n                } else {\n                    my_swap(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Queue-based refinement with priority on largest violations\n    // Use a set of positions that might have violations\n    set<pair<int,int>> violations;\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n                violations.insert({x, y});\n            }\n        }\n    }\n    \n    while (!violations.empty() && ops.size() < 9990) {\n        // Pick the violation with largest difference\n        auto it = max_element(violations.begin(), violations.end(),\n            [&](const pair<int,int>& a, const pair<int,int>& b) {\n                int diff_a = max(0, grid[a.first][a.second] - min(grid[a.first+1][a.second], grid[a.first+1][a.second+1]));\n                int diff_b = max(0, grid[b.first][b.second] - min(grid[b.first+1][b.second], grid[b.first+1][b.second+1]));\n                return diff_a < diff_b;\n            });\n        \n        auto [x, y] = *it;\n        violations.erase(it);\n        \n        if (x >= N - 1) continue;\n        \n        int val = grid[x][y];\n        int left = grid[x+1][y];\n        int right = grid[x+1][y+1];\n        \n        if (val > left || val > right) {\n            int nx, ny;\n            if (left <= right) {\n                nx = x + 1; ny = y;\n            } else {\n                nx = x + 1; ny = y + 1;\n            }\n            \n            my_swap(x, y, nx, ny);\n            \n            // Re-check affected positions\n            auto add_violation = [&](int px, int py) {\n                if (px < 0 || px >= N - 1 || py < 0 || py > px) return;\n                if (grid[px][py] > grid[px+1][py] || grid[px][py] > grid[px+1][py+1]) {\n                    violations.insert({px, py});\n                } else {\n                    violations.erase({px, py});\n                }\n            };\n            \n            // Check parent positions\n            if (x > 0) {\n                add_violation(x-1, y);\n                if (y > 0) add_violation(x-1, y-1);\n            }\n            \n            // Check child positions\n            if (nx < N - 1) {\n                add_violation(nx, ny);\n            }\n            \n            // Re-check current position\n            add_violation(x, y);\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for (auto [x1, y1, x2, y2] : ops) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/dsu>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n, m;\nvector<vector<int>> input, output;\n\n// Check if adjacency relationships are preserved for the current output\nbool checkAdjacencies() {\n    // For each pair of colors (0..M), check if their adjacency status matches input\n    for (int c = 0; c <= m; c++) {\n        for (int d = c + 1; d <= m; d++) {\n            bool adjInput = false, adjOutput = false;\n            \n            // Check input adjacency (excluding boundary for now)\n            for (int i = 0; i < n && !adjInput; i++) {\n                for (int j = 0; j < n && !adjInput; j++) {\n                    if (input[i][j] == c || input[i][j] == d) {\n                        // Check neighbors\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (input[i][j] == c && input[ni][nj] == d) adjInput = true;\n                                if (input[i][j] == d && input[ni][nj] == c) adjInput = true;\n                            } else if (input[i][j] == 0) {\n                                // Boundary tile of color 0\n                                adjInput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Check output adjacency\n            for (int i = 0; i < n && !adjOutput; i++) {\n                for (int j = 0; j < n && !adjOutput; j++) {\n                    if (output[i][j] == c) {\n                        int di[] = {0, 1, 0, -1};\n                        int dj[] = {1, 0, -1, 0};\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) {\n                                if (output[ni][nj] == d) adjOutput = true;\n                            } else {\n                                // Cell is on boundary - adjacent to color 0\n                                if (d == 0) adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Also check for c=0: cells on boundary are adjacent to color 0\n            if (c == 0) {\n                for (int i = 0; i < n && !adjOutput; i++) {\n                    for (int j = 0; j < n && !adjOutput; j++) {\n                        if (output[i][j] == d) {\n                            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                                adjOutput = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (adjInput != adjOutput) return false;\n        }\n    }\n    return true;\n}\n\n// Check connectivity for all colors (including 0)\nbool checkConnectivity() {\n    // For each color, check if its cells are connected (4-directional)\n    for (int c = 0; c <= m; c++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] == c) {\n                    cells.push_back({i, j});\n                }\n            }\n        }\n        \n        if (cells.empty()) continue;\n        \n        // BFS to check connectivity\n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(n, vector<bool>(n, false));\n        q.push(cells[0]);\n        visited[cells[0].first][cells[0].second] = true;\n        int count = 0;\n        \n        while (!q.empty()) {\n            auto [i, j] = q.front(); q.pop();\n            count++;\n            \n            int di[] = {0, 1, 0, -1};\n            int dj[] = {1, 0, -1, 0};\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) {\n                    if (!visited[ni][nj] && output[ni][nj] == c) {\n                        visited[ni][nj] = true;\n                        q.push({ni, nj});\n                    }\n                } else if (c == 0) {\n                    // Color 0 can connect through outside\n                    // Already counted as connected if adjacent to boundary\n                }\n            }\n        }\n        \n        if (count != (int)cells.size()) return false;\n    }\n    return true;\n}\n\n// Check if a cell can be safely set to 0 (empty)\nbool canSetToZero(int i, int j, int originalColor) {\n    int saved = output[i][j];\n    output[i][j] = 0;\n    \n    // Check constraints\n    bool valid = checkAdjacencies() && checkConnectivity();\n    \n    output[i][j] = saved;\n    return valid;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    input.assign(n, vector<int>(n));\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input[i][j];\n        }\n    }\n    \n    // Start with a copy of input\n    output = input;\n    \n    // Multiple passes to remove unnecessary cells\n    for (int pass = 0; pass < 10; pass++) {\n        // Collect all cells that might be removable\n        vector<pair<int,int>> candidates;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (output[i][j] > 0) {\n                    // Check if this color appears elsewhere\n                    bool hasOtherCell = false;\n                    for (int ii = 0; ii < n && !hasOtherCell; ii++) {\n                        for (int jj = 0; jj < n && !hasOtherCell; jj++) {\n                            if ((ii != i || jj != j) && output[ii][jj] == output[i][j]) {\n                                hasOtherCell = true;\n                            }\n                        }\n                    }\n                    if (hasOtherCell) {\n                        candidates.push_back({i, j});\n                    }\n                }\n            }\n        }\n        \n        // Shuffle candidates for randomness\n        random_device rd;\n        mt19937 g(rd());\n        shuffle(candidates.begin(), candidates.end(), g);\n        \n        // Try to remove cells\n        for (auto [i, j] : candidates) {\n            int originalColor = output[i][j];\n            if (originalColor == 0) continue;\n            \n            if (canSetToZero(i, j, originalColor)) {\n                output[i][j] = 0;\n            }\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << output[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint N, D, Q;\nint queries = 0;\n\nchar compare(int a, int b) {\n    if (a == b || queries >= Q) return '=';\n    queries++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    cout.flush();\n    string s; cin >> s;\n    return s[0];\n}\n\nchar compare_set(const vector<int>& L, const vector<int>& R) {\n    if (L.empty() || R.empty() || queries >= Q) return '=';\n    queries++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    string s; cin >> s;\n    return s[0];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> D >> Q;\n    \n    // Phase 1: Build sorted order using insertion sort with binary search\n    // This is more query-efficient than bubble sort\n    vector<int> order;\n    order.push_back(0);\n    \n    int sort_budget = Q * 3 / 10; // Use 30% of queries for sorting\n    \n    for (int i = 1; i < N && queries < sort_budget; i++) {\n        // Binary search to find insertion position\n        int lo = 0, hi = (int)order.size();\n        while (lo < hi && queries < sort_budget) {\n            int mid = (lo + hi) / 2;\n            char res = compare(i, order[mid]);\n            \n            if (res == '<') {\n                hi = mid;\n            } else if (res == '>') {\n                lo = mid + 1;\n            } else {\n                lo = mid;\n                break;\n            }\n        }\n        order.insert(order.begin() + lo, i);\n    }\n    \n    // Add remaining items (those we didn't have queries to sort)\n    set<int> in_order(order.begin(), order.end());\n    for (int i = 0; i < N; i++) {\n        if (!in_order.count(i)) {\n            order.push_back(i);\n        }\n    }\n    \n    // Phase 2: Learn relative weights through group comparisons\n    // We'll use a tournament approach to compare groups of items\n    int remaining = Q - queries;\n    int weight_learn_budget = remaining * 3 / 5;\n    \n    // Create initial weights based on position in sorted order\n    vector<double> weights(N, 1.0);\n    for (int i = 0; i < N; i++) {\n        weights[order[i]] = 1.0 + (double)i / N * 10.0; // Linear scaling\n    }\n    \n    // Phase 3: Create initial groups using greedy\n    vector<vector<int>> groups(D);\n    vector<double> group_weights(D, 0);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = order[i];\n        double w = weights[item];\n        \n        int best = 0;\n        for (int j = 1; j < D; j++) {\n            if (group_weights[j] < group_weights[best]) {\n                best = j;\n            }\n        }\n        \n        groups[best].push_back(item);\n        group_weights[best] += w;\n    }\n    \n    // Phase 4: Systematic refinement using actual comparisons\n    remaining = Q - queries;\n    \n    // Use remaining queries to compare and balance groups\n    for (int iter = 0; iter < min(remaining / 2, 50) && remaining >= 2; iter++) {\n        // Compare all pairs of groups to find imbalances\n        vector<pair<double, pair<int,int>>> imbalances;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = i + 1; j < D; j++) {\n                if (groups[i].empty() || groups[j].empty()) continue;\n                double diff = abs(group_weights[i] - group_weights[j]);\n                imbalances.push_back({diff, {i, j}});\n            }\n        }\n        \n        if (imbalances.empty()) break;\n        \n        // Sort by imbalance (largest first)\n        sort(imbalances.rbegin(), imbalances.rend());\n        \n        bool improved = false;\n        for (auto& p : imbalances) {\n            if (remaining < 2) break;\n            \n            int g1 = p.second.first;\n            int g2 = p.second.second;\n            \n            // Compare the groups\n            remaining--;\n            char real_res = compare_set(groups[g1], groups[g2]);\n            \n            if (real_res == '=') {\n                // Groups are equal, update estimates\n                double avg = (group_weights[g1] + group_weights[g2]) / 2;\n                group_weights[g1] = avg;\n                group_weights[g2] = avg;\n                continue;\n            }\n            \n            int heavy = (real_res == '>') ? g1 : g2;\n            int light = (real_res == '>') ? g2 : g1;\n            \n            // Try to move one item from heavy to light\n            if (groups[heavy].size() <= 1) continue;\n            \n            // Find the best item to move (one that doesn't overcorrect)\n            int best_item = -1;\n            double best_balance = 1e9;\n            \n            for (int k = 0; k < min(5, (int)groups[heavy].size()); k++) {\n                int idx = uniform_int_distribution<int>(0, (int)groups[heavy].size() - 1)(rng);\n                int candidate = groups[heavy][idx];\n                double new_heavy = group_weights[heavy] - weights[candidate];\n                double new_light = group_weights[light] + weights[candidate];\n                double balance = abs(new_heavy - new_light);\n                \n                if (balance < best_balance) {\n                    best_balance = balance;\n                    best_item = idx;\n                }\n            }\n            \n            if (best_item == -1) continue;\n            \n            // Perform the move\n            int item = groups[heavy][best_item];\n            double item_w = weights[item];\n            \n            groups[heavy].erase(groups[heavy].begin() + best_item);\n            groups[light].push_back(item);\n            \n            remaining--;\n            char verify = compare_set(groups[heavy], groups[light]);\n            \n            if (verify == '>') {\n                // Still heavy, keep the move (improved)\n                group_weights[heavy] -= item_w;\n                group_weights[light] += item_w;\n                improved = true;\n            } else if (verify == '<') {\n                // Overcorrected, revert\n                groups[light].pop_back();\n                groups[heavy].insert(groups[heavy].begin() + best_item, item);\n            } else {\n                // Perfect balance!\n                group_weights[heavy] -= item_w;\n                group_weights[light] += item_w;\n                improved = true;\n                break;\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Consume remaining queries\n    while (queries < Q) {\n        compare(0, min(1, N - 1));\n    }\n    \n    // Output\n    vector<int> assignment(N);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << (i ? \" \" : \"\") << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int n = 200, m = 10;\n    const int h = n / m; // 20\n    \n    // Read input\n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(h);\n        for (int j = 0; j < h; j++) {\n            cin >> stacks[i][j];\n        }\n        reverse(stacks[i].begin(), stacks[i].end()); // top is at back\n    }\n    \n    vector<array<int, 2>> operations;\n    int next_to_remove = 1;\n    \n    // Helper to remove from top\n    auto try_remove = [&]() -> bool {\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_to_remove) {\n                stacks[i].pop_back();\n                operations.push_back({next_to_remove, 0});\n                next_to_remove++;\n                return true;\n            }\n        }\n        return false;\n    };\n    \n    // Helper to find stack containing a given box\n    auto find_stack = [&](int v) -> 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] == v) return i;\n            }\n        }\n        return -1;\n    };\n    \n    // Remove easily accessible boxes first\n    while (true) {\n        bool removed = try_remove();\n        if (!removed) break;\n    }\n    \n    // Process remaining boxes\n    while (next_to_remove <= n) {\n        int target_stack = find_stack(next_to_remove);\n        if (target_stack == -1) {\n            break;\n        }\n        \n        auto& st = stacks[target_stack];\n        // Find position of target box (from top, which is back)\n        int pos = -1;\n        for (int i = 0; i < (int)st.size(); i++) {\n            if (st[i] == next_to_remove) {\n                pos = i;\n                break;\n            }\n        }\n        \n        if (pos == (int)st.size() - 1) {\n            // It's already on top\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n            continue;\n        }\n        \n        // Need to move boxes above it\n        // Find best destination: stack with smallest top, or empty stack\n        int best_dest = -1;\n        int best_top = n + 1;\n        for (int i = 0; i < m; i++) {\n            if (i == target_stack) continue;\n            if (stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n            if (stacks[i].back() < best_top) {\n                best_top = stacks[i].back();\n                best_dest = i;\n            }\n        }\n        \n        // Move boxes from position pos+1 to end to best_dest\n        int k = (int)st.size() - pos - 1;\n        // Move in one operation by moving the top box v = st[pos+1]\n        if (k > 0) {\n            int v = st[pos + 1];\n            operations.push_back({v, best_dest});\n            // Update stacks\n            vector<int> moved(st.begin() + pos + 1, st.end());\n            st.resize(pos + 1);\n            for (int x : moved) {\n                stacks[best_dest].push_back(x);\n            }\n        }\n        \n        // Now remove the target box\n        if (!st.empty() && st.back() == next_to_remove) {\n            st.pop_back();\n            operations.push_back({next_to_remove, 0});\n            next_to_remove++;\n        }\n        \n        // Try to remove any consecutive boxes that are now on top\n        while (true) {\n            bool removed = try_remove();\n            if (!removed) break;\n        }\n        \n        if (operations.size() > 5000) break;\n    }\n    \n    // Output\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 40;\nconst int MAX_CELL = MAX_N * MAX_N;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\n\nconst int di[4] = {0, 1, 0, -1};\nconst int dj[4] = {1, 0, -1, 0};\nconst char dirChar[4] = {'R', 'D', 'L', 'U'};\n\nint cellId(int i, int j) { return i * N + j; }\n\nvector<int> neighbors[MAX_CELL];\nint dist[MAX_CELL][MAX_CELL];\n\nvoid buildGraph() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int u = cellId(i, j);\n            if (j + 1 < N && v[i][j] == '0') {\n                int vv = cellId(i, j+1);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n            if (i + 1 < N && h[i][j] == '0') {\n                int vv = cellId(i+1, j);\n                neighbors[u].push_back(vv);\n                neighbors[vv].push_back(u);\n            }\n        }\n    }\n}\n\nvoid precomputeDistances() {\n    int total = N * N;\n    for (int src = 0; src < total; src++) {\n        fill(dist[src], dist[src] + total, 1e9);\n        queue<int> q;\n        dist[src][src] = 0;\n        q.push(src);\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int nb : neighbors[u]) {\n                if (dist[src][nb] == 1e9) {\n                    dist[src][nb] = dist[src][u] + 1;\n                    q.push(nb);\n                }\n            }\n        }\n    }\n}\n\n// DFS coverage (Euler tour)\nvoid dfsCover(int i, int j, vector<vector<bool>>& vis, string& route) {\n    vis[i][j] = true;\n    for (int dir = 0; dir < 4; dir++) {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (dir == 0 && v[i][j] == '1') continue;\n        if (dir == 1 && h[i][j] == '1') continue;\n        if (dir == 2 && v[i][j-1] == '1') continue;\n        if (dir == 3 && h[i-1][j] == '1') continue;\n        if (!vis[ni][nj]) {\n            route.push_back(dirChar[dir]);\n            dfsCover(ni, nj, vis, route);\n            route.push_back(dirChar[(dir+2)%4]);\n        }\n    }\n}\n\n// Get path from src to dst as list of direction indices\nvector<int> getPath(int src, int dst) {\n    vector<int> path;\n    int cur = src;\n    while (cur != dst) {\n        for (int nb : neighbors[cur]) {\n            if (dist[nb][dst] == dist[cur][dst] - 1) {\n                // Determine direction\n                int ci = cur / N, cj = cur % N;\n                int ni = nb / N, nj = nb % N;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (ci + di[dir] == ni && cj + dj[dir] == nj) {\n                        path.push_back(dir);\n                        break;\n                    }\n                }\n                cur = nb;\n                break;\n            }\n        }\n    }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    cin >> N;\n    h.resize(N-1);\n    v.resize(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    d.assign(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> d[i][j];\n\n    buildGraph();\n    precomputeDistances();\n\n    const int MAX_MOVES = 100000;\n    int totalCells = N * N;\n\n    // Phase 1: DFS coverage\n    vector<vector<bool>> vis(N, vector<bool>(N, false));\n    string route;\n    route.reserve(MAX_MOVES);\n    dfsCover(0, 0, vis, route);\n    int dfsLen = (int)route.size();\n\n    // Initialize dirt state after DFS\n    vector<vector<int>> dirt(N, vector<int>(N, 0));\n    int curPos = 0;\n    {\n        int ci = 0, cj = 0;\n        for (char ch : route) {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n            int dir = -1;\n            if (ch == 'R') dir = 0;\n            else if (ch == 'D') dir = 1;\n            else if (ch == 'L') dir = 2;\n            else if (ch == 'U') dir = 3;\n            ci += di[dir]; cj += dj[dir];\n            dirt[ci][cj] = 0;\n        }\n        curPos = 0;\n    }\n\n    int remainingSteps = MAX_MOVES - dfsLen;\n    int stepsUsed = 0;\n\n    // We'll repeatedly find the best cell to visit, compute full path, and execute it\n    while (stepsUsed < remainingSteps) {\n        // Check if remaining steps are enough to return to origin\n        if (remainingSteps - stepsUsed <= dist[curPos][0] + 2) {\n            // Need to start heading back\n            break;\n        }\n\n        // Find the cell with the highest \"urgency\" = d * (time since last visit)\n        // But we also consider how many more times we want to visit it\n        // Target visit count proportional to sqrt(d)\n        \n        int bestTarget = -1;\n        double bestScore = -1e18;\n        \n        for (int id = 0; id < totalCells; id++) {\n            if (id == curPos) continue; // already here\n            \n            int i = id / N, j = id % N;\n            \n            // Urgency = current dirt accumulation\n            double urgency = (double)dirt[i][j] / (1 + d[i][j]); // normalize by dirt rate\n            \n            // Score = urgency / distance (prioritize nearby high-urgency cells)\n            double score = urgency / (1 + dist[curPos][id]);\n            \n            // Add bonus for cells with high dirt rate (break ties)\n            score += (double)d[i][j] / 100000.0;\n            \n            if (score > bestScore) {\n                bestScore = score;\n                bestTarget = id;\n            }\n        }\n        \n        if (bestTarget == -1) break;\n        \n        // Compute full path to bestTarget\n        vector<int> path = getPath(curPos, bestTarget);\n        \n        // Check if we have enough steps for this path + eventual return\n        if (stepsUsed + (int)path.size() + dist[bestTarget][0] > remainingSteps) {\n            // Can't make this trip, try a shorter one\n            // Sort targets by distance and try the closest feasible one\n            vector<pair<int,int>> candidates; // (distance, id)\n            for (int id = 0; id < totalCells; id++) {\n                if (id == curPos) continue;\n                candidates.push_back({dist[curPos][id], id});\n            }\n            sort(candidates.begin(), candidates.end());\n            \n            bool found = false;\n            for (auto& p : candidates) {\n                int id = p.second;\n                vector<int> shortPath = getPath(curPos, id);\n                if (stepsUsed + (int)shortPath.size() + dist[id][0] <= remainingSteps) {\n                    path = shortPath;\n                    bestTarget = id;\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) break;\n        }\n        \n        // Execute the path\n        for (int dir : path) {\n            route.push_back(dirChar[dir]);\n            int ci = curPos / N, cj = curPos % N;\n            int ni = ci + di[dir], nj = cj + dj[dir];\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dirt[i][j] += d[i][j];\n            curPos = cellId(ni, nj);\n            dirt[ni][nj] = 0;\n            stepsUsed++;\n        }\n    }\n\n    // Return to origin\n    vector<int> returnPath = getPath(curPos, 0);\n    for (int dir : returnPath) {\n        route.push_back(dirChar[dir]);\n    }\n\n    // Ensure length\n    if ((int)route.size() > MAX_MOVES) {\n        route.resize(MAX_MOVES);\n    }\n\n    cout << route << endl;\n\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<pair<int,int>> char_pos[26];\nconst int INF = 1e9;\n\nvoid precompute() {\n    for (int c = 0; c < 26; c++) {\n        char_pos[c].clear();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == 'A' + c) {\n                    char_pos[c].push_back({i, j});\n                }\n            }\n        }\n    }\n}\n\n// Find optimal path for a sequence using DP with state reconstruction\nvector<pair<int,int>> get_optimal_path(const string& s, int start_i, int start_j) {\n    int len = s.size();\n    if (len == 0) return {};\n    \n    // Store DP states for each position\n    vector<vector<vector<int>>> dp_states(len, vector<vector<int>>(N, vector<int>(N, INF)));\n    vector<vector<vector<pair<int,int>>>> prev_states(len, vector<vector<pair<int,int>>>(N, vector<pair<int,int>>(N, {-1, -1})));\n    \n    // First character\n    int c0 = s[0] - 'A';\n    for (auto& p : char_pos[c0]) {\n        dp_states[0][p.first][p.second] = abs(p.first - start_i) + abs(p.second - start_j) + 1;\n        prev_states[0][p.first][p.second] = {start_i, start_j};\n    }\n    \n    // Remaining characters\n    for (int pos = 1; pos < len; pos++) {\n        int target_char = s[pos] - 'A';\n        int prev_char = s[pos-1] - 'A';\n        \n        for (auto& target : char_pos[target_char]) {\n            int ti = target.first, tj = target.second;\n            int min_cost = INF;\n            int best_pi = -1, best_pj = -1;\n            \n            for (auto& prevp : char_pos[prev_char]) {\n                int pi = prevp.first, pj = prevp.second;\n                if (dp_states[pos-1][pi][pj] >= INF) continue;\n                \n                int cost = dp_states[pos-1][pi][pj] + \n                          abs(ti - pi) + abs(tj - pj) + 1;\n                if (cost < min_cost) {\n                    min_cost = cost;\n                    best_pi = pi;\n                    best_pj = pj;\n                }\n            }\n            \n            if (min_cost < INF) {\n                dp_states[pos][ti][tj] = min_cost;\n                prev_states[pos][ti][tj] = {best_pi, best_pj};\n            }\n        }\n    }\n    \n    // Find best end position\n    int last_char = s[len-1] - 'A';\n    int best_i = -1, best_j = -1, best_cost = INF;\n    for (auto& p : char_pos[last_char]) {\n        if (dp_states[len-1][p.first][p.second] < best_cost) {\n            best_cost = dp_states[len-1][p.first][p.second];\n            best_i = p.first;\n            best_j = p.second;\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> path(len);\n    int ci = best_i, cj = best_j;\n    for (int pos = len-1; pos >= 0; pos--) {\n        path[pos] = {ci, cj};\n        if (pos > 0) {\n            auto prev = prev_states[pos][ci][cj];\n            ci = prev.first;\n            cj = prev.second;\n        }\n    }\n    \n    return path;\n}\n\n// Compute overlap between suffix of a and prefix of b\nint get_overlap(const string& a, const string& b) {\n    int max_len = min((int)a.size(), (int)b.size());\n    for (int len = max_len; len >= 0; len--) {\n        bool match = true;\n        for (int k = 0; k < len; k++) {\n            if (a[a.size() - len + k] != b[k]) {\n                match = false;\n                break;\n            }\n        }\n        if (match) return len;\n    }\n    return 0;\n}\n\n// Build superstring with cost-aware greedy selection\nstring build_superstring(int& estimated_cost) {\n    // Find best starting word considering both overlap potential and position\n    int best_start = 0;\n    double best_start_score = -INF;\n    \n    for (int i = 0; i < M; i++) {\n        double start_cost = INF;\n        for (auto& p : char_pos[words[i][0] - 'A']) {\n            double cost = abs(p.first - si) + abs(p.second - sj) + 1;\n            start_cost = min(start_cost, cost);\n        }\n        \n        // Count potential overlaps with other words\n        int total_overlap = 0;\n        for (int j = 0; j < M; j++) {\n            if (i != j) {\n                total_overlap += get_overlap(words[i], words[j]);\n                total_overlap += get_overlap(words[j], words[i]);\n            }\n        }\n        \n        double score = total_overlap / (double)M - start_cost / 100.0;\n        if (score > best_start_score) {\n            best_start_score = score;\n            best_start = i;\n        }\n    }\n    \n    string result = words[best_start];\n    vector<bool> used(M, false);\n    used[best_start] = true;\n    estimated_cost = 0;\n    \n    // Add initial estimated cost\n    for (auto& p : char_pos[result[0] - 'A']) {\n        estimated_cost = min(estimated_cost + INF, \n                           abs(p.first - si) + abs(p.second - sj) + 1);\n    }\n    \n    while (true) {\n        // Check completion\n        bool all_done = true;\n        for (int i = 0; i < M; i++) {\n            if (!used[i]) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) break;\n        \n        // Mark contained words\n        bool contained = false;\n        for (int i = 0; i < M; i++) {\n            if (!used[i] && result.find(words[i]) != string::npos) {\n                used[i] = true;\n                contained = true;\n            }\n        }\n        if (contained) continue;\n        \n        // Find best word using multi-factor scoring\n        int best_word = -1;\n        double best_score = -INF;\n        int best_overlap = 0;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            \n            int ov = get_overlap(result, words[i]);\n            \n            // Score: high overlap + low movement + potential for future overlaps\n            double score = ov * 10.0;  // Strong weight on overlap\n            \n            // Bonus for common characters (potential future overlaps)\n            int common_chars = 0;\n            for (char c : words[i]) {\n                for (int j = 0; j < M; j++) {\n                    if (!used[j] && j != i) {\n                        if (words[j].find(c) != string::npos) {\n                            common_chars++;\n                        }\n                    }\n                }\n            }\n            score += common_chars / 100.0;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_word = i;\n                best_overlap = ov;\n            }\n        }\n        \n        if (best_word == -1) {\n            for (int i = 0; i < M; i++) {\n                if (!used[i]) {\n                    best_word = i;\n                    best_overlap = 0;\n                    break;\n                }\n            }\n        }\n        \n        if (best_word != -1) {\n            result += words[best_word].substr(best_overlap);\n            used[best_word] = true;\n            estimated_cost += (5 - best_overlap) * 3;  // rough estimate\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    cin >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    words.resize(M);\n    for (int i = 0; i < M; i++) cin >> words[i];\n    \n    precompute();\n    \n    // Build superstring with better word selection\n    int est_cost;\n    string result = build_superstring(est_cost);\n    \n    // Compute optimal path using stored DP states\n    auto path = get_optimal_path(result, si, sj);\n    \n    // Output\n    int limit = min((int)path.size(), 5000);\n    for (int i = 0; i < limit; i++) {\n        cout << path[i].first << \" \" << path[i].second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <cstdio>\n#include <set>\n#include <vector>\n#include <utility>\nusing namespace std;\n\nint main() {\n    setvbuf(stdin, NULL, _IONBF, 0);\n    setvbuf(stdout, NULL, _IONBF, 0);\n    \n    int N, M;\n    double eps;\n    scanf(\"%d %d %lf\", &N, &M, &eps);\n    \n    // Read shapes\n    vector<vector<pair<int,int>>> shapes(M);\n    for (int k = 0; k < M; k++) {\n        int d;\n        scanf(\"%d\", &d);\n        shapes[k].resize(d);\n        for (int t = 0; t < d; t++) {\n            scanf(\"%d %d\", &shapes[k][t].first, &shapes[k][t].second);\n        }\n    }\n    \n    // Mark reachable cells\n    vector<vector<bool>> reachable(N, vector<bool>(N, false));\n    for (int k = 0; k < M; k++) {\n        int max_i = 0, max_j = 0;\n        for (auto [di, dj] : shapes[k]) {\n            max_i = max(max_i, di);\n            max_j = max(max_j, dj);\n        }\n        for (int pi = 0; pi + max_i < N; pi++) {\n            for (int pj = 0; pj + max_j < N; pj++) {\n                for (auto [di, dj] : shapes[k]) {\n                    reachable[pi + di][pj + dj] = true;\n                }\n            }\n        }\n    }\n    \n    // Drill reachable cells only\n    set<pair<int,int>> oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!reachable[i][j]) continue;\n            \n            printf(\"q 1 %d %d\\n\", i, j);\n            fflush(stdout);\n            int v;\n            scanf(\"%d\", &v);\n            if (v > 0) {\n                oil.insert({i, j});\n            }\n        }\n    }\n    \n    // Make guess\n    printf(\"a %d\", (int)oil.size());\n    for (auto [i, j] : oil) {\n        printf(\" %d %d\", i, j);\n    }\n    printf(\"\\n\");\n    fflush(stdout);\n    \n    int result;\n    scanf(\"%d\", &result);\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    vector<int> prev_heights(N, 0);\n    \n    for (int d = 0; d < D; d++) {\n        // Calculate minimum and maximum heights for each reservation\n        vector<int> min_h(N), max_h(N);\n        int total_min = 0, total_max = 0;\n        \n        for (int k = 0; k < N; k++) {\n            min_h[k] = max(1, (a[d][k] + W - 1) / W);  // at least 1, ceil division\n            max_h[k] = W;  // upper bound (will be constrained later)\n            total_min += min_h[k];\n        }\n        \n        // If total minimum exceeds W, we need to force sharing\n        if (total_min > W) {\n            // Scale proportionally but keep all \u2265 1\n            int remaining = W;\n            for (int k = 0; k < N; k++) {\n                int h = max(1, remaining / (N - k));\n                min_h[k] = min(min_h[k], h);\n                remaining -= min_h[k];\n            }\n            total_min = W;\n        }\n        \n        // DP: dp[h] = min cost for processed reservations using total height h\n        const int INF = 1e9;\n        vector<int> dp(W + 1, INF);\n        dp[0] = 0;\n        \n        for (int k = 0; k < N; k++) {\n            vector<int> ndp(W + 1, INF);\n            \n            for (int cur_h = 0; cur_h <= W; cur_h++) {\n                if (dp[cur_h] >= INF) continue;\n                \n                // Maximum height we can give to this reservation\n                int max_possible = W - cur_h - (N - k - 1);  // leave at least 1 for each remaining\n                if (max_possible < min_h[k]) continue;\n                \n                for (int h = min_h[k]; h <= max_possible && cur_h + h <= W; h++) {\n                    // Area penalty\n                    int area = h * W;\n                    int penalty = max(0, 100 * (a[d][k] - area));\n                    \n                    // Partition change cost\n                    int change_cost = 0;\n                    if (d > 0) {\n                        change_cost = abs(h - prev_heights[k]);\n                    }\n                    \n                    int total = dp[cur_h] + penalty + change_cost;\n                    if (total < ndp[cur_h + h]) {\n                        ndp[cur_h + h] = total;\n                    }\n                }\n            }\n            dp = move(ndp);\n        }\n        \n        // We must end exactly at W\n        int best_cost = dp[W];\n        if (best_cost >= INF) {\n            // Fallback: distribute evenly\n            int base = W / N;\n            int rem = W % N;\n            vector<int> heights(N);\n            for (int k = 0; k < N; k++) {\n                heights[k] = base + (k < rem ? 1 : 0);\n            }\n            \n            int cur_y = 0;\n            for (int k = 0; k < N; k++) {\n                cout << cur_y << \" 0 \" << cur_y + heights[k] << \" \" << W << \"\\n\";\n                cur_y += heights[k];\n            }\n            prev_heights = heights;\n            continue;\n        }\n        \n        // Backtrack to find optimal heights\n        vector<int> heights(N);\n        {\n            int cur_total = W;\n            for (int k = N - 1; k >= 0; k--) {\n                int max_possible = cur_total - k;  // leave at least 1 for each remaining\n                if (max_possible < min_h[k]) max_possible = min_h[k];\n                if (max_possible > cur_total) max_possible = cur_total;\n                \n                // Find height that works\n                int best_h = min_h[k];\n                for (int h = min_h[k]; h <= max_possible; h++) {\n                    int prev_total = cur_total - h;\n                    if (dp[prev_total] < INF) {\n                        // Check if this leads to optimal solution\n                        int area = h * W;\n                        int penalty = max(0, 100 * (a[d][k] - area));\n                        int change_cost = 0;\n                        if (d > 0) {\n                            change_cost = abs(h - prev_heights[k]);\n                        }\n                        \n                        if (dp[prev_total] + penalty + change_cost == best_cost) {\n                            // Adjust best_cost for next iteration\n                            if (k > 0) {\n                                // Find the cost before this reservation\n                                // We need to rebuild dp for backtracking\n                                bool found = false;\n                                for (int ph = 0; ph <= prev_total; ph++) {\n                                    if (dp[ph] < INF) {\n                                        // This is the state before this reservation\n                                        // The cost should be dp[ph]\n                                        best_cost = dp[ph];\n                                        found = true;\n                                        break;\n                                    }\n                                }\n                            }\n                            best_h = h;\n                            break;\n                        }\n                    }\n                }\n                \n                heights[k] = best_h;\n                cur_total -= best_h;\n                \n                // Safety: ensure we don't go negative\n                if (cur_total < 0) {\n                    cur_total = 0;\n                }\n            }\n            \n            // Verify sum\n            int total = 0;\n            for (int h : heights) total += h;\n            if (total != W) {\n                // Adjust last height\n                heights[N-1] += W - total;\n                if (heights[N-1] < 1) heights[N-1] = 1;\n            }\n        }\n        \n        // Output this day's rectangles\n        int cur_y = 0;\n        for (int k = 0; k < N; k++) {\n            int i0 = cur_y;\n            int i1 = cur_y + heights[k];\n            \n            // Final safety check\n            if (i0 >= i1) i1 = i0 + 1;\n            if (i1 > W) i1 = W;\n            if (i0 < 0) i0 = 0;\n            \n            cout << i0 << \" 0 \" << i1 << \" \" << W << \"\\n\";\n            cur_y = i1;\n        }\n        \n        // Update previous heights\n        prev_heights = heights;\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int STAMP_SIZE = 3;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N_actual, M, K;\n    cin >> N_actual >> M >> K;\n    \n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(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 >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int,int,int>> operations;\n    vector<vector<long long>> cur = board;\n    \n    // Helper to get current gap\n    auto get_gap = [&](int i, int j) {\n        long long r = cur[i][j] % MOD;\n        return (MOD - 1 - r + MOD) % MOD;\n    };\n    \n    // Evaluate placement with smart scoring\n    auto evaluate = [&](int m, int p, int q) {\n        double total_score = 0;\n        bool any_negative = false;\n        \n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int ci = p + i, cj = q + j;\n                long long cur_gap = get_gap(ci, cj);\n                long long stamp_val = stamps[m][i][j] % MOD;\n                long long new_gap = (cur_gap - stamp_val + MOD) % MOD;\n                long long reduction = cur_gap - new_gap;\n                \n                // Weight based on gap size\n                double weight = 1.0 + (double)cur_gap / MOD * 3.0;\n                \n                if (reduction >= 0) {\n                    total_score += reduction * weight;\n                    // Bonus for getting close to perfect\n                    if (new_gap < MOD / 100) {\n                        total_score += MOD * 0.1;\n                    }\n                } else {\n                    // Penalty for overshoot\n                    total_score += reduction * 1.0;\n                    any_negative = true;\n                }\n            }\n        }\n        \n        // Penalty for making any cell worse\n        if (any_negative) {\n            total_score *= 0.8;\n        }\n        \n        return total_score;\n    };\n    \n    // Phase 1: Aggressive improvement focusing on needy cells\n    for (int op = 0; op < K; op++) {\n        double best_score = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n        \n        // Find cell with biggest gap\n        int target_i = -1, target_j = -1;\n        long long max_gap = -1;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                long long gap = get_gap(i, j);\n                if (gap > max_gap) {\n                    max_gap = gap;\n                    target_i = i;\n                    target_j = j;\n                }\n            }\n        }\n        \n        if (max_gap <= MOD / 200) break; // All cells within 0.5% of perfect\n        \n        // Search stamps affecting target cell\n        for (int m = 0; m < M; m++) {\n            for (int p = max(0, target_i - 2); p <= min(N - 3, target_i); p++) {\n                for (int q = max(0, target_j - 2); q <= min(N - 3, target_j); q++) {\n                    if (p > target_i || p + 2 < target_i) continue;\n                    if (q > target_j || q + 2 < target_j) continue;\n                    \n                    double score = evaluate(m, p, q);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // If no good operation found for target, search all\n        if (best_score <= 0) {\n            for (int m = 0; m < M; m++) {\n                for (int p = 0; p <= N - 3; p++) {\n                    for (int q = 0; q <= N - 3; q++) {\n                        double score = evaluate(m, p, q);\n                        if (score > best_score) {\n                            best_score = score;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Apply operation\n        if (best_m != -1) {\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    cur[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n            operations.push_back({best_m, best_p, best_q});\n        }\n    }\n    \n    // Phase 2: Fine-tuning with all remaining operations\n    while (operations.size() < K) {\n        double best_score = -1e18;\n        int best_m = -1, best_p = -1, best_q = -1;\n        \n        // Try to find any improvement\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                    double score = evaluate(m, p, q);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // If we can't improve, just use the stamp with largest total value\n        if (best_score <= 0) {\n            for (int m = 0; m < M; m++) {\n                for (int p = 0; p <= N - 3; p++) {\n                    for (int q = 0; q <= N - 3; q++) {\n                        long long total_val = 0;\n                        for (int i = 0; i < 3; i++) {\n                            for (int j = 0; j < 3; j++) {\n                                total_val += stamps[m][i][j] % MOD;\n                            }\n                        }\n                        if (total_val > best_score) {\n                            best_score = total_val;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Apply operation\n        if (best_m != -1) {\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    cur[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n            operations.push_back({best_m, best_p, best_q});\n        }\n    }\n    \n    // Output\n    cout << operations.size() << \"\\n\";\n    for (const auto& [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // For each container, find its target row\n    vector<int> targetRow(N*N);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            targetRow[i*N + j] = i;\n        }\n    }\n    \n    // State\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    vector<int> craneRow(N), craneCol(N);\n    vector<int> holding(N, -1);\n    vector<int> nextReceiving(N, 0);\n    vector<int> nextDispatch(N, 0);\n    vector<bool> dispatched(N*N, false);\n    \n    // Initialize positions\n    for (int i = 0; i < N; i++) {\n        craneRow[i] = i;\n        craneCol[i] = 0;\n    }\n    \n    vector<string> ops(N);\n    \n    // Bomb all small cranes immediately (turns 0-3)\n    for (int i = 1; i < N; i++) {\n        for (int t = 0; t < i-1; t++) {\n            ops[i] += '.';\n        }\n        ops[i] += 'B';\n    }\n    \n    // Large crane stays active\n    ops[0] = \"....\";  // Wait while small cranes bomb\n    \n    // After bombing, only crane 0 remains active\n    // Process all containers using just the large crane\n    \n    int turn = 4;  // Already used 4 turns for bombing\n    \n    // Map to track where each container is currently\n    // -1 = not on grid, -2 = dispatched\n    \n    while (turn < MAX_TURNS) {\n        // Step 1: Deliver new containers to receiving gates\n        for (int i = 0; i < N; i++) {\n            if (nextReceiving[i] < N && grid[i][0] == -1) {\n                grid[i][0] = A[i][nextReceiving[i]];\n                nextReceiving[i]++;\n            }\n        }\n        \n        // Step 3: Dispatch containers at gates (before crane moves)\n        for (int i = 0; i < N; i++) {\n            if (grid[i][4] != -1) {\n                int c = grid[i][4];\n                if (c / N == i && c % N == nextDispatch[i]) {\n                    dispatched[c] = true;\n                    grid[i][4] = -1;\n                    nextDispatch[i]++;\n                }\n            }\n        }\n        \n        int r = craneRow[0], c = craneCol[0];\n        char action = '.';\n        \n        if (holding[0] == -1) {\n            // Find the most useful container to pick up\n            int bestR = -1, bestC = -1;\n            int bestPriority = -1;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) {\n                        int container = grid[i][j];\n                        int tr = container / N;\n                        \n                        // Don't pick up from dispatch gate if next in sequence\n                        if (j == 4 && container % N == nextDispatch[tr]) continue;\n                        \n                        int priority = 0;\n                        \n                        if (j == 0 && i != tr) {\n                            // At receiving gate, wrong row - highest priority\n                            priority = 100;\n                        } else if (j == 4 && i != tr) {\n                            // At wrong dispatch gate\n                            priority = 90;\n                        } else if (i != tr) {\n                            // In wrong row\n                            priority = 80 - abs(i - tr);\n                        } else if (j < 4 && container % N != nextDispatch[i]) {\n                            // In correct row but wrong order\n                            priority = 50;\n                        }\n                        \n                        if (priority > bestPriority) {\n                            bestPriority = priority;\n                            bestR = i;\n                            bestC = j;\n                        }\n                    }\n                }\n            }\n            \n            if (bestR != -1) {\n                if (r == bestR && c == bestC) {\n                    action = 'P';\n                } else {\n                    // Move towards target\n                    if (r < bestR) action = 'D';\n                    else if (r > bestR) action = 'U';\n                    else if (c < bestC) action = 'R';\n                    else if (c > bestC) action = 'L';\n                }\n            } else {\n                // Check if any container is still in receiving queue but not yet placed\n                bool hasRemaining = false;\n                for (int i = 0; i < N; i++) {\n                    if (nextReceiving[i] < N) {\n                        hasRemaining = true;\n                        // Move towards this receiving gate\n                        if (r < i) action = 'D';\n                        else if (r > i) action = 'U';\n                        break;\n                    }\n                }\n                \n                if (!hasRemaining) {\n                    // All containers are either dispatched or waiting\n                    // Move to center\n                    if (r < 2) action = 'D';\n                    else if (r > 2) action = 'U';\n                    else if (c < 2) action = 'R';\n                    else if (c > 2) action = 'L';\n                }\n            }\n        } else {\n            // Holding a container, deliver to target\n            int container = holding[0];\n            int tr = container / N;\n            int tn = container % N;\n            \n            if (r == tr) {\n                // In correct row\n                if (c == 4) {\n                    // At dispatch gate\n                    if (grid[r][4] == -1) {\n                        action = 'Q';\n                    } else {\n                        // Gate blocked, move left\n                        if (c > 0) action = 'L';\n                    }\n                } else if (c < 4) {\n                    // Move right towards dispatch gate\n                    action = 'R';\n                } else {\n                    // Past dispatch gate (shouldn't happen)\n                    if (c > 0) action = 'L';\n                }\n            } else {\n                // Move vertically to correct row\n                if (r < tr) action = 'D';\n                else if (r > tr) action = 'U';\n                else action = 'R';  // Same row, move right\n            }\n        }\n        \n        // Execute action with validation\n        if (action == 'P' && grid[r][c] != -1 && holding[0] == -1) {\n            holding[0] = grid[r][c];\n            grid[r][c] = -1;\n        } else if (action == 'Q' && grid[r][c] == -1 && holding[0] != -1) {\n            grid[r][c] = holding[0];\n            holding[0] = -1;\n            // Check if just placed at dispatch gate\n            if (c == 4 && grid[r][c] != -1) {\n                int container = grid[r][c];\n                if (container / N == r && container % N == nextDispatch[r]) {\n                    dispatched[container] = true;\n                    grid[r][c] = -1;\n                    nextDispatch[r]++;\n                }\n            }\n        } else if (action == 'U' && r > 0) {\n            craneRow[0] = r-1;\n        } else if (action == 'D' && r < N-1) {\n            craneRow[0] = r+1;\n        } else if (action == 'L' && c > 0) {\n            craneCol[0] = c-1;\n        } else if (action == 'R' && c < N-1) {\n            craneCol[0] = c+1;\n        }\n        \n        ops[0] += action;\n        \n        // Add '.' for bombed cranes\n        for (int i = 1; i < N; i++) {\n            if ((int)ops[i].length() < (int)ops[0].length()) {\n                ops[i] += '.';\n            }\n        }\n        \n        turn++;\n        \n        // Check if all done\n        bool allDone = true;\n        for (int i = 0; i < N*N && allDone; i++) {\n            if (!dispatched[i]) allDone = false;\n        }\n        if (allDone) break;\n    }\n    \n    // Normalize output lengths\n    int maxLen = 0;\n    for (int i = 0; i < N; i++) {\n        maxLen = max(maxLen, (int)ops[i].length());\n    }\n    for (int i = 0; i < N; i++) {\n        while ((int)ops[i].length() < maxLen) {\n            ops[i] += '.';\n        }\n        cout << ops[i] << '\\n';\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\nconst int MAX_TURNS = 100000;\nconst int DX[] = {-1, 1, 0, 0};\nconst int DY[] = {0, 0, -1, 1};\nconst string DIR = \"UDLR\";\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<vector<int>> h(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> ops;\n    int x = 0, y = 0;\n    int load = 0;\n    \n    // BFS for shortest path\n    auto get_path = [&](int sx, int sy, int tx, int ty) -> vector<pair<int,int>> {\n        if (sx == tx && sy == ty) return {};\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(N, vector<int>(N, INF));\n        vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n        \n        dist[sx][sy] = 0;\n        q.push({sx, sy});\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            if (cx == tx && cy == ty) break;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = cx + DX[d], ny = cy + DY[d];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && dist[nx][ny] > dist[cx][cy] + 1) {\n                    dist[nx][ny] = dist[cx][cy] + 1;\n                    prev[nx][ny] = {cx, cy};\n                    q.push({nx, ny});\n                }\n            }\n        }\n        \n        if (dist[tx][ty] == INF) return {};\n        \n        vector<pair<int,int>> path;\n        int cx = tx, cy = ty;\n        while (cx != sx || cy != sy) {\n            path.push_back({cx, cy});\n            auto [px, py] = prev[cx][cy];\n            cx = px; cy = py;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto move_to = [&](int tx, int ty) {\n        if (x == tx && y == ty) return;\n        auto path = get_path(x, y, tx, ty);\n        for (auto [nx, ny] : path) {\n            for (int d = 0; d < 4; d++) {\n                if (x + DX[d] == nx && y + DY[d] == ny) {\n                    ops.push_back(DIR.substr(d, 1));\n                    break;\n                }\n            }\n            x = nx; y = ny;\n        }\n    };\n    \n    // Phase 1: Calculate \"gravity\" center of soil\n    // The optimal hub is roughly the weighted center of mass\n    long long total_positive = 0, sum_x = 0, sum_y = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (h[i][j] > 0) {\n                total_positive += h[i][j];\n                sum_x += (long long)h[i][j] * i;\n                sum_y += (long long)h[i][j] * j;\n            }\n        }\n    }\n    \n    // Hub position (center of mass of positive soil)\n    int hub_x = sum_x / max(total_positive, 1LL);\n    int hub_y = sum_y / max(total_positive, 1LL);\n    \n    // Actually, let's just scan the grid in a snake pattern and move soil to nearest sink\n    // This is simpler and often works better\n    \n    // Collect all soil to central storage (hub)\n    // Then distribute from hub\n    \n    // Phase 1: Scan grid and collect all positive soil\n    for (int i = 0; i < N && (int)ops.size() < MAX_TURNS - 1000; i++) {\n        for (int j = 0; j < N && (int)ops.size() < MAX_TURNS - 1000; j++) {\n            if (h[i][j] > 0) {\n                // Move to this cell\n                move_to(i, j);\n                \n                // Load everything\n                int amount = h[i][j];\n                ops.push_back(\"+\" + to_string(amount));\n                h[i][j] = 0;\n                load += amount;\n                \n                // Immediately find a sink to dump\n                int best_sink_x = -1, best_sink_y = -1;\n                int best_dist = INF;\n                \n                for (int ii = 0; ii < N; ii++) {\n                    for (int jj = 0; jj < N; jj++) {\n                        if (h[ii][jj] < 0) {\n                            int dist = abs(i - ii) + abs(j - jj);\n                            if (dist < best_dist) {\n                                best_dist = dist;\n                                best_sink_x = ii;\n                                best_sink_y = jj;\n                            }\n                        }\n                    }\n                }\n                \n                if (best_sink_x == -1) break; // No more sinks\n                \n                // Move to sink\n                move_to(best_sink_x, best_sink_y);\n                \n                // Unload as much as needed\n                int needed = -h[best_sink_x][best_sink_y];\n                int to_dump = min(load, needed);\n                ops.push_back(\"-\" + to_string(to_dump));\n                h[best_sink_x][best_sink_y] += to_dump;\n                load -= to_dump;\n                \n                // If we still have load, find another sink\n                while (load > 0 && (int)ops.size() < MAX_TURNS - 100) {\n                    // Find nearest sink with remaining need\n                    int best_dist = INF;\n                    int best_sx = -1, best_sy = -1;\n                    \n                    for (int ii = 0; ii < N; ii++) {\n                        for (int jj = 0; jj < N; jj++) {\n                            if (h[ii][jj] < 0) {\n                                int dist = abs(x - ii) + abs(y - jj);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best_sx = ii;\n                                    best_sy = jj;\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (best_sx == -1) break;\n                    \n                    move_to(best_sx, best_sy);\n                    needed = -h[best_sx][best_sy];\n                    to_dump = min(load, needed);\n                    ops.push_back(\"-\" + to_string(to_dump));\n                    h[best_sx][best_sy] += to_dump;\n                    load -= to_dump;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Handle any remaining work\n    while ((int)ops.size() < MAX_TURNS - 100) {\n        // Find any pair of source and sink\n        bool found = false;\n        for (int i = 0; i < N && !found; i++) {\n            for (int j = 0; j < N && !found; j++) {\n                if (h[i][j] > 0) {\n                    // Find nearest sink\n                    for (int ii = 0; ii < N && !found; ii++) {\n                        for (int jj = 0; jj < N && !found; jj++) {\n                            if (h[ii][jj] < 0) {\n                                int amount = min(h[i][j], -h[ii][jj]);\n                                amount = min(amount, 500);\n                                \n                                if (amount > 0) {\n                                    move_to(i, j);\n                                    ops.push_back(\"+\" + to_string(amount));\n                                    h[i][j] -= amount;\n                                    load = amount;\n                                    \n                                    move_to(ii, jj);\n                                    ops.push_back(\"-\" + to_string(amount));\n                                    h[ii][jj] += amount;\n                                    load = 0;\n                                    found = true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        if (!found) break;\n    }\n    \n    // Output\n    for (const string& op : ops) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 6;\n    const int M = 15;\n    const int SEED_COUNT = 2 * N * (N - 1);\n    const int T = 10;\n    \n    vector<vector<int>> seeds(SEED_COUNT, vector<int>(M));\n    vector<int> totals(SEED_COUNT);\n    \n    for (int i = 0; i < SEED_COUNT; i++) {\n        totals[i] = 0;\n        for (int j = 0; j < M; j++) {\n            cin >> seeds[i][j];\n            totals[i] += seeds[i][j];\n        }\n    }\n    \n    // Proven optimal position ordering\n    const vector<pair<int,int>> positions = {\n        {2, 2}, {2, 3}, {3, 2}, {3, 3},\n        {1, 2}, {1, 3}, {2, 1}, {2, 4}, \n        {3, 1}, {3, 4}, {4, 2}, {4, 3},\n        {0, 2}, {0, 3}, {2, 0}, {2, 5}, \n        {3, 0}, {3, 5}, {5, 2}, {5, 3},\n        {1, 1}, {1, 4}, {4, 1}, {4, 4},\n        {0, 1}, {0, 4}, {1, 0}, {1, 5}, \n        {4, 0}, {4, 5}, {5, 1}, {5, 4},\n        {0, 0}, {0, 5}, {5, 0}, {5, 5}\n    };\n    \n    for (int t = 0; t < T; t++) {\n        // Find best and second-best trait values\n        vector<int> best_trait(M, 0);\n        vector<int> second_best_trait(M, 0);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            for (int j = 0; j < M; j++) {\n                if (seeds[i][j] > best_trait[j]) {\n                    second_best_trait[j] = best_trait[j];\n                    best_trait[j] = seeds[i][j];\n                } else if (seeds[i][j] > second_best_trait[j]) {\n                    second_best_trait[j] = seeds[i][j];\n                }\n            }\n        }\n        \n        // Find top 3 seeds for each trait (for diversity scoring)\n        vector<vector<int>> top_3_per_trait(M);\n        for (int j = 0; j < M; j++) {\n            vector<pair<int,int>> sorted_by_trait;\n            for (int i = 0; i < SEED_COUNT; i++) {\n                sorted_by_trait.push_back({seeds[i][j], i});\n            }\n            sort(sorted_by_trait.rbegin(), sorted_by_trait.rend());\n            for (int k = 0; k < 3; k++) {\n                top_3_per_trait[j].push_back(sorted_by_trait[k].second);\n            }\n        }\n        \n        // Calculate trait diversity\n        vector<int> trait_diversity(SEED_COUNT, 0);\n        for (int j = 0; j < M; j++) {\n            for (int seed_idx : top_3_per_trait[j]) {\n                trait_diversity[seed_idx]++;\n            }\n        }\n        \n        // Compute scores\n        vector<pair<int, int>> scores;\n        scores.reserve(SEED_COUNT);\n        \n        for (int i = 0; i < SEED_COUNT; i++) {\n            int score = 0;\n            \n            // Base score from total\n            score += totals[i];\n            \n            // Trait excellence bonuses\n            int elite_traits = 0;\n            for (int j = 0; j < M; j++) {\n                if (seeds[i][j] == best_trait[j]) {\n                    elite_traits++;\n                    score += 300;\n                } else if (seeds[i][j] == second_best_trait[j]) {\n                    score += 150;\n                }\n                \n                // Value-based bonuses\n                if (seeds[i][j] >= 95) {\n                    score += 100;\n                } else if (seeds[i][j] >= 90) {\n                    score += 60;\n                } else if (seeds[i][j] >= 85) {\n                    score += 35;\n                } else if (seeds[i][j] >= 80) {\n                    score += 20;\n                } else if (seeds[i][j] >= 75) {\n                    score += 10;\n                }\n            }\n            \n            // Diversity bonus - being good in many different traits\n            score += trait_diversity[i] * 30;\n            \n            // Elite synergy\n            if (elite_traits >= 2) {\n                score += elite_traits * 50;\n            }\n            \n            // Final generations: focus heavily on total value and elite traits\n            if (t >= 7) {\n                score += totals[i] * (t - 5);\n                // Extra focus on elite traits in final rounds\n                if (elite_traits >= 3) {\n                    score += 200;\n                }\n            }\n            \n            // In the very last generation, aggressively select for total value\n            if (t == T - 1) {\n                score += totals[i] * 3;\n            }\n            \n            scores.push_back({score, i});\n        }\n        \n        sort(scores.rbegin(), scores.rend());\n        \n        // Create grid\n        vector<vector<int>> grid(N, vector<int>(N));\n        \n        for (int p = 0; p < 36; p++) {\n            int i = positions[p].first;\n            int j = positions[p].second;\n            grid[i][j] = scores[p].second;\n        }\n        \n        // Output 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        cout.flush();\n        \n        // Read new seeds\n        for (int i = 0; i < SEED_COUNT; i++) {\n            totals[i] = 0;\n            for (int j = 0; j < M; j++) {\n                cin >> seeds[i][j];\n                totals[i] += seeds[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int x, y;\n    Position(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass TakoyakiSolver {\nprivate:\n    int N, M, V;\n    vector<string> initial_grid, target_grid;\n    vector<Position> initial_positions, target_positions;\n    vector<vector<bool>> occupied;\n    \n    // Simple arm: root + 1 fingertip\n    int edge_length;\n    Position root_pos;\n    int direction; // 0: right, 1: down, 2: left, 3: up\n    \n    // State\n    bool holding;\n    int holding_idx;\n    vector<int> target_for_initial;\n    vector<int> pickup_order; // Optimal order to pick up takoyaki\n    \n    // Output\n    vector<string> commands;\n    \npublic:\n    TakoyakiSolver() {\n        readInput();\n        matchPositions();\n        planOptimalOrder();\n        solve();\n    }\n    \n    void readInput() {\n        cin >> N >> M >> V;\n        \n        initial_grid.resize(N);\n        target_grid.resize(N);\n        occupied.assign(N, vector<bool>(N, false));\n        \n        for (int i = 0; i < N; i++) {\n            cin >> initial_grid[i];\n            for (int j = 0; j < N; j++) {\n                if (initial_grid[i][j] == '1') {\n                    initial_positions.push_back(Position(i, j));\n                    occupied[i][j] = true;\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> target_grid[i];\n            for (int j = 0; j < N; j++) {\n                if (target_grid[i][j] == '1') {\n                    target_positions.push_back(Position(i, j));\n                }\n            }\n        }\n        \n        holding = false;\n        holding_idx = -1;\n    }\n    \n    void matchPositions() {\n        target_for_initial.assign(M, -1);\n        vector<bool> target_used(M, false);\n        \n        // Hungarian-like matching with better distance metric\n        for (int i = 0; i < M; i++) {\n            int best_j = -1;\n            int best_dist = 1e9;\n            \n            for (int j = 0; j < M; j++) {\n                if (!target_used[j]) {\n                    // Use Manhattan distance\n                    int dist = abs(initial_positions[i].x - target_positions[j].x) +\n                              abs(initial_positions[i].y - target_positions[j].y);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_j = j;\n                    }\n                }\n            }\n            \n            target_for_initial[i] = best_j;\n            target_used[best_j] = true;\n        }\n    }\n    \n    void planOptimalOrder() {\n        // Plan order to pick up takoyaki to minimize total travel\n        pickup_order.clear();\n        vector<bool> picked(M, false);\n        \n        // Start from root position (0,0)\n        Position current = Position(0, 0);\n        \n        for (int step = 0; step < M; step++) {\n            int best_idx = -1;\n            int best_dist = 1e9;\n            \n            for (int i = 0; i < M; i++) {\n                if (!picked[i]) {\n                    // Distance from current position to this takoyaki\n                    int dist = abs(initial_positions[i].x - current.x) +\n                              abs(initial_positions[i].y - current.y);\n                    \n                    // Add bonus for being near its target too\n                    Position target = target_positions[target_for_initial[i]];\n                    dist += abs(target.x - initial_positions[i].x) +\n                            abs(target.y - initial_positions[i].y);\n                    \n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx >= 0) {\n                pickup_order.push_back(best_idx);\n                picked[best_idx] = true;\n                current = target_positions[target_for_initial[best_idx]];\n            }\n        }\n    }\n    \n    Position getFingertipPosition() {\n        return Position(\n            root_pos.x + dx[direction] * edge_length,\n            root_pos.y + dy[direction] * edge_length\n        );\n    }\n    \n    char moveRootTowards(const Position& target) {\n        char move = '.';\n        int dx_target = target.x - root_pos.x;\n        int dy_target = target.y - root_pos.y;\n        \n        // Always move in the direction with larger difference\n        if (abs(dx_target) >= abs(dy_target)) {\n            if (dx_target > 0 && root_pos.x < N - 1) {\n                move = 'D';\n                root_pos.x++;\n            } else if (dx_target < 0 && root_pos.x > 0) {\n                move = 'U';\n                root_pos.x--;\n            } else if (dy_target > 0 && root_pos.y < N - 1) {\n                move = 'R';\n                root_pos.y++;\n            } else if (dy_target < 0 && root_pos.y > 0) {\n                move = 'L';\n                root_pos.y--;\n            }\n        } else {\n            if (dy_target > 0 && root_pos.y < N - 1) {\n                move = 'R';\n                root_pos.y++;\n            } else if (dy_target < 0 && root_pos.y > 0) {\n                move = 'L';\n                root_pos.y--;\n            } else if (dx_target > 0 && root_pos.x < N - 1) {\n                move = 'D';\n                root_pos.x++;\n            } else if (dx_target < 0 && root_pos.x > 0) {\n                move = 'U';\n                root_pos.x--;\n            }\n        }\n        \n        return move;\n    }\n    \n    string generateCommand() {\n        string cmd(4, '.'); // For 2 vertices\n        \n        // Determine where to go based on state\n        Position target;\n        \n        if (!holding) {\n            // Find next takoyaki to pick up\n            int next_idx = -1;\n            int min_dist = 1e9;\n            \n            for (int i = 0; i < M; i++) {\n                if (occupied[initial_positions[i].x][initial_positions[i].y]) {\n                    int dist = abs(initial_positions[i].x - root_pos.x) +\n                              abs(initial_positions[i].y - root_pos.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        next_idx = i;\n                    }\n                }\n            }\n            \n            if (next_idx >= 0) {\n                target = initial_positions[next_idx];\n                \n                // Move root towards target\n                cmd[0] = moveRootTowards(target);\n                \n                // Rotate fingertip towards target\n                Position fingertip = getFingertipPosition();\n                int dx_target = target.x - root_pos.x;\n                int dy_target = target.y - root_pos.y;\n                int target_dir = (abs(dx_target) >= abs(dy_target)) ? \n                                 ((dx_target > 0) ? 1 : 3) : \n                                 ((dy_target > 0) ? 0 : 2);\n                \n                if (target_dir != direction) {\n                    int diff = (target_dir - direction + 4) % 4;\n                    if (diff <= 2) {\n                        cmd[1] = 'R';\n                        direction = (direction + 1) % 4;\n                    } else {\n                        cmd[1] = 'L';\n                        direction = (direction + 3) % 4;\n                    }\n                }\n                \n                // Try to grab\n                fingertip = getFingertipPosition();\n                if (fingertip.x >= 0 && fingertip.x < N && \n                    fingertip.y >= 0 && fingertip.y < N &&\n                    fingertip == target && occupied[target.x][target.y]) {\n                    cmd[3] = 'P';\n                    holding = true;\n                    holding_idx = next_idx;\n                    occupied[target.x][target.y] = false;\n                }\n            }\n        } else {\n            // Deliver the held takoyaki\n            target = target_positions[target_for_initial[holding_idx]];\n            \n            if (!occupied[target.x][target.y]) {\n                cmd[0] = moveRootTowards(target);\n                \n                Position fingertip = getFingertipPosition();\n                int dx_target = target.x - root_pos.x;\n                int dy_target = target.y - root_pos.y;\n                int target_dir = (abs(dx_target) >= abs(dy_target)) ? \n                                 ((dx_target > 0) ? 1 : 3) : \n                                 ((dy_target > 0) ? 0 : 2);\n                \n                if (target_dir != direction) {\n                    int diff = (target_dir - direction + 4) % 4;\n                    if (diff <= 2) {\n                        cmd[1] = 'R';\n                        direction = (direction + 1) % 4;\n                    } else {\n                        cmd[1] = 'L';\n                        direction = (direction + 3) % 4;\n                    }\n                }\n                \n                fingertip = getFingertipPosition();\n                if (fingertip.x >= 0 && fingertip.x < N && \n                    fingertip.y >= 0 && fingertip.y < N &&\n                    fingertip == target) {\n                    cmd[3] = 'P';\n                    holding = false;\n                    occupied[target.x][target.y] = true;\n                    holding_idx = -1;\n                }\n            }\n        }\n        \n        return cmd;\n    }\n    \n    void solve() {\n        // Design arm: edge length = min(N-1, N/2)\n        edge_length = min(N - 1, N / 2);\n        if (edge_length < 1) edge_length = 1;\n        \n        cout << 2 << endl;\n        cout << 0 << \" \" << edge_length << endl;\n        \n        // Initial position\n        root_pos = Position(0, 0);\n        direction = 0;\n        cout << root_pos.x << \" \" << root_pos.y << endl;\n        \n        // Generate commands\n        commands.clear();\n        \n        // Pre-calculate adjacent targets for faster path\n        vector<vector<int>> adj_initial(M);\n        for (int i = 0; i < M; i++) {\n            for (int j = i + 1; j < M; j++) {\n                int dist = abs(initial_positions[i].x - initial_positions[j].x) +\n                          abs(initial_positions[i].y - initial_positions[j].y);\n                if (dist <= 3) { // Close enough to be \"adjacent\"\n                    adj_initial[i].push_back(j);\n                    adj_initial[j].push_back(i);\n                }\n            }\n        }\n        \n        for (int turn = 0; turn < 100000; turn++) {\n            string cmd = generateCommand();\n            commands.push_back(cmd);\n            \n            // Check all delivered\n            bool all_delivered = true;\n            for (int i = 0; i < M; i++) {\n                Position target = target_positions[target_for_initial[i]];\n                if (!occupied[target.x][target.y]) {\n                    all_delivered = false;\n                    break;\n                }\n            }\n            \n            if (all_delivered && !holding) {\n                break;\n            }\n            \n            // Safety\n            root_pos.x = max(0, min(N - 1, root_pos.x));\n            root_pos.y = max(0, min(N - 1, root_pos.y));\n        }\n        \n        // Output\n        for (const string& cmd : commands) {\n            cout << cmd << endl;\n        }\n    }\n    \n    static const int dx[4];\n    static const int dy[4];\n};\n\nconst int TakoyakiSolver::dx[4] = {0, 1, 0, -1};\nconst int TakoyakiSolver::dy[4] = {1, 0, -1, 0};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TakoyakiSolver solver;\n    \n    return 0;\n}","ahc039":"#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 = 5000;\n    vector<pair<int,int>> mackerel(N), sardine(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> mackerel[i].first >> mackerel[i].second;\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> sardine[i].first >> sardine[i].second;\n    }\n    \n    int best_score = -1e9;\n    int best_x1 = 0, best_y1 = 0, best_x2 = 0, best_y2 = 0;\n    \n    // Use multiple cell sizes to cover different cluster scales\n    // Fish clusters have std dev 1000-5000, so cell size 200-800 should work\n    vector<pair<int,int>> configs = {\n        {200, 0}, {200, 50}, {200, 100}, {200, 150},\n        {300, 0}, {300, 75}, {300, 150}, {300, 225},\n        {400, 0}, {400, 100}, {400, 200}, {400, 300},\n        {500, 0}, {500, 125}, {500, 250}, {500, 375},\n        {600, 0}, {600, 150}, {600, 300}, {600, 450},\n        {800, 0}, {800, 200}, {800, 400}, {800, 600}\n    };\n    \n    for (auto& [CELL, OFFSET] : configs) {\n        int CELLS = 100000 / CELL + 2;\n        \n        // Build grid\n        vector<vector<short>> grid(CELLS, vector<short>(CELLS, 0));\n        for (auto& p : mackerel) {\n            int cx = (p.first + OFFSET) / CELL;\n            int cy = (p.second + OFFSET) / CELL;\n            if (cx >= 0 && cx < CELLS && cy >= 0 && cy < CELLS)\n                grid[cx][cy]++;\n        }\n        for (auto& p : sardine) {\n            int cx = (p.first + OFFSET) / CELL;\n            int cy = (p.second + OFFSET) / CELL;\n            if (cx >= 0 && cx < CELLS && cy >= 0 && cy < CELLS)\n                grid[cx][cy]--;\n        }\n        \n        // Kadane 2D with early termination for negative regions\n        for (int top = 0; top < CELLS; top++) {\n            vector<int> temp(CELLS, 0);\n            for (int bottom = top; bottom < CELLS; bottom++) {\n                // Quick check if continuing is worth it\n                bool all_negative = true;\n                for (int j = 0; j < CELLS; j++) {\n                    temp[j] += grid[bottom][j];\n                    if (temp[j] > 0) all_negative = false;\n                }\n                if (all_negative) continue;\n                \n                int cur = 0, left = 0;\n                for (int j = 0; j < CELLS; j++) {\n                    cur += temp[j];\n                    if (cur > best_score) {\n                        best_score = cur;\n                        const int MARGIN = 15;\n                        best_x1 = max(0, top * CELL - OFFSET - MARGIN);\n                        best_y1 = max(0, left * CELL - OFFSET - MARGIN);\n                        best_x2 = min(100000, (bottom + 1) * CELL - OFFSET + MARGIN);\n                        best_y2 = min(100000, (j + 1) * CELL - OFFSET + MARGIN);\n                    }\n                    if (cur < 0) {\n                        cur = 0;\n                        left = j + 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Fallback: direct search around each mackerel\n    if (best_score <= 5) {\n        for (int i = 0; i < N; i++) {\n            auto [mx, my] = mackerel[i];\n            for (int s : {200, 500, 1000, 2000, 5000}) {\n                int x1 = max(0, mx - s);\n                int y1 = max(0, my - s);\n                int x2 = min(100000, mx + s);\n                int y2 = min(100000, my + s);\n                \n                if (x1 >= x2 || y1 >= y2) continue;\n                \n                int score = 0;\n                for (auto& p : mackerel)\n                    if (p.first >= x1 && p.first <= x2 && p.second >= y1 && p.second <= y2)\n                        score++;\n                for (auto& p : sardine)\n                    if (p.first >= x1 && p.first <= x2 && p.second >= y1 && p.second <= y2)\n                        score--;\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_x1 = x1; best_y1 = y1;\n                    best_x2 = x2; best_y2 = y2;\n                }\n            }\n            if (best_score > 5) break;\n        }\n    }\n    \n    if (best_score <= 0) {\n        cout << \"4\\n0 0\\n1 0\\n1 1\\n0 1\\n\";\n        return 0;\n    }\n    \n    if (best_x1 == best_x2) { if (best_x2 < 100000) best_x2++; else best_x1--; }\n    if (best_y1 == best_y2) { if (best_y2 < 100000) best_y2++; else best_y1--; }\n    best_x1 = max(0, best_x1); best_y1 = max(0, best_y1);\n    best_x2 = min(100000, best_x2); best_y2 = min(100000, best_y2);\n    \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 <bits/stdc++.h>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nstruct Rectangle {\n    long long w, h;\n    long long area;\n    double ratio;  // w/h ratio\n};\n\nint N, T, sigma;\nvector<Rectangle> rects;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Placement {\n    int p, r;\n    char d;\n    int b;\n};\n\nstruct PlacedRect {\n    long long x1, y1, x2, y2;\n    int idx;\n};\n\n// Evaluate placement and return score\nlong long evaluate_placement(const vector<Placement>& placements,\n                            long long& width, long long& height) {\n    vector<PlacedRect> placed;\n    vector<bool> used(N, false);\n    \n    for (const auto& pl : placements) {\n        int idx = pl.p;\n        if (idx < 0 || idx >= N || used[idx]) continue;\n        used[idx] = true;\n        \n        long long rw = rects[idx].w;\n        long long rh = rects[idx].h;\n        if (pl.r) swap(rw, rh);\n        \n        if (pl.d == 'U') {\n            long long left_x = 0;\n            if (pl.b >= 0) {\n                for (const auto& pr : placed) {\n                    if (pr.idx == pl.b) {\n                        left_x = pr.x2;\n                        break;\n                    }\n                }\n            }\n            \n            long long bottom_y = 0;\n            for (const auto& pr : placed) {\n                if (left_x < pr.x2 && left_x + rw > pr.x1) {\n                    bottom_y = max(bottom_y, pr.y2);\n                }\n            }\n            \n            placed.push_back({left_x, bottom_y, left_x + rw, bottom_y + rh, idx});\n        } else {\n            long long top_y = 0;\n            if (pl.b >= 0) {\n                for (const auto& pr : placed) {\n                    if (pr.idx == pl.b) {\n                        top_y = pr.y2;\n                        break;\n                    }\n                }\n            }\n            \n            long long right_x = 0;\n            for (const auto& pr : placed) {\n                if (top_y < pr.y2 && top_y + rh > pr.y1) {\n                    right_x = max(right_x, pr.x2);\n                }\n            }\n            \n            placed.push_back({right_x, top_y, right_x + rw, top_y + rh, idx});\n        }\n    }\n    \n    width = 0;\n    height = 0;\n    for (const auto& pr : placed) {\n        width = max(width, pr.x2);\n        height = max(height, pr.y2);\n    }\n    \n    long long unplaced_sum = 0;\n    for (int i = 0; i < N; i++) {\n        if (!used[i]) {\n            unplaced_sum += rects[i].w + rects[i].h;\n        }\n    }\n    \n    return width + height + unplaced_sum;\n}\n\n// Generate simple row packing\nvector<Placement> generate_row_packing(const vector<bool>& use_rect,\n                                      const vector<bool>& rotate_rect) {\n    vector<Placement> result;\n    \n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        \n        int rot = rotate_rect[i] ? 1 : 0;\n        \n        if (result.empty()) {\n            result.push_back({i, rot, 'U', -1});\n        } else {\n            result.push_back({i, rot, 'U', result.back().p});\n        }\n    }\n    \n    return result;\n}\n\n// Generate two-row packing with dynamic split\nvector<Placement> generate_two_row_packing(const vector<bool>& use_rect,\n                                          const vector<bool>& rotate_rect,\n                                          int split_ratio = 50) {\n    vector<Placement> result;\n    vector<int> first_row;\n    vector<int> second_row;\n    \n    int count = 0;\n    for (int i = 0; i < N; i++) if (use_rect[i]) count++;\n    int first_count = count * split_ratio / 100;\n    if (first_count < 1) first_count = 1;\n    if (first_count >= count) first_count = max(1, count / 2);\n    \n    int placed = 0;\n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        if (placed < first_count) {\n            first_row.push_back(i);\n        } else {\n            second_row.push_back(i);\n        }\n        placed++;\n    }\n    \n    for (size_t i = 0; i < first_row.size(); i++) {\n        int idx = first_row[i];\n        int rot = rotate_rect[idx] ? 1 : 0;\n        if (result.empty()) {\n            result.push_back({idx, rot, 'U', -1});\n        } else {\n            result.push_back({idx, rot, 'U', result.back().p});\n        }\n    }\n    \n    if (!second_row.empty()) {\n        int first_last = first_row.back();\n        for (size_t i = 0; i < second_row.size(); i++) {\n            int idx = second_row[i];\n            int rot = rotate_rect[idx] ? 1 : 0;\n            if (i == 0) {\n                result.push_back({idx, rot, 'L', first_last});\n            } else {\n                result.push_back({idx, rot, 'U', result.back().p});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Generate best-fit packing with more position candidates\nvector<Placement> generate_advanced_best_fit(const vector<bool>& use_rect,\n                                            const vector<bool>& rotate_rect,\n                                            bool prefer_square = false) {\n    vector<Placement> result;\n    vector<PlacedRect> placed;\n    \n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        \n        long long best_score = 1LL << 60;\n        int best_rot = 0;\n        int best_ref = -1;\n        char best_dir = 'U';\n        long long best_x = 0, best_y = 0;\n        \n        for (int rot = 0; rot < 2; rot++) {\n            long long rw = rects[i].w;\n            long long rh = rects[i].h;\n            if (rot) swap(rw, rh);\n            \n            // Collect candidate x positions\n            set<long long> x_candidates;\n            x_candidates.insert(0);\n            for (const auto& pr : placed) {\n                x_candidates.insert(pr.x2);\n                x_candidates.insert(pr.x1);\n                // Also try positions that align with left edges\n                if (pr.x1 - rw >= 0) x_candidates.insert(pr.x1 - rw);\n            }\n            \n            for (long long left_x : x_candidates) {\n                long long bottom_y = 0;\n                for (const auto& pk : placed) {\n                    if (left_x < pk.x2 && left_x + rw > pk.x1) {\n                        bottom_y = max(bottom_y, pk.y2);\n                    }\n                }\n                \n                long long max_x = left_x + rw;\n                long long max_y = bottom_y + rh;\n                for (const auto& pk : placed) {\n                    max_x = max(max_x, pk.x2);\n                    max_y = max(max_y, pk.y2);\n                }\n                \n                long long score = max_x + max_y;\n                if (prefer_square) {\n                    score += abs(max_x - max_y);\n                }\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_rot = rot;\n                    best_dir = 'U';\n                    best_x = left_x;\n                    best_y = bottom_y;\n                    best_ref = -1;\n                    \n                    // Find best reference\n                    for (const auto& pr : placed) {\n                        if (pr.x2 == left_x) {\n                            best_ref = pr.idx;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Try L placements\n            set<long long> y_candidates;\n            y_candidates.insert(0);\n            for (const auto& pr : placed) {\n                y_candidates.insert(pr.y2);\n                y_candidates.insert(pr.y1);\n                if (pr.y1 - rh >= 0) y_candidates.insert(pr.y1 - rh);\n            }\n            \n            for (long long top_y : y_candidates) {\n                long long right_x = 0;\n                for (const auto& pk : placed) {\n                    if (top_y < pk.y2 && top_y + rh > pk.y1) {\n                        right_x = max(right_x, pk.x2);\n                    }\n                }\n                \n                long long max_x = right_x + rw;\n                long long max_y = top_y + rh;\n                for (const auto& pk : placed) {\n                    max_x = max(max_x, pk.x2);\n                    max_y = max(max_y, pk.y2);\n                }\n                \n                long long score = max_x + max_y;\n                if (prefer_square) {\n                    score += abs(max_x - max_y);\n                }\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_rot = rot;\n                    best_dir = 'L';\n                    best_x = right_x;\n                    best_y = top_y;\n                    best_ref = -1;\n                    \n                    // Find best reference\n                    for (const auto& pr : placed) {\n                        if (pr.y2 == top_y) {\n                            best_ref = pr.idx;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        result.push_back({i, best_rot, best_dir, best_ref});\n        \n        long long rw = rects[i].w;\n        long long rh = rects[i].h;\n        if (best_rot) swap(rw, rh);\n        placed.push_back({best_x, best_y, best_x + rw, best_y + rh, i});\n    }\n    \n    return result;\n}\n\n// Smart rotation decision based on aspect ratio\nvector<bool> smart_rotation(const vector<bool>& use_rect, const string& mode) {\n    vector<bool> rot(N, false);\n    \n    for (int i = 0; i < N; i++) {\n        if (!use_rect[i]) continue;\n        \n        if (mode == \"wider\") {\n            // Rotate to make width >= height\n            if (rects[i].w < rects[i].h) rot[i] = true;\n        } else if (mode == \"taller\") {\n            // Rotate to make height >= width\n            if (rects[i].h < rects[i].w) rot[i] = true;\n        } else if (mode == \"squarelike\") {\n            // Rotate to make aspect ratio closer to 1\n            double ratio1 = (double)rects[i].w / rects[i].h;\n            double ratio2 = (double)rects[i].h / rects[i].w;\n            if (abs(ratio1 - 1.0) > abs(ratio2 - 1.0)) {\n                rot[i] = true;\n            }\n        } else if (mode == \"minarea\") {\n            // Try both and keep original (no rotation default)\n            rot[i] = false;\n        }\n    }\n    \n    return rot;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    rects.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].w >> rects[i].h;\n        rects[i].area = rects[i].w * rects[i].h;\n        rects[i].ratio = (double)rects[i].w / rects[i].h;\n    }\n    \n    long long best_score = 1LL << 60;\n    vector<Placement> best_packing;\n    \n    // Pre-compute orderings\n    vector<pair<long long, int>> area_order, width_order, height_order;\n    vector<pair<double, int>> ratio_order;\n    for (int i = 0; i < N; i++) {\n        area_order.push_back({rects[i].area, i});\n        width_order.push_back({rects[i].w, i});\n        height_order.push_back({rects[i].h, i});\n        ratio_order.push_back({rects[i].ratio, i});\n    }\n    sort(area_order.begin(), area_order.end());\n    sort(width_order.begin(), width_order.end());\n    sort(height_order.begin(), height_order.end());\n    sort(ratio_order.begin(), ratio_order.end());\n    \n    vector<string> rot_modes = {\"none\", \"wider\", \"taller\", \"squarelike\"};\n    \n    for (int turn = 0; turn < T; turn++) {\n        vector<Placement> packing;\n        int strategy = turn % 30;\n        \n        if (strategy < 4) {\n            // Simple row with different rotations\n            vector<bool> use(N, true);\n            vector<bool> rot = smart_rotation(use, rot_modes[strategy]);\n            packing = generate_row_packing(use, rot);\n        } else if (strategy < 8) {\n            // Two rows with different rotations and split ratios\n            vector<bool> use(N, true);\n            vector<bool> rot = smart_rotation(use, rot_modes[strategy - 4]);\n            int split = 40 + (turn % 3) * 10;\n            packing = generate_two_row_packing(use, rot, split);\n        } else if (strategy < 12) {\n            // Advanced best-fit with different rotations\n            vector<bool> use(N, true);\n            vector<bool> rot = smart_rotation(use, rot_modes[strategy - 8]);\n            bool prefer = (strategy % 2 == 0);\n            packing = generate_advanced_best_fit(use, rot, prefer);\n        } else if (strategy < 16) {\n            // Subset based on area (small rectangles)\n            int keep_count = max(1, N * (strategy - 10) / 10);\n            if (keep_count > N) keep_count = N;\n            vector<bool> use(N, false);\n            for (int i = 0; i < keep_count; i++) {\n                use[area_order[i].second] = true;\n            }\n            vector<bool> rot = smart_rotation(use, \"wider\");\n            packing = generate_advanced_best_fit(use, rot, true);\n        } else if (strategy < 20) {\n            // Skip large rectangles\n            int skip_count = (strategy - 15) * N / 10;\n            vector<bool> use(N, true);\n            for (int i = N - 1; i >= N - skip_count && i >= 0; i--) {\n                use[area_order[i].second] = false;\n            }\n            vector<bool> rot = smart_rotation(use, \"squarelike\");\n            packing = generate_advanced_best_fit(use, rot, true);\n        } else if (strategy < 24) {\n            // Subset based on height\n            int keep_count = max(1, N * (strategy - 18) / 10);\n            if (keep_count > N) keep_count = N;\n            vector<bool> use(N, false);\n            for (int i = 0; i < keep_count; i++) {\n                use[height_order[i].second] = true;\n            }\n            vector<bool> rot = smart_rotation(use, \"taller\");\n            packing = generate_advanced_best_fit(use, rot, false);\n        } else {\n            // Two rows with height-based ordering\n            vector<bool> use(N, true);\n            vector<bool> rot = smart_rotation(use, \"squarelike\");\n            packing = generate_two_row_packing(use, rot, 50);\n        }\n        \n        // Evaluate and update best\n        long long W, H;\n        long long score = evaluate_placement(packing, W, H);\n        \n        if (score < best_score) {\n            best_score = score;\n            best_packing = packing;\n        }\n        \n        // Output best packing\n        cout << (int)best_packing.size() << endl;\n        for (const auto& pl : best_packing) {\n            cout << pl.p << \" \" << pl.r << \" \" << pl.d << \" \" << pl.b << endl;\n        }\n        cout.flush();\n        \n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int i = 0; i < N; ++i) cin >> A[i];\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> parent(N, -1);\n    vector<int> depth(N, -1);\n    vector<bool> assigned(N, false);\n    vector<vector<int>> children(N);\n    \n    // Sort by beauty descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) {\n        return A[i] > A[j];\n    });\n    \n    for (int v : order) {\n        if (assigned[v]) continue;\n        \n        // BFS from v over unassigned vertices, up to depth H\n        vector<int> dist(N, -1);\n        vector<int> prev(N, -1);\n        queue<int> q;\n        dist[v] = 0;\n        q.push(v);\n        \n        int best_end = -1;\n        int best_attach = -1;\n        int best_total = -1;\n        \n        while (!q.empty()) {\n            int cur = q.front(); q.pop();\n            int d = dist[cur];\n            if (d == H) continue;\n            \n            for (int w : adj[cur]) {\n                if (assigned[w] && depth[w] < H) {\n                    int candidate_depth = depth[w] + 1 + d;\n                    if (candidate_depth <= H && candidate_depth > best_total) {\n                        best_total = candidate_depth;\n                        best_end = cur;\n                        best_attach = w;\n                    }\n                }\n                if (!assigned[w] && dist[w] == -1) {\n                    dist[w] = d + 1;\n                    prev[w] = cur;\n                    q.push(w);\n                }\n            }\n        }\n        \n        if (best_end != -1) {\n            // Reconstruct path: from best_end back to v (including both)\n            vector<int> path;\n            int cur = best_end;\n            while (cur != v) {\n                path.push_back(cur);\n                cur = prev[cur];\n            }\n            path.push_back(v);\n            // path = [best_end, ..., v] (descending order)\n            \n            // Assign nodes from best_end to v\n            int current_parent = best_attach;\n            int current_depth = depth[current_parent] + 1;\n            for (int node : path) {\n                parent[node] = current_parent;\n                depth[node] = current_depth;\n                children[current_parent].push_back(node);\n                assigned[node] = true;\n                current_parent = node;\n                current_depth++;\n            }\n        } else {\n            // Become root\n            parent[v] = -1;\n            depth[v] = 0;\n            assigned[v] = true;\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\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 20;\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Convert to mutable 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    }\n    \n    vector<string> ans;\n    \n    // Perform a shift\n    auto shift = [&](char dir, int idx, bool record = true) {\n        if (record) {\n            ans.push_back(string(1, dir) + \" \" + to_string(idx));\n        }\n        \n        if (dir == 'L') {\n            for (int j = 0; j < N-1; j++) {\n                board[idx][j] = board[idx][j+1];\n            }\n            board[idx][N-1] = '.';\n        } else if (dir == 'R') {\n            for (int j = N-1; j > 0; j--) {\n                board[idx][j] = board[idx][j-1];\n            }\n            board[idx][0] = '.';\n        } else if (dir == 'U') {\n            for (int i = 0; i < N-1; i++) {\n                board[i][idx] = board[i+1][idx];\n            }\n            board[N-1][idx] = '.';\n        } else { // 'D'\n            for (int i = N-1; i > 0; i--) {\n                board[i][idx] = board[i-1][idx];\n            }\n            board[0][idx] = '.';\n        }\n    };\n    \n    // Check if a line has Fuku\n    auto has_fuku = [&](int idx, bool is_row) -> bool {\n        if (is_row) {\n            for (int j = 0; j < N; j++) {\n                if (board[idx][j] == 'o') return true;\n            }\n        } else {\n            for (int i = 0; i < N; i++) {\n                if (board[i][idx] == 'o') return true;\n            }\n        }\n        return false;\n    };\n    \n    // Count Oni in a line\n    auto count_oni = [&](int idx, bool is_row) -> int {\n        int cnt = 0;\n        if (is_row) {\n            for (int j = 0; j < N; j++) {\n                if (board[idx][j] == 'x') cnt++;\n            }\n        } else {\n            for (int i = 0; i < N; i++) {\n                if (board[i][idx] == 'x') cnt++;\n            }\n        }\n        return cnt;\n    };\n    \n    // Check if a line has Oni\n    auto has_oni = [&](int idx, bool is_row) -> bool {\n        return count_oni(idx, is_row) > 0;\n    };\n    \n    // Find the shortest clear direction for a batch of Oni\n    // Returns (direction, max_distance) where max_distance is how many times we can push\n    auto find_batch_direction = [&]() -> tuple<char, int, int> {\n        int best_score = 0;\n        char best_dir = ' ';\n        int best_idx = -1;\n        int best_dist = 0;\n        \n        // For each row, check left and right\n        for (int i = 0; i < N; i++) {\n            if (!has_fuku(i, true)) {\n                // Check left\n                int max_dist = 0;\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, j + 1);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(i, true) * 2 - max_dist; // Prefer removing many Oni with few shifts\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'L';\n                        best_idx = i;\n                        best_dist = max_dist;\n                    }\n                }\n                \n                // Check right\n                max_dist = 0;\n                for (int j = 0; j < N; j++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, N - j);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(i, true) * 2 - max_dist;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'R';\n                        best_idx = i;\n                        best_dist = max_dist;\n                    }\n                }\n            }\n        }\n        \n        // For each column, check up and down\n        for (int j = 0; j < N; j++) {\n            if (!has_fuku(j, false)) {\n                // Check up\n                int max_dist = 0;\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, i + 1);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(j, false) * 2 - max_dist;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'U';\n                        best_idx = j;\n                        best_dist = max_dist;\n                    }\n                }\n                \n                // Check down\n                max_dist = 0;\n                for (int i = 0; i < N; i++) {\n                    if (board[i][j] == 'x') {\n                        max_dist = max(max_dist, N - i);\n                    }\n                }\n                if (max_dist > 0) {\n                    int score = count_oni(j, false) * 2 - max_dist;\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = 'D';\n                        best_idx = j;\n                        best_dist = max_dist;\n                    }\n                }\n            }\n        }\n        \n        return {best_dir, best_idx, best_dist};\n    };\n    \n    // Main loop\n    while (true) {\n        // Check if there are any Oni\n        bool has_oni_remaining = false;\n        for (int i = 0; i < N && !has_oni_remaining; i++) {\n            for (int j = 0; j < N && !has_oni_remaining; j++) {\n                if (board[i][j] == 'x') has_oni_remaining = true;\n            }\n        }\n        \n        if (!has_oni_remaining) break;\n        \n        auto [dir, idx, dist] = find_batch_direction();\n        \n        if (dir == ' ') {\n            // No safe batch direction found - use individual Oni removal\n            // Find an Oni with clear direction\n            bool found = false;\n            for (int i = 0; i < N && !found; i++) {\n                for (int j = 0; j < N && !found; j++) {\n                    if (board[i][j] != 'x') continue;\n                    \n                    // Check each direction\n                    bool clear_up = true;\n                    bool clear_down = true;\n                    bool clear_left = true;\n                    bool clear_right = true;\n                    \n                    for (int k = i-1; k >= 0 && clear_up; k--) {\n                        if (board[k][j] == 'o') clear_up = false;\n                    }\n                    for (int k = i+1; k < N && clear_down; k++) {\n                        if (board[k][j] == 'o') clear_down = false;\n                    }\n                    for (int k = j-1; k >= 0 && clear_left; k--) {\n                        if (board[i][k] == 'o') clear_left = false;\n                    }\n                    for (int k = j+1; k < N && clear_right; k++) {\n                        if (board[i][k] == 'o') clear_right = false;\n                    }\n                    \n                    if (clear_up) {\n                        for (int t = 0; t < i + 1; t++) shift('U', j);\n                        for (int t = 0; t < i + 1; t++) shift('D', j);\n                        found = true;\n                    } else if (clear_down) {\n                        for (int t = 0; t < N - i; t++) shift('D', j);\n                        for (int t = 0; t < N - i; t++) shift('U', j);\n                        found = true;\n                    } else if (clear_left) {\n                        for (int t = 0; t < j + 1; t++) shift('L', i);\n                        for (int t = 0; t < j + 1; t++) shift('R', i);\n                        found = true;\n                    } else if (clear_right) {\n                        for (int t = 0; t < N - j; t++) shift('R', i);\n                        for (int t = 0; t < N - j; t++) shift('L', i);\n                        found = true;\n                    }\n                }\n            }\n        } else {\n            // Batch removal: push dist times in direction, then pull dist times back\n            char opposite;\n            if (dir == 'L') opposite = 'R';\n            else if (dir == 'R') opposite = 'L';\n            else if (dir == 'U') opposite = 'D';\n            else opposite = 'U';\n            \n            for (int t = 0; t < dist; t++) {\n                shift(dir, idx);\n            }\n            for (int t = 0; t < dist; t++) {\n                shift(opposite, idx);\n            }\n        }\n    }\n    \n    // Output\n    for (const string& s : ans) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#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 = 100;\n    const int L = 500000;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    // Create a solution that balances flow based on target frequencies\n    vector<int> a(N), b(N);\n    \n    // The key idea: For each employee i, the number of times they visit a_i vs b_i\n    // differs by at most 1. So the total outgoing flow to j depends on how many\n    // employees point to j with their a_i or b_i.\n    \n    // If we can make the incoming flow approximately proportional to T,\n    // we'll achieve low error.\n    \n    // Simple approach: Create a cyclic shift based on sorted order\n    vector<pair<int,int>> sorted;\n    for (int i = 0; i < N; i++) {\n        sorted.push_back({T[i], i});\n    }\n    sort(sorted.begin(), sorted.end(), greater<>());\n    \n    // Now assign successors: each employee points two steps ahead in sorted order\n    // This creates good mixing\n    for (int i = 0; i < N; i++) {\n        int emp = sorted[i].second;\n        int idx1 = (i + 1) % N;\n        int idx2 = (i + 2) % N;\n        a[emp] = sorted[idx1].second;\n        b[emp] = sorted[idx2].second;\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\n\nstruct City {\n    int lx, rx, ly, ry;\n    int cx, cy;\n};\n\nvector<City> cities;\n\n// Fast inline query function\ninline vector<pair<int,int>> make_query(const vector<int>& subset) {\n    int sz = subset.size();\n    cout << \"? \" << sz;\n    for (int x : subset) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int,int>> result(sz - 1);\n    for (int i = 0; i < sz - 1; i++) {\n        cin >> result[i].first >> result[i].second;\n        if (result[i].first > result[i].second) \n            swap(result[i].first, result[i].second);\n    }\n    return result;\n}\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n) : p(n), sz(n, 1) {\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int x) {\n        while (p[x] != x) {\n            p[x] = p[p[x]];\n            x = p[x];\n        }\n        return x;\n    }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\n// Check rectangle overlap\ninline bool rectangles_overlap(int i, int j) {\n    const auto& a = cities[i];\n    const auto& b = cities[j];\n    return !(a.rx < b.lx || b.rx < a.lx || a.ry < b.ly || b.ry < a.ly);\n}\n\n// Estimate distance using center points\ninline int center_dist(int i, int j) {\n    long long dx = cities[i].cx - cities[j].cx;\n    long long dy = cities[i].cy - cities[j].cy;\n    return (int)sqrt((double)(dx * dx + dy * dy));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read input\n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cities.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        cities[i].cx = (cities[i].lx + cities[i].rx) / 2;\n        cities[i].cy = (cities[i].ly + cities[i].ry) / 2;\n    }\n    \n    // Build proximity graph\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            if (rectangles_overlap(i, j)) {\n                adj[i].push_back(j);\n                adj[j].push_back(i);\n            }\n        }\n    }\n    \n    // Better group assignment using spatial order with overlap consideration\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        // Sort by center, but prefer cities with more overlapping neighbors\n        int deg_a = adj[a].size(), deg_b = adj[b].size();\n        if (deg_a != deg_b) return deg_a > deg_b;\n        if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n        return cities[a].cy < cities[b].cy;\n    });\n    \n    // Assign to groups\n    vector<vector<int>> groups(M);\n    vector<int> group_sizes = G;\n    vector<bool> city_used(N, false);\n    \n    // Process groups from largest to smallest\n    vector<pair<int,int>> size_idx;\n    for (int k = 0; k < M; k++) {\n        size_idx.push_back({G[k], k});\n    }\n    sort(size_idx.begin(), size_idx.end(), greater<pair<int,int>>());\n    \n    for (auto& [sz, k] : size_idx) {\n        groups[k].reserve(sz);\n        \n        // Find best unused starting city (most overlap with other unused cities)\n        int best = -1;\n        int best_score = -1;\n        for (int i = 0; i < N; i++) {\n            if (!city_used[i]) {\n                int score = 0;\n                for (int v : adj[i]) {\n                    if (!city_used[v]) score++;\n                }\n                if (score > best_score) {\n                    best_score = score;\n                    best = i;\n                }\n            }\n        }\n        \n        if (best == -1) {\n            // Fallback: take first unused city\n            for (int i = 0; i < N; i++) {\n                if (!city_used[i]) {\n                    best = i;\n                    break;\n                }\n            }\n        }\n        \n        // BFS to collect nearby cities\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(best);\n        visited[best] = true;\n        \n        while (!q.empty() && (int)groups[k].size() < sz) {\n            int v = q.front(); q.pop();\n            if (!city_used[v]) {\n                groups[k].push_back(v);\n                city_used[v] = true;\n            }\n            \n            // Add neighbors\n            for (int u : adj[v]) {\n                if (!visited[u] && !city_used[u] && (int)groups[k].size() < sz) {\n                    visited[u] = true;\n                    q.push(u);\n                }\n            }\n        }\n        \n        // Fill remaining with closest unused cities by center distance\n        if ((int)groups[k].size() < sz) {\n            vector<pair<int,int>> remaining;\n            for (int i = 0; i < N; i++) {\n                if (!city_used[i]) {\n                    int min_dist = INT_MAX;\n                    for (int c : groups[k]) {\n                        min_dist = min(min_dist, center_dist(c, i));\n                    }\n                    remaining.push_back({min_dist, i});\n                }\n            }\n            sort(remaining.begin(), remaining.end());\n            \n            for (auto& [dist, idx] : remaining) {\n                if ((int)groups[k].size() >= sz) break;\n                if (!city_used[idx]) {\n                    groups[k].push_back(idx);\n                    city_used[idx] = true;\n                }\n            }\n        }\n    }\n    \n    // Query phase - maximize efficiency\n    vector<vector<pair<int,int>>> group_edges(M);\n    set<pair<int,int>> known_edges;\n    int queries_used = 0;\n    \n    // Process groups in order of size (largest first gets more queries)\n    for (auto& [sz, k] : size_idx) {\n        if (queries_used >= Q) break;\n        \n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g <= 1) continue;\n        if (g == 2) {\n            group_edges[k].push_back({group[0], group[1]});\n            continue;\n        }\n        \n        // Use maximum query size L for efficiency\n        int window_size = min(L, g);\n        \n        // Make overlapping queries to cover entire group\n        for (int start = 0; start < g && queries_used < Q; start += max(1, window_size - 2)) {\n            int end = min(start + window_size, g);\n            if (end - start < 2) {\n                end = g;\n                start = max(0, g - window_size);\n                if (end - start < 2) break;\n            }\n            \n            vector<int> subset;\n            subset.reserve(end - start);\n            for (int j = start; j < end; j++) {\n                subset.push_back(group[j]);\n            }\n            \n            auto results = make_query(subset);\n            queries_used++;\n            \n            for (auto& e : results) {\n                known_edges.insert(e);\n            }\n        }\n    }\n    \n    // Use remaining queries to discover edges between close cities across groups\n    if (queries_used < Q) {\n        vector<pair<int,int>> unqueried_overlaps;\n        for (int i = 0; i < N; i++) {\n            for (int j : adj[i]) {\n                if (i < j && known_edges.count({i, j}) == 0) {\n                    unqueried_overlaps.push_back({i, j});\n                }\n            }\n        }\n        \n        // Query in batches\n        for (int i = 0; i < (int)unqueried_overlaps.size() && queries_used < Q; i += L) {\n            set<int> subset_set;\n            for (int j = i; j < min(i + L, (int)unqueried_overlaps.size()); j++) {\n                if ((int)subset_set.size() >= L) break;\n                subset_set.insert(unqueried_overlaps[j].first);\n                if ((int)subset_set.size() < L) {\n                    subset_set.insert(unqueried_overlaps[j].second);\n                }\n            }\n            \n            vector<int> subset(subset_set.begin(), subset_set.end());\n            if ((int)subset.size() >= 2) {\n                auto results = make_query(subset);\n                queries_used++;\n                for (auto& e : results) {\n                    known_edges.insert(e);\n                }\n            }\n        }\n    }\n    \n    // Build MST for each group\n    for (int k = 0; k < M; k++) {\n        const auto& group = groups[k];\n        int g = G[k];\n        \n        if (g <= 1) continue;\n        if (g == 2) {\n            if (group_edges[k].empty()) {\n                group_edges[k].push_back({group[0], group[1]});\n            }\n            continue;\n        }\n        \n        DSU dsu(N);\n        group_edges[k].clear();\n        group_edges[k].reserve(g - 1);\n        \n        // Build and sort candidate edges\n        vector<tuple<int,int,int>> candidates; // (priority, u, v)\n        candidates.reserve(g * (g - 1) / 2);\n        \n        for (int i = 0; i < g; i++) {\n            for (int j = i + 1; j < g; j++) {\n                int u = group[i], v = group[j];\n                if (u > v) swap(u, v);\n                \n                int priority;\n                if (known_edges.count({u, v})) {\n                    priority = -1; // Highest priority\n                } else if (rectangles_overlap(u, v)) {\n                    priority = 0; // Very likely close\n                } else {\n                    priority = center_dist(u, v) + 1;\n                }\n                candidates.push_back({priority, u, v});\n            }\n        }\n        \n        sort(candidates.begin(), candidates.end());\n        \n        int added = 0;\n        for (auto& [priority, u, v] : candidates) {\n            if (dsu.unite(u, v)) {\n                group_edges[k].push_back({u, v});\n                added++;\n                if (added == g - 1) break;\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    cout.flush();\n    \n    for (int k = 0; k < M; k++) {\n        for (int j = 0; j < G[k]; j++) {\n            if (j > 0) cout << \" \";\n            cout << groups[k][j];\n        }\n        cout << endl;\n        \n        for (auto& e : group_edges[k]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Cell {\n    int r, c;\n    Cell(int r = 0, int c = 0) : r(r), c(c) {}\n};\n\nstring dirs = \"UDLR\";\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<Cell> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].r >> targets[i].c;\n    }\n    \n    // State tracking\n    vector<string> grid(N, string(N, '.'));\n    int posR = targets[0].r, posC = targets[0].c;\n    vector<string> actions;\n    \n    auto getBlock = [&](int r, int c) -> bool {\n        return !(r >= 0 && r < N && c >= 0 && c < N) || grid[r][c] == '#';\n    };\n    \n    // Simple strategy: Use Manhattan moves with occasional slides\n    for (int idx = 1; idx < M; idx++) {\n        int tr = targets[idx].r, tc = targets[idx].c;\n        \n        // While not at target, move towards it\n        while (posR != tr || posC != tc) {\n            // Try to find a good slide direction\n            int bestSlideDir = -1;\n            int bestSlideDist = abs(posR - tr) + abs(posC - tc);\n            \n            for (int d = 0; d < 4; d++) {\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Slide as far as possible in this direction\n                    int sr = nr, sc = nc;\n                    while (true) {\n                        int nnr = sr + dr[d], nnc = sc + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        sr = nnr; sc = nnc;\n                    }\n                    int dist = abs(sr - tr) + abs(sc - tc);\n                    if (dist < bestSlideDist) {\n                        bestSlideDist = dist;\n                        bestSlideDir = d;\n                    }\n                }\n            }\n            \n            bool usedSlide = false;\n            if (bestSlideDir >= 0) {\n                int d = bestSlideDir;\n                int nr = posR + dr[d], nc = posC + dc[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                    // Execute slide\n                    actions.push_back(\"S \" + string(1, dirs[d]));\n                    \n                    // Update position\n                    while (true) {\n                        int nnr = posR + dr[d], nnc = posC + dc[d];\n                        if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || getBlock(nnr, nnc)) break;\n                        posR = nnr; posC = nnc;\n                    }\n                    usedSlide = true;\n                }\n            }\n            \n            if (!usedSlide) {\n                // Simple move towards target\n                int bestDir = -1;\n                int bestDist = abs(posR - tr) + abs(posC - tc);\n                \n                for (int d = 0; d < 4; d++) {\n                    int nr = posR + dr[d], nc = posC + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !getBlock(nr, nc)) {\n                        int dist = abs(nr - tr) + abs(nc - tc);\n                        if (dist < bestDist) {\n                            bestDist = dist;\n                            bestDir = d;\n                        }\n                    }\n                }\n                \n                if (bestDir >= 0) {\n                    // Check if we can place a block to improve future slides\n                    // For simplicity, just move\n                    int nr = posR + dr[bestDir], nc = posC + dc[bestDir];\n                    actions.push_back(\"M \" + string(1, dirs[bestDir]));\n                    posR = nr; posC = nc;\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (const auto& a : actions) {\n        cout << a << \"\\n\";\n    }\n    \n    return 0;\n}"}}}