{"model_name":"qwen3-coder-plus","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int id, x, y, r;\n    bool operator<(const Company& other) const {\n        return r > other.r; // Sort by area descending\n    }\n};\n\nstruct Rectangle {\n    int a, b, c, d; // (a,b) to (c,d)\n};\n\nconst int SIZE = 10000;\nvector<vector<bool>> occupied(SIZE, vector<bool>(SIZE, false));\nvector<Rectangle> result;\nvector<Company> companies;\n\n// Check if rectangle overlaps with existing ones\nbool is_valid(int a, int b, int c, int d) {\n    if (a < 0 || b < 0 || c > SIZE || d > SIZE) return false;\n    if (a >= c || b >= d) return false;\n    \n    for (int i = a; i < c; i++) {\n        for (int j = b; j < d; j++) {\n            if (occupied[i][j]) return false;\n        }\n    }\n    return true;\n}\n\n// Mark rectangle as occupied\nvoid mark_occupied(int a, int b, int c, int d, bool mark = true) {\n    for (int i = a; i < c; i++) {\n        for (int j = b; j < d; j++) {\n            occupied[i][j] = mark;\n        }\n    }\n}\n\n// Find factors of area\nvector<pair<int, int>> get_factors(int area) {\n    vector<pair<int, int>> factors;\n    for (int w = 1; w * w <= area; w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            factors.push_back({w, h});\n            if (w != h) factors.push_back({h, w});\n        }\n    }\n    return factors;\n}\n\n// Try to place rectangle for company\nbool place_company(const Company& comp) {\n    int target_x = comp.x;\n    int target_y = comp.y;\n    int area = comp.r;\n    \n    auto factors = get_factors(area);\n    \n    // Try different rectangle shapes\n    for (auto& factor : factors) {\n        int w = factor.first;\n        int h = factor.second;\n        \n        // Try different positions around the target point\n        for (int dx = -w/2; dx <= w/2; dx++) {\n            for (int dy = -h/2; dy <= h/2; dy++) {\n                int a = target_x + dx;\n                int b = target_y + dy;\n                int c = a + w;\n                int d = b + h;\n                \n                // Check if the target point is inside (using 0.5 offset)\n                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                    if (is_valid(a, b, c, d)) {\n                        mark_occupied(a, b, c, d);\n                        result[comp.id] = {a, b, c, d};\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // If exact area doesn't work, try approximate areas\n    for (int delta = 1; delta <= min(100, area/10); delta++) {\n        vector<int> test_areas = {area + delta, area - delta};\n        for (int test_area : test_areas) {\n            if (test_area <= 0) continue;\n            \n            auto test_factors = get_factors(test_area);\n            for (auto& factor : test_factors) {\n                int w = factor.first;\n                int h = factor.second;\n                \n                for (int dx = -w/2; dx <= w/2; dx++) {\n                    for (int dy = -h/2; dy <= h/2; dy++) {\n                        int a = target_x + dx;\n                        int b = target_y + dy;\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                            if (is_valid(a, b, c, d)) {\n                                mark_occupied(a, b, c, d);\n                                result[comp.id] = {a, b, c, d};\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Last resort: place any valid rectangle\n    for (int w = 1; w <= min(100, area); w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            for (int a = max(0, target_x - w + 1); a <= min(SIZE - w, target_x); a++) {\n                for (int b = max(0, target_y - h + 1); b <= min(SIZE - h, target_y); b++) {\n                    int c = a + w;\n                    int d = b + h;\n                    \n                    if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                        if (is_valid(a, b, c, d)) {\n                            mark_occupied(a, b, c, d);\n                            result[comp.id] = {a, b, c, d};\n                            return true;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Place smallest possible rectangle as fallback\n    int a = max(0, min(target_x, SIZE - 1));\n    int b = max(0, min(target_y, SIZE - 1));\n    int c = min(SIZE, a + 1);\n    int d = min(SIZE, b + 1);\n    a = max(0, c - 1);\n    b = max(0, d - 1);\n    \n    if (is_valid(a, b, c, d)) {\n        mark_occupied(a, b, c, d);\n        result[comp.id] = {a, b, c, d};\n        return true;\n    }\n    \n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    companies.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        companies[i].id = i;\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n    \n    // Sort by area descending\n    sort(companies.begin(), companies.end());\n    \n    // Place each company\n    for (const auto& company : companies) {\n        place_company(company);\n    }\n    \n    // Output results\n    for (const auto& rect : result) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SIZE = 50;\nint si, sj;\nint tile_id[SIZE][SIZE];\nint points[SIZE][SIZE];\nvector<pair<int,int>> tile_cells[2500]; // max possible tiles\nbool tile_visited[2500];\nstring best_path;\nint best_score = 0;\n\n// Directions: U, D, L, R\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nvoid preprocess_tiles() {\n    bool processed[2500] = {false};\n    int max_tile_id = 0;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            max_tile_id = max(max_tile_id, tile_id[i][j]);\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            int tid = tile_id[i][j];\n            tile_cells[tid].push_back({i, j});\n        }\n    }\n}\n\nint get_tile_value(int tile_id) {\n    int value = 0;\n    for (auto& cell : tile_cells[tile_id]) {\n        value += points[cell.first][cell.second];\n    }\n    return value;\n}\n\nbool is_valid_move(int x, int y) {\n    return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n}\n\nvector<pair<int,int>> get_adjacent_cells(int x, int y) {\n    vector<pair<int,int>> adj;\n    for (int d = 0; d < 4; d++) {\n        int nx = x + dx[d];\n        int ny = y + dy[d];\n        if (is_valid_move(nx, ny)) {\n            adj.push_back({nx, ny});\n        }\n    }\n    return adj;\n}\n\nset<int> get_adjacent_unvisited_tiles(int current_x, int current_y) {\n    set<int> adjacent_tiles;\n    \n    // Get all cells of current tile\n    int current_tile = tile_id[current_x][current_y];\n    \n    // Check all cells of current tile for adjacent cells\n    for (auto& cell : tile_cells[current_tile]) {\n        auto adj_cells = get_adjacent_cells(cell.first, cell.second);\n        for (auto& adj_cell : adj_cells) {\n            int adj_tile = tile_id[adj_cell.first][adj_cell.second];\n            if (!tile_visited[adj_tile]) {\n                adjacent_tiles.insert(adj_tile);\n            }\n        }\n    }\n    \n    return adjacent_tiles;\n}\n\n// Simple greedy approach with some lookahead\nstring greedy_search() {\n    // Reset visited status\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int current_x = si, current_y = sj;\n    int current_tile = tile_id[current_x][current_y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    // Look ahead a few steps\n    for (int step = 0; step < 2000; step++) { // Limit path length\n        auto adjacent_tiles = get_adjacent_unvisited_tiles(current_x, current_y);\n        \n        if (adjacent_tiles.empty()) {\n            break;\n        }\n        \n        // Find best next tile based on value and potential\n        int best_tile = -1;\n        int best_value = -1;\n        pair<int,int> best_cell;\n        char best_direction = ' ';\n        \n        // Check all adjacent unvisited tiles\n        for (int tile : adjacent_tiles) {\n            int tile_value = get_tile_value(tile);\n            \n            // Find the best cell in this tile to move to\n            for (auto& cell : tile_cells[tile]) {\n                // Check if this cell is adjacent to current position\n                bool is_adjacent = false;\n                char direction = ' ';\n                \n                // Get all cells of current tile\n                for (auto& cur_cell : tile_cells[current_tile]) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = cur_cell.first + dx[d];\n                        int ny = cur_cell.second + dy[d];\n                        if (is_valid_move(nx, ny) && nx == cell.first && ny == cell.second) {\n                            is_adjacent = true;\n                            direction = dir_char[d];\n                            break;\n                        }\n                    }\n                    if (is_adjacent) break;\n                }\n                \n                if (is_adjacent && tile_value > best_value) {\n                    best_value = tile_value;\n                    best_tile = tile;\n                    best_cell = cell;\n                    best_direction = direction;\n                }\n            }\n        }\n        \n        if (best_tile == -1) {\n            break;\n        }\n        \n        // Move to best tile\n        tile_visited[best_tile] = true;\n        current_x = best_cell.first;\n        current_y = best_cell.second;\n        current_tile = best_tile;\n        path += best_direction;\n    }\n    \n    return path;\n}\n\n// Improved greedy with better evaluation\nstring improved_greedy() {\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int current_x = si, current_y = sj;\n    int current_tile = tile_id[current_x][current_y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    int total_score = 0;\n    \n    // Add initial position score\n    for (auto& cell : tile_cells[current_tile]) {\n        total_score += points[cell.first][cell.second];\n    }\n    \n    for (int step = 0; step < 2500; step++) {\n        auto adjacent_tiles = get_adjacent_unvisited_tiles(current_x, current_y);\n        \n        if (adjacent_tiles.empty()) {\n            break;\n        }\n        \n        // Evaluate moves more carefully\n        struct Move {\n            int tile_id;\n            pair<int,int> target_cell;\n            char direction;\n            int value;\n            double score; // value + some heuristic\n        };\n        \n        vector<Move> possible_moves;\n        \n        // Collect all possible moves\n        for (int tile : adjacent_tiles) {\n            int tile_value = get_tile_value(tile);\n            \n            // Find all ways to reach this tile\n            for (auto& cell : tile_cells[tile]) {\n                // Check adjacency from current tile\n                for (auto& cur_cell : tile_cells[current_tile]) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = cur_cell.first + dx[d];\n                        int ny = cur_cell.second + dy[d];\n                        if (is_valid_move(nx, ny) && nx == cell.first && ny == cell.second) {\n                            Move move;\n                            move.tile_id = tile;\n                            move.target_cell = cell;\n                            move.direction = dir_char[d];\n                            move.value = tile_value;\n                            \n                            // Simple scoring: just the tile value\n                            move.score = tile_value;\n                            possible_moves.push_back(move);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (possible_moves.empty()) {\n            break;\n        }\n        \n        // Sort by score descending\n        sort(possible_moves.begin(), possible_moves.end(), \n             [](const Move& a, const Move& b) { return a.score > b.score; });\n        \n        // Take the best move\n        auto& best_move = possible_moves[0];\n        tile_visited[best_move.tile_id] = true;\n        current_x = best_move.target_cell.first;\n        current_y = best_move.target_cell.second;\n        current_tile = best_move.tile_id;\n        path += best_move.direction;\n        total_score += best_move.value;\n    }\n    \n    if (total_score > best_score) {\n        best_score = total_score;\n        best_path = path;\n    }\n    \n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> tile_id[i][j];\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess_tiles();\n    \n    // Try multiple approaches and take the best\n    string result = improved_greedy();\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int QUERY_COUNT = 1000;\n\n// Edge weight estimates\nvector<vector<double>> h_edges; // horizontal edges (i,j) to (i,j+1)\nvector<vector<double>> v_edges; // vertical edges (i,j) to (i+1,j)\n\n// History of paths and their actual lengths for learning\nvector<vector<pair<int,int>>> path_history;\nvector<int> actual_length_history;\n\n// Initialize edge weights\nvoid initialize_weights() {\n    h_edges.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 5000.0));\n    v_edges.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 5000.0));\n}\n\n// Calculate path length using current estimates\ndouble calculate_estimated_length(const vector<pair<int,int>>& path) {\n    double length = 0.0;\n    for (int i = 0; i < (int)path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) {\n            length += h_edges[r1][c1];\n        } else if (r1 == r2 && c2 == c1 - 1) {\n            length += h_edges[r1][c2];\n        } else if (c1 == c2 && r2 == r1 + 1) {\n            length += v_edges[r1][c1];\n        } else if (c1 == c2 && r2 == r1 - 1) {\n            length += v_edges[r2][c1];\n        }\n    }\n    return length;\n}\n\n// Get actual length from the last query\nint get_actual_length() {\n    int actual_length;\n    cin >> actual_length;\n    return actual_length;\n}\n\n// Find shortest path using A* with current estimates\nvector<pair<int,int>> find_shortest_path(int start_r, int start_c, int end_r, int end_c) {\n    // Priority queue: {f_score, g_score, row, col}\n    priority_queue<tuple<double, double, int, int>, vector<tuple<double, double, int, int>>, greater<>> pq;\n    \n    // Distance and parent tracking\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int,int>>> parent(GRID_SIZE, vector<pair<int,int>>(GRID_SIZE, {-1, -1}));\n    \n    auto heuristic = [&](int r, int c) {\n        return abs(r - end_r) + abs(c - end_c);\n    };\n    \n    dist[start_r][start_c] = 0;\n    pq.push({heuristic(start_r, start_c), 0.0, start_r, start_c});\n    \n    vector<pair<int,int>> directions = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // U, D, L, R\n    \n    while (!pq.empty()) {\n        auto [f_score, g_score, r, c] = pq.top();\n        pq.pop();\n        \n        if (g_score > dist[r][c]) continue;\n        \n        if (r == end_r && c == end_c) break;\n        \n        // Explore neighbors\n        for (int dir = 0; dir < 4; dir++) {\n            int dr = directions[dir].first;\n            int dc = directions[dir].second;\n            int nr = r + dr;\n            int nc = c + dc;\n            \n            // Check bounds\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            \n            double edge_cost = 0;\n            if (dr == 0 && dc == 1) { // Right\n                edge_cost = h_edges[r][c];\n            } else if (dr == 0 && dc == -1) { // Left\n                edge_cost = h_edges[nr][nc];\n            } else if (dr == 1 && dc == 0) { // Down\n                edge_cost = v_edges[r][c];\n            } else if (dr == -1 && dc == 0) { // Up\n                edge_cost = v_edges[nr][nc];\n            }\n            \n            double new_g_score = g_score + edge_cost;\n            if (new_g_score < dist[nr][nc]) {\n                dist[nr][nc] = new_g_score;\n                parent[nr][nc] = {r, c};\n                double f_score = new_g_score + heuristic(nr, nc);\n                pq.push({f_score, new_g_score, nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int r = end_r, c = end_c;\n    while (r != -1 && c != -1) {\n        path.push_back({r, c});\n        auto p = parent[r][c];\n        r = p.first;\n        c = p.second;\n    }\n    reverse(path.begin(), path.end());\n    \n    return path;\n}\n\n// Convert path to direction string\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r2 == r1 - 1) result += 'U';\n        else if (r2 == r1 + 1) result += 'D';\n        else if (c2 == c1 - 1) result += 'L';\n        else if (c2 == c1 + 1) result += 'R';\n    }\n    return result;\n}\n\n// Update edge weights based on actual path performance\nvoid update_weights(const vector<pair<int,int>>& path, int actual_length) {\n    if (path.size() < 2) return;\n    \n    double estimated_length = calculate_estimated_length(path);\n    double error = actual_length - estimated_length;\n    \n    // Learning rate decreases over time\n    double learning_rate = 0.1 * exp(-0.002 * path_history.size());\n    \n    // Distribute error among edges in the path\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) { // Right\n            h_edges[r1][c1] += learning_rate * error / (path.size() - 1);\n            h_edges[r1][c1] = max(100.0, min(10000.0, h_edges[r1][c1]));\n        } else if (r1 == r2 && c2 == c1 - 1) { // Left\n            h_edges[r1][c2] += learning_rate * error / (path.size() - 1);\n            h_edges[r1][c2] = max(100.0, min(10000.0, h_edges[r1][c2]));\n        } else if (c1 == c2 && r2 == r1 + 1) { // Down\n            v_edges[r1][c1] += learning_rate * error / (path.size() - 1);\n            v_edges[r1][c1] = max(100.0, min(10000.0, v_edges[r1][c1]));\n        } else if (c1 == c2 && r2 == r1 - 1) { // Up\n            v_edges[r2][c1] += learning_rate * error / (path.size() - 1);\n            v_edges[r2][c1] = max(100.0, min(10000.0, v_edges[r2][c1]));\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_weights();\n    \n    for (int query = 0; query < QUERY_COUNT; query++) {\n        int start_r, start_c, end_r, end_c;\n        cin >> start_r >> start_c >> end_r >> end_c;\n        \n        // For the first few queries, we might want to add some exploration\n        vector<pair<int,int>> path = find_shortest_path(start_r, start_c, end_r, end_c);\n        \n        string path_str = path_to_string(path);\n        cout << path_str << endl;\n        cout.flush();\n        \n        // Store path for learning\n        path_history.push_back(path);\n        \n        // Get actual length and update weights\n        int actual_length = get_actual_length();\n        actual_length_history.push_back(actual_length);\n        \n        update_weights(path, actual_length);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst string ALPHABET = \"ABCDEFGH\";\n\nstruct StringInfo {\n    string s;\n    int id;\n    bool placed = false;\n    int row = -1, col = -1;\n    bool horizontal = true;\n};\n\nvector<string> matrix(N, string(N, '.'));\nvector<StringInfo> strings;\nint M;\n\n// Check if string can be placed at position (r,c) in given direction\nbool canPlace(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        \n        if (matrix[nr][nc] != '.' && matrix[nr][nc] != s[i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place string at position (r,c) in given direction\nvoid placeString(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        matrix[nr][nc] = s[i];\n    }\n}\n\n// Count how many strings are currently matched\nint countMatches() {\n    int count = 0;\n    for (const auto& str_info : strings) {\n        const string& s = str_info.s;\n        bool found = false;\n        \n        // Check horizontal placements\n        for (int r = 0; r < N && !found; r++) {\n            for (int c = 0; c < N && !found; c++) {\n                bool match = true;\n                for (int i = 0; i < (int)s.length(); i++) {\n                    int nc = (c + i) % N;\n                    if (matrix[r][nc] != s[i]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) {\n                    found = true;\n                }\n            }\n        }\n        \n        // Check vertical placements\n        if (!found) {\n            for (int c = 0; c < N && !found; c++) {\n                for (int r = 0; r < N && !found; r++) {\n                    bool match = true;\n                    for (int i = 0; i < (int)s.length(); i++) {\n                        int nr = (r + i) % N;\n                        if (matrix[nr][c] != s[i]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                    }\n                }\n            }\n        }\n        \n        if (found) count++;\n    }\n    return count;\n}\n\n// Try to place as many strings as possible\nvoid greedyPlacement() {\n    // Sort strings by length (longer first might be better)\n    vector<pair<int, int>> str_lengths;\n    for (int i = 0; i < M; i++) {\n        str_lengths.push_back({(int)strings[i].s.length(), i});\n    }\n    sort(str_lengths.rbegin(), str_lengths.rend());\n    \n    for (const auto& p : str_lengths) {\n        int idx = p.second;\n        const string& s = strings[idx].s;\n        \n        // Try to place this string\n        bool placed = false;\n        \n        // Try horizontal placements first\n        for (int r = 0; r < N && !placed; r++) {\n            for (int c = 0; c < N && !placed; c++) {\n                if (canPlace(s, r, c, true)) {\n                    placeString(s, r, c, true);\n                    strings[idx].placed = true;\n                    strings[idx].row = r;\n                    strings[idx].col = c;\n                    strings[idx].horizontal = true;\n                    placed = true;\n                }\n            }\n        }\n        \n        // Try vertical placements if horizontal didn't work\n        if (!placed) {\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    if (canPlace(s, r, c, false)) {\n                        placeString(s, r, c, false);\n                        strings[idx].placed = true;\n                        strings[idx].row = r;\n                        strings[idx].col = c;\n                        strings[idx].horizontal = false;\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Improve by trying to fill empty spots\nvoid fillEmptySpots() {\n    // For each empty cell, try to determine the best character\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matrix[r][c] == '.') {\n                // Count which characters would help match more strings\n                map<char, int> char_score;\n                \n                for (char ch : ALPHABET) {\n                    matrix[r][c] = ch;\n                    int new_matches = countMatches();\n                    char_score[ch] = new_matches;\n                }\n                \n                // Choose character that maximizes matches\n                char best_char = '.';\n                int best_score = -1;\n                for (const auto& p : char_score) {\n                    if (p.second > best_score) {\n                        best_score = p.second;\n                        best_char = p.first;\n                    }\n                }\n                \n                matrix[r][c] = best_char;\n            }\n        }\n    }\n}\n\n// Simple randomized approach\nvoid randomImprovement() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    int current_matches = countMatches();\n    \n    // Try random changes\n    for (int iter = 0; iter < 1000; iter++) {\n        // Pick a random cell\n        int r = gen() % N;\n        int c = gen() % N;\n        char original = matrix[r][c];\n        \n        // Try a random character\n        char new_char = ALPHABET[gen() % ALPHABET.length()];\n        matrix[r][c] = new_char;\n        \n        int new_matches = countMatches();\n        if (new_matches < current_matches) {\n            matrix[r][c] = original; // Revert\n        } else {\n            current_matches = new_matches;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    strings.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> strings[i].s;\n        strings[i].id = i;\n    }\n    \n    // Initialize matrix\n    for (int i = 0; i < N; i++) {\n        matrix[i] = string(N, '.');\n    }\n    \n    // Greedy placement\n    greedyPlacement();\n    \n    // Try to improve\n    fillEmptySpots();\n    \n    // Final improvement\n    randomImprovement();\n    \n    // Output result\n    for (const string& row : matrix) {\n        cout << row << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 70;\nint N, si, sj;\nchar grid[MAX_N][MAX_N];\nbool is_road[MAX_N][MAX_N];\nint cost[MAX_N][MAX_N];\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Calculate visible squares from a given position\nset<pair<int,int>> get_visible_squares(int x, int y) {\n    set<pair<int,int>> visible;\n    \n    // Horizontal visibility (same row)\n    // Left direction\n    for (int j = y; j >= 0; j--) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    // Right direction\n    for (int j = y; j < N; j++) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    \n    // Vertical visibility (same column)\n    // Up direction\n    for (int i = x; i >= 0; i--) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    // Down direction\n    for (int i = x; i < N; i++) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    \n    return visible;\n}\n\n// Count total road squares\nint count_roads() {\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) cnt++;\n        }\n    }\n    return cnt;\n}\n\n// Check if position is valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && is_road[x][y];\n}\n\n// Calculate coverage of a path\nset<pair<int,int>> calculate_coverage(const vector<Point>& path) {\n    set<pair<int,int>> covered;\n    for (const auto& p : path) {\n        auto visible = get_visible_squares(p.x, p.y);\n        covered.insert(visible.begin(), visible.end());\n    }\n    return covered;\n}\n\n// Calculate path cost\nint calculate_cost(const vector<char>& path) {\n    int total_cost = 0;\n    int x = si, y = sj;\n    \n    for (char c : path) {\n        int dir = -1;\n        for (int i = 0; i < 4; i++) {\n            if (dir_char[i] == c) {\n                dir = i;\n                break;\n            }\n        }\n        \n        if (dir == -1) continue;\n        \n        int nx = x + dx[dir];\n        int ny = y + dy[dir];\n        \n        if (!is_valid(nx, ny)) return 1e9; // Invalid move\n        \n        total_cost += cost[nx][ny];\n        x = nx;\n        y = ny;\n    }\n    \n    // Must return to start\n    if (x != si || y != sj) return 1e9;\n    \n    return total_cost;\n}\n\n// Generate spiral path as initial solution\nvector<char> generate_spiral_path() {\n    vector<char> path;\n    int x = si, y = sj;\n    \n    // Simple strategy: try to cover the area systematically\n    // This is a placeholder - we'll improve it\n    \n    // Try to go in a pattern that covers area\n    int steps = min(N * N, 2000); // Limit path length\n    int dir = 0; // Start going right\n    \n    for (int i = 0; i < steps; i++) {\n        // Try current direction\n        int nx = x + dx[dir];\n        int ny = y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            path.push_back(dir_char[dir]);\n            x = nx;\n            y = ny;\n        } else {\n            // Try other directions\n            bool found = false;\n            for (int d = 0; d < 4; d++) {\n                nx = x + dx[d];\n                ny = y + dy[d];\n                if (is_valid(nx, ny)) {\n                    path.push_back(dir_char[d]);\n                    x = nx;\n                    y = ny;\n                    dir = d;\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) break;\n        }\n        \n        // Occasionally change direction to explore\n        if (i % 20 == 0) {\n            dir = (dir + 1) % 4;\n        }\n    }\n    \n    // Return to start\n    // Simple approach: just add moves back (this is suboptimal)\n    while (path.size() < 3000 && (x != si || y != sj)) {\n        // Greedy move towards start\n        int best_dir = -1;\n        int min_dist = abs(x - si) + abs(y - sj);\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (is_valid(nx, ny)) {\n                int dist = abs(nx - si) + abs(ny - sj);\n                if (dist < min_dist) {\n                    min_dist = dist;\n                    best_dir = d;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            path.push_back(dir_char[best_dir]);\n            x += dx[best_dir];\n            y += dy[best_dir];\n        } else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Improve path using local search\nvector<char> improve_path(vector<char> path) {\n    // Remove invalid parts\n    int x = si, y = sj;\n    vector<char> valid_path;\n    \n    for (char c : path) {\n        int dir = -1;\n        for (int i = 0; i < 4; i++) {\n            if (dir_char[i] == c) {\n                dir = i;\n                break;\n            }\n        }\n        \n        if (dir == -1) continue;\n        \n        int nx = x + dx[dir];\n        int ny = y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            valid_path.push_back(c);\n            x = nx;\n            y = ny;\n        }\n    }\n    \n    // If we're not at start, try to return\n    if (x != si || y != sj) {\n        // Simple greedy return\n        int attempts = 100;\n        while (attempts-- > 0 && valid_path.size() < 3000 && (x != si || y != sj)) {\n            int best_dir = -1;\n            int min_dist = abs(x - si) + abs(y - sj);\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                if (is_valid(nx, ny)) {\n                    int dist = abs(nx - si) + abs(ny - sj);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_dir = d;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                valid_path.push_back(dir_char[best_dir]);\n                x += dx[best_dir];\n                y += dy[best_dir];\n            } else {\n                break;\n            }\n        }\n    }\n    \n    return valid_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j];\n            if (line[j] == '#') {\n                is_road[i][j] = false;\n            } else {\n                is_road[i][j] = true;\n                cost[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    // Generate initial path\n    vector<char> path = generate_spiral_path();\n    \n    // Improve the path\n    path = improve_path(path);\n    \n    // Further improvement attempts\n    for (int iter = 0; iter < 5 && path.size() > 2; iter++) {\n        // Try removing some segments if they don't affect coverage much\n        if (path.size() > 100) {\n            // Remove every 50th move as experiment\n            vector<char> new_path;\n            for (int i = 0; i < (int)path.size(); i++) {\n                if (i % 50 != 0 || i < 10) {\n                    new_path.push_back(path[i]);\n                }\n            }\n            auto improved = improve_path(new_path);\n            if (improved.size() <= path.size()) {\n                path = improved;\n            }\n        }\n    }\n    \n    // Ensure path is not too long\n    if (path.size() > 2999) {\n        path.resize(2999);\n        // Make sure we return to start\n        path = improve_path(path);\n    }\n    \n    // Output result\n    for (char c : path) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int MAX_N = 1000;\nconst int MAX_M = 20;\nconst int MAX_K = 20;\nconst int MAX_DAYS = 2000;\n\n// Global variables\nint N, M, K, R;\nvector<vector<int>> task_skills;  // [task][skill] = required level\nvector<vector<int>> member_skills; // [member][skill] = estimated level\nvector<vector<int>> task_times;    // [task][member] = observed time\nvector<vector<int>> dependencies;  // [task] = list of prerequisite tasks\nvector<vector<int>> reverse_dependencies; // [task] = list of dependent tasks\nvector<int> task_status;           // -1:not started, 0:in progress, 1:completed\nvector<int> member_status;         // -1:free, task_id:working on task\nvector<int> task_completion_day;   // when each task was completed\nvector<set<int>> completed_tasks_by_member; // track what each member completed\n\n// For skill estimation\nvector<int> task_start_day;\nvector<vector<pair<int,int>>> member_task_history; // {task_id, completion_time}\n\n// Topological sorting helper\nvector<int> in_degree;\nqueue<int> ready_tasks;\n\nvoid read_input() {\n    cin >> N >> M >> K >> R;\n    \n    task_skills.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_skills[i][j];\n        }\n    }\n    \n    dependencies.resize(N);\n    reverse_dependencies.resize(N);\n    in_degree.assign(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--; // Convert to 0-indexed\n        dependencies[v].push_back(u);\n        reverse_dependencies[u].push_back(v);\n        in_degree[v]++;\n    }\n}\n\n// Initialize data structures\nvoid initialize() {\n    task_status.assign(N, -1);\n    member_status.assign(M, -1);\n    task_completion_day.assign(N, -1);\n    task_start_day.assign(N, -1);\n    completed_tasks_by_member.resize(M);\n    member_task_history.resize(M);\n    \n    // Initialize skill estimates with reasonable defaults\n    member_skills.resize(M, vector<int>(K, 10)); // Start with moderate skills\n    task_times.resize(N, vector<int>(M, 1));     // Default time estimate\n    \n    // Find initially ready tasks (no dependencies)\n    for (int i = 0; i < N; i++) {\n        if (in_degree[i] == 0) {\n            ready_tasks.push(i);\n        }\n    }\n}\n\n// Estimate member skills based on history\nvoid update_skill_estimates() {\n    // Simple approach: for each member, look at tasks they completed quickly\n    for (int member = 0; member < M; member++) {\n        if (member_task_history[member].size() == 0) continue;\n        \n        // Look at recent successful completions (time = 1 day usually means skill >= difficulty)\n        map<int, vector<int>> skill_samples; // skill_index -> list of observed levels\n        \n        for (auto& [task_id, completion_time] : member_task_history[member]) {\n            if (completion_time <= 2) { // Completed quickly\n                for (int k = 0; k < K; k++) {\n                    // If completed quickly, member's skill is likely >= task requirement\n                    skill_samples[k].push_back(task_skills[task_id][k]);\n                }\n            }\n        }\n        \n        // Update skill estimates\n        for (int k = 0; k < K; k++) {\n            if (!skill_samples[k].empty()) {\n                // Take maximum observed requirement they handled well\n                sort(skill_samples[k].begin(), skill_samples[k].end());\n                member_skills[member][k] = max(member_skills[member][k], \n                                             skill_samples[k].back());\n            }\n        }\n    }\n}\n\n// Calculate estimated time for a member to complete a task\nint estimate_time(int task_id, int member_id) {\n    int w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0, task_skills[task_id][k] - member_skills[member_id][k]);\n    }\n    \n    if (w == 0) return 1;\n    else return max(1, w); // Simplified - ignoring randomness for planning\n}\n\n// Get best available member for a task\nint get_best_member(int task_id) {\n    int best_member = 0;\n    int min_time = estimate_time(task_id, 0);\n    \n    for (int member = 1; member < M; member++) {\n        int time = estimate_time(task_id, member);\n        if (time < min_time) {\n            min_time = time;\n            best_member = member;\n        }\n    }\n    \n    return best_member;\n}\n\n// Update ready tasks based on completed tasks\nvoid update_ready_tasks(int completed_task) {\n    for (int dependent : reverse_dependencies[completed_task]) {\n        in_degree[dependent]--;\n        if (in_degree[dependent] == 0) {\n            ready_tasks.push(dependent);\n        }\n    }\n}\n\n// Main assignment logic\nvector<pair<int, int>> assign_tasks(int current_day) {\n    vector<pair<int, int>> assignments;\n    \n    // Find free members\n    vector<int> free_members;\n    for (int member = 0; member < M; member++) {\n        if (member_status[member] == -1) {\n            free_members.push_back(member);\n        }\n    }\n    \n    if (free_members.empty() || ready_tasks.empty()) {\n        return assignments;\n    }\n    \n    // Create list of ready tasks with priorities\n    vector<pair<int, int>> task_priority; // {priority, task_id}\n    queue<int> temp_queue = ready_tasks; // Copy to avoid modifying original\n    \n    while (!temp_queue.empty()) {\n        int task_id = temp_queue.front();\n        temp_queue.pop();\n        \n        // Priority: tasks with more dependents first, then lower ID\n        int priority = -reverse_dependencies[task_id].size() * 1000 - task_id;\n        task_priority.push_back({priority, task_id});\n    }\n    \n    sort(task_priority.begin(), task_priority.end());\n    \n    // Assign tasks to free members\n    int task_count = min((int)free_members.size(), (int)task_priority.size());\n    \n    for (int i = 0; i < task_count; i++) {\n        int member_id = free_members[i];\n        int task_id = task_priority[i].second;\n        \n        // Remove this task from ready queue (we'll re-add if not assigned)\n        // Actually, let's handle this more carefully in the main loop\n        \n        assignments.push_back({member_id, task_id});\n        task_status[task_id] = 0; // Mark as in progress\n        member_status[member_id] = task_id;\n        task_start_day[task_id] = current_day;\n    }\n    \n    return assignments;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    read_input();\n    initialize();\n    \n    int day = 0;\n    \n    while (day < MAX_DAYS) {\n        day++;\n        \n        // Process completed tasks from previous day\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) {\n            break; // Done\n        }\n        \n        vector<int> completed_members(n_completed);\n        for (int i = 0; i < n_completed; i++) {\n            cin >> completed_members[i];\n            completed_members[i]--; // Convert to 0-indexed\n        }\n        \n        // Update based on completed tasks\n        for (int member_idx : completed_members) {\n            int task_id = member_status[member_idx];\n            if (task_id != -1) {\n                task_status[task_id] = 1;\n                task_completion_day[task_id] = day;\n                member_status[member_idx] = -1;\n                completed_tasks_by_member[member_idx].insert(task_id);\n                \n                // Record completion for skill estimation\n                int duration = day - task_start_day[task_id];\n                member_task_history[member_idx].push_back({task_id, duration});\n                \n                // Update ready tasks\n                update_ready_tasks(task_id);\n            }\n        }\n        \n        // Update skill estimates periodically\n        if (day % 10 == 0) {\n            update_skill_estimates();\n        }\n        \n        // Make new assignments\n        vector<pair<int, int>> assignments = assign_tasks(day);\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& [member, task] : assignments) {\n            cout << \" \" << (member + 1) << \" \" << (task + 1);\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst int NUM_ORDERS = 1000;\nconst int SELECT_COUNT = 50;\n\nstruct Order {\n    int id, a, b, c, d;\n    int pickup_dist_from_depot;\n    int delivery_dist_from_depot;\n    int direct_distance;\n};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan_distance(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nint manhattan_distance(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Calculate total distance of a route\nlong long calculate_route_distance(const vector<Point>& route) {\n    long long total = 0;\n    for (size_t i = 0; i + 1 < route.size(); i++) {\n        total += manhattan_distance(route[i], route[i + 1]);\n    }\n    return total;\n}\n\n// Greedy insertion to build route\nvector<Point> build_route(const vector<Order>& selected_orders) {\n    vector<pair<Point, int>> points; // point and order_id (negative for pickup, positive for delivery)\n    \n    for (const auto& order : selected_orders) {\n        points.emplace_back(Point(order.a, order.b), -order.id); // pickup (negative id)\n        points.emplace_back(Point(order.c, order.d), order.id);  // delivery (positive id)\n    }\n    \n    // Start with depot\n    vector<Point> route = {Point(DEPOT_X, DEPOT_Y)};\n    vector<bool> picked_up(selected_orders.size(), false);\n    vector<bool> delivered(selected_orders.size(), false);\n    vector<int> order_position(selected_orders.size() + 1, -1); // position in route for each order pickup\n    \n    // Simple greedy insertion\n    while (points.size() > 0) {\n        long long best_cost = 1e18;\n        size_t best_pos = 0;\n        size_t best_point_idx = 0;\n        bool valid_insertion = false;\n        \n        // Try inserting each remaining point at each possible position\n        for (size_t i = 0; i < points.size(); i++) {\n            auto& point = points[i];\n            int order_id = abs(point.second);\n            bool is_pickup = point.second < 0;\n            \n            // Check if insertion is valid\n            if (!is_pickup && !picked_up[order_id - 1]) continue; // Can't deliver before pickup\n            \n            for (size_t pos = 1; pos <= route.size(); pos++) {\n                route.insert(route.begin() + pos, point.first);\n                long long new_cost = calculate_route_distance(route);\n                route.erase(route.begin() + pos);\n                \n                if (new_cost < best_cost) {\n                    best_cost = new_cost;\n                    best_pos = pos;\n                    best_point_idx = i;\n                    valid_insertion = true;\n                }\n            }\n        }\n        \n        if (!valid_insertion) {\n            // Fallback: just append remaining points in some order\n            for (auto& point : points) {\n                route.push_back(point.first);\n            }\n            break;\n        }\n        \n        // Apply best insertion\n        auto point = points[best_point_idx];\n        int order_id = abs(point.second);\n        bool is_pickup = point.second < 0;\n        \n        route.insert(route.begin() + best_pos, point.first);\n        points.erase(points.begin() + best_point_idx);\n        \n        if (is_pickup) {\n            picked_up[order_id - 1] = true;\n            order_position[order_id] = best_pos;\n        } else {\n            delivered[order_id - 1] = true;\n        }\n    }\n    \n    // Return to depot\n    route.push_back(Point(DEPOT_X, DEPOT_Y));\n    \n    return route;\n}\n\n// Improved route construction using better heuristic\nvector<Point> build_better_route(const vector<Order>& selected_orders) {\n    vector<pair<Point, int>> points; // point and order_id\n    \n    for (const auto& order : selected_orders) {\n        points.emplace_back(Point(order.a, order.b), -order.id); // pickup\n        points.emplace_back(Point(order.c, order.d), order.id);  // delivery\n    }\n    \n    vector<Point> route = {Point(DEPOT_X, DEPOT_Y)};\n    vector<bool> served(selected_orders.size(), false);\n    \n    // Use nearest neighbor with constraint that pickup comes before delivery\n    vector<bool> picked_up(selected_orders.size(), false);\n    \n    while (points.size() > 0) {\n        int best_idx = -1;\n        long long best_dist = 1e18;\n        Point current = route.back();\n        \n        for (size_t i = 0; i < points.size(); i++) {\n            auto& point = points[i];\n            int order_id = abs(point.second) - 1;\n            bool is_pickup = point.second < 0;\n            \n            // Constraint: can only pick up if not picked up yet\n            // Constraint: can only deliver if picked up\n            if (is_pickup) {\n                if (!picked_up[order_id]) {\n                    long long dist = manhattan_distance(current, point.first);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            } else {\n                if (picked_up[order_id] && !served[order_id]) {\n                    long long dist = manhattan_distance(current, point.first);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_idx == -1) break;\n        \n        auto selected_point = points[best_idx];\n        int order_id = abs(selected_point.second) - 1;\n        bool is_pickup = selected_point.second < 0;\n        \n        route.push_back(selected_point.first);\n        points.erase(points.begin() + best_idx);\n        \n        if (is_pickup) {\n            picked_up[order_id] = true;\n        } else {\n            served[order_id] = true;\n        }\n    }\n    \n    route.push_back(Point(DEPOT_X, DEPOT_Y));\n    return route;\n}\n\n// Score-based selection of orders\nvector<Order> select_orders(vector<Order>& orders) {\n    // Calculate efficiency score for each order\n    for (auto& order : orders) {\n        order.pickup_dist_from_depot = manhattan_distance(DEPOT_X, DEPOT_Y, order.a, order.b);\n        order.delivery_dist_from_depot = manhattan_distance(DEPOT_X, DEPOT_Y, order.c, order.d);\n        order.direct_distance = manhattan_distance(order.a, order.b, order.c, order.d);\n    }\n    \n    // Sort by efficiency (lower is better)\n    // Efficiency = direct distance + min(pickup_to_depot, delivery_to_depot)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        int eff_a = a.direct_distance + min(a.pickup_dist_from_depot, a.delivery_dist_from_depot);\n        int eff_b = b.direct_distance + min(b.pickup_dist_from_depot, b.delivery_dist_from_depot);\n        return eff_a < eff_b;\n    });\n    \n    // Take first 50 orders\n    vector<Order> selected(orders.begin(), orders.begin() + SELECT_COUNT);\n    return selected;\n}\n\nint main() {\n    vector<Order> orders(NUM_ORDERS);\n    \n    // Read input\n    for (int i = 0; i < NUM_ORDERS; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i + 1;\n    }\n    \n    // Select orders\n    vector<Order> selected_orders = select_orders(orders);\n    \n    // Build route\n    vector<Point> route = build_better_route(selected_orders);\n    \n    // Output selected orders\n    cout << SELECT_COUNT;\n    for (const auto& order : selected_orders) {\n        cout << \" \" << order.id;\n    }\n    cout << endl;\n    \n    // Output route\n    cout << route.size();\n    for (const auto& point : route) {\n        cout << \" \" << point.x << \" \" << point.y;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u, v;\n    int d; // euclidean distance (rounded)\n    int l; // actual length (revealed online)\n    double ratio; // l/d ratio\n};\n\nvector<pair<int, int>> coords(N);\nvector<Edge> edges(M);\nvector<int> parent(N);\nint component_count = N;\n\nvoid init_union_find() {\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n}\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nbool unite(int x, int y) {\n    x = find(x);\n    y = find(y);\n    if (x == y) return false;\n    parent[x] = y;\n    component_count--;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read coordinates\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        \n        // Calculate euclidean distance\n        long long dx = coords[edges[i].u].first - coords[edges[i].v].first;\n        long long dy = coords[edges[i].u].second - coords[edges[i].v].second;\n        edges[i].d = (int)round(sqrt(dx * dx + dy * dy));\n    }\n    \n    init_union_find();\n    \n    // Process each edge as it comes\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        edges[i].l = l;\n        edges[i].ratio = (double)l / edges[i].d;\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        // Check if this edge connects two different components\n        bool would_connect = (find(u) != find(v));\n        \n        bool accept = false;\n        \n        // Always accept edges that connect different components until we have a spanning tree\n        if (would_connect && component_count > 1) {\n            accept = true;\n        }\n        // For remaining edges, be selective based on cost efficiency\n        else if (component_count == 1) {\n            // Even after connectivity, accept very cheap edges that could improve the tree\n            // Only accept if significantly better than average\n            if (edges[i].ratio <= 1.3) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            unite(u, v);\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nconst int INF = 100000000;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Point pos;\n    int type;\n    Pet() : pos(0, 0), type(0) {}\n    Pet(Point p, int t) : pos(p), type(t) {}\n};\n\nstruct Human {\n    Point pos;\n    Human() : pos(0, 0) {}\n    Human(Point p) : pos(p) {}\n};\n\n// Directions: up, down, left, right\nconst vector<Point> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"UDLR\";\nconst string BLOCK_CHARS = \"udlr\";\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nvector<vector<int>> grid; // 0 = passable, 1 = blocked\nvector<vector<int>> pet_count; // count of pets in each cell\n\n// Check if position is valid\nbool valid(int x, int y) {\n    return x >= 1 && x <= H && y >= 1 && y <= W;\n}\n\nbool valid_point(Point p) {\n    return valid(p.x, p.y);\n}\n\n// Get adjacent points\nvector<Point> get_adjacent(Point p) {\n    vector<Point> adj;\n    for (auto& d : DIRS) {\n        Point np = {p.x + d.x, p.y + d.y};\n        if (valid_point(np)) {\n            adj.push_back(np);\n        }\n    }\n    return adj;\n}\n\n// BFS to calculate reachable area size from a point\nint calculate_area_size(Point start) {\n    if (!valid_point(start) || grid[start.x][start.y] == 1) return 0;\n    \n    vector<vector<bool>> visited(H + 1, vector<bool>(W + 1, false));\n    queue<Point> q;\n    q.push(start);\n    visited[start.x][start.y] = true;\n    int size = 0;\n    \n    while (!q.empty()) {\n        Point cur = q.front(); q.pop();\n        size++;\n        \n        for (auto& d : DIRS) {\n            Point next = {cur.x + d.x, cur.y + d.y};\n            if (valid_point(next) && !visited[next.x][next.y] && grid[next.x][next.y] == 0) {\n                visited[next.x][next.y] = true;\n                q.push(next);\n            }\n        }\n    }\n    \n    return size;\n}\n\n// Count pets in reachable area from a point\nint count_pets_in_area(Point start) {\n    if (!valid_point(start) || grid[start.x][start.y] == 1) return 0;\n    \n    vector<vector<bool>> visited(H + 1, vector<bool>(W + 1, false));\n    queue<Point> q;\n    q.push(start);\n    visited[start.x][start.y] = true;\n    int pet_count_area = 0;\n    \n    while (!q.empty()) {\n        Point cur = q.front(); q.pop();\n        pet_count_area += pet_count[cur.x][cur.y];\n        \n        for (auto& d : DIRS) {\n            Point next = {cur.x + d.x, cur.y + d.y};\n            if (valid_point(next) && !visited[next.x][next.y] && grid[next.x][next.y] == 0) {\n                visited[next.x][next.y] = true;\n                q.push(next);\n            }\n        }\n    }\n    \n    return pet_count_area;\n}\n\n// Simple heuristic: if we can block a square that limits pet movement, do it\nstring decide_actions(int turn) {\n    string actions(M, '.');\n    \n    // Update pet count grid\n    pet_count.assign(H + 1, vector<int>(W + 1, 0));\n    for (const auto& pet : pets) {\n        if (valid_point(pet.pos)) {\n            pet_count[pet.pos.x][pet.pos.y]++;\n        }\n    }\n    \n    // Early turns: just observe and move away from pets\n    if (turn < 50) {\n        for (int i = 0; i < M; i++) {\n            // Move away from nearby pets if possible\n            Point cur = humans[i].pos;\n            bool moved = false;\n            \n            // Check if any pet is adjacent\n            for (auto& pet : pets) {\n                if (abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y) <= 2) {\n                    // Try to move away\n                    for (int d = 0; d < 4; d++) {\n                        Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                        if (valid_point(next) && grid[next.x][next.y] == 0) {\n                            // Check if this move takes us away from pets\n                            int dist_to_pet = abs(pet.pos.x - next.x) + abs(pet.pos.y - next.y);\n                            int cur_dist = abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y);\n                            if (dist_to_pet > cur_dist) {\n                                actions[i] = DIR_CHARS[d];\n                                moved = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (moved) break;\n                }\n            }\n            \n            // If we didn't move, try to block strategically\n            if (!moved && turn > 20) {\n                for (int d = 0; d < 4; d++) {\n                    Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                        // Don't block if pet is adjacent to the square we want to block\n                        bool pet_adjacent = false;\n                        for (auto& pet : pets) {\n                            if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                                pet_adjacent = true;\n                                break;\n                            }\n                        }\n                        if (!pet_adjacent) {\n                            actions[i] = BLOCK_CHARS[d];\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    // Mid game: start creating barriers\n    else if (turn < 200) {\n        for (int i = 0; i < M; i++) {\n            Point cur = humans[i].pos;\n            \n            // Try to block to create isolated areas\n            // Prefer blocking squares that separate areas with fewer pets\n            vector<pair<int, int>> candidates; // {score, direction}\n            \n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                    // Don't block if pet is adjacent\n                    bool pet_adjacent = false;\n                    for (auto& pet : pets) {\n                        if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                            pet_adjacent = true;\n                            break;\n                        }\n                    }\n                    if (!pet_adjacent) {\n                        // Score based on potential to create good areas\n                        grid[block_pos.x][block_pos.y] = 1;\n                        int area_size = calculate_area_size(cur);\n                        int pet_count_area = count_pets_in_area(cur);\n                        grid[block_pos.x][block_pos.y] = 0;\n                        \n                        double score = (double)area_size / (1 + pet_count_area);\n                        candidates.push_back({(int)(score * 1000), d});\n                    }\n                }\n            }\n            \n            if (!candidates.empty()) {\n                sort(candidates.rbegin(), candidates.rend());\n                actions[i] = BLOCK_CHARS[candidates[0].second];\n            } else {\n                // If no good blocking, try to move to better position\n                int best_score = -1;\n                int best_dir = -1;\n                \n                for (int d = 0; d < 4; d++) {\n                    Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                    if (valid_point(next) && grid[next.x][next.y] == 0) {\n                        int area_size = calculate_area_size(next);\n                        int pet_count_area = count_pets_in_area(next);\n                        int score = area_size - pet_count_area * 10;\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_dir = d;\n                        }\n                    }\n                }\n                \n                if (best_dir != -1) {\n                    actions[i] = DIR_CHARS[best_dir];\n                }\n            }\n        }\n    }\n    // Late game: optimize final positions\n    else {\n        for (int i = 0; i < M; i++) {\n            Point cur = humans[i].pos;\n            \n            // Calculate current situation\n            int current_area = calculate_area_size(cur);\n            int current_pets = count_pets_in_area(cur);\n            double current_score = (double)current_area / 900.0 * pow(2.0, -current_pets);\n            \n            // Try all possible actions and pick the best\n            double best_score = current_score;\n            char best_action = '.';\n            \n            // Try blocking\n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                    // Don't block if pet is adjacent\n                    bool pet_adjacent = false;\n                    for (auto& pet : pets) {\n                        if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                            pet_adjacent = true;\n                            break;\n                        }\n                    }\n                    if (!pet_adjacent) {\n                        grid[block_pos.x][block_pos.y] = 1;\n                        int new_area = calculate_area_size(cur);\n                        int new_pets = count_pets_in_area(cur);\n                        double new_score = (double)new_area / 900.0 * pow(2.0, -new_pets);\n                        grid[block_pos.x][block_pos.y] = 0;\n                        \n                        if (new_score > best_score) {\n                            best_score = new_score;\n                            best_action = BLOCK_CHARS[d];\n                        }\n                    }\n                }\n            }\n            \n            // Try moving\n            for (int d = 0; d < 4; d++) {\n                Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(next) && grid[next.x][next.y] == 0) {\n                    int new_area = calculate_area_size(next);\n                    int new_pets = count_pets_in_area(next);\n                    double new_score = (double)new_area / 900.0 * pow(2.0, -new_pets);\n                    \n                    if (new_score > best_score) {\n                        best_score = new_score;\n                        best_action = DIR_CHARS[d];\n                    }\n                }\n            }\n            \n            actions[i] = best_action;\n        }\n    }\n    \n    return actions;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Initialize grid\n    grid.assign(H + 1, vector<int>(W + 1, 0));\n    \n    // Read initial positions\n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t;\n        cin >> x >> y >> t;\n        pets[i] = Pet(Point(x, y), t);\n    }\n    \n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        humans[i] = Human(Point(x, y));\n    }\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // Decide actions\n        string actions = decide_actions(turn);\n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        string pet_moves;\n        getline(cin, pet_moves);\n        if (pet_moves.empty()) {\n            getline(cin, pet_moves);\n        }\n        \n        stringstream ss(pet_moves);\n        string move;\n        for (int i = 0; i < N && ss >> move; i++) {\n            // Update pet position based on movement\n            for (char c : move) {\n                switch (c) {\n                    case 'U': pets[i].pos.x--; break;\n                    case 'D': pets[i].pos.x++; break;\n                    case 'L': pets[i].pos.y--; break;\n                    case 'R': pets[i].pos.y++; break;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint si, sj, ti, tj;\ndouble p;\nbool h_wall[N][N-1]; // horizontal walls\nbool v_wall[N-1][N]; // vertical walls\n\n// Direction mappings\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nbool can_move(int x, int y, int dir) {\n    if (dir == 0) { // Up\n        if (x == 0) return false;\n        return !v_wall[x-1][y];\n    } else if (dir == 1) { // Down\n        if (x == N-1) return false;\n        return !v_wall[x][y];\n    } else if (dir == 2) { // Left\n        if (y == 0) return false;\n        return !h_wall[x][y-1];\n    } else { // Right\n        if (y == N-1) return false;\n        return !h_wall[x][y];\n    }\n}\n\n// Create a robust path using a strategy that builds in redundancy\nstring create_robust_path() {\n    string path;\n    \n    // Strategy: Create a path with built-in redundancy\n    // We'll use a \"thick path\" approach where we don't just follow\n    // the shortest route, but create a wider corridor\n    \n    int x = si, y = sj;\n    \n    // Since home is in top-left (0-4, 0-4) and office is in bottom-right (15-19, 15-19)\n    // We generally want to go right and down\n    \n    // Main strategy:\n    // 1. Go right in a robust manner\n    // 2. Go down in a robust manner\n    // 3. Fine-tune to exact position\n    \n    // Phase 1: Move toward target column with redundancy\n    while (y < tj && path.length() < 180) {\n        if (can_move(x, y, 3)) { // Right\n            path += 'R';\n            y++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try down then right\n            if (x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n                moved = true;\n            } else if (x > 0 && can_move(x, y, 0)) {\n                path += 'U';\n                x--;\n                moved = true;\n            }\n            \n            if (moved && y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n            } else if (moved) {\n                // Undo the vertical move if we can't go right\n                if (x > si) {\n                    path += 'U';\n                    x--;\n                } else {\n                    path += 'D';\n                    x++;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Move toward target row with redundancy\n    while (x < ti && path.length() < 195) {\n        if (can_move(x, y, 1)) { // Down\n            path += 'D';\n            x++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try right then down\n            if (y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n                moved = true;\n            } else if (y > 0 && can_move(x, y, 2)) {\n                path += 'L';\n                y--;\n                moved = true;\n            }\n            \n            if (moved && x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n            } else if (moved) {\n                // Undo the horizontal move if we can't go down\n                if (y > sj) {\n                    path += 'L';\n                    y--;\n                } else {\n                    path += 'R';\n                    y++;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Fine adjustment\n    while ((x != ti || y != tj) && path.length() < 200) {\n        if (x < ti && can_move(x, y, 1)) {\n            path += 'D';\n            x++;\n        } else if (x > ti && can_move(x, y, 0)) {\n            path += 'U';\n            x--;\n        } else if (y < tj && can_move(x, y, 3)) {\n            path += 'R';\n            y++;\n        } else if (y > tj && can_move(x, y, 2)) {\n            path += 'L';\n            y--;\n        } else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Alternative approach: Create a path with explicit redundancy\nstring create_redundant_path() {\n    string path;\n    int x = si, y = sj;\n    \n    // Create a path where every few steps, we add a small loop\n    // This provides redundancy - if one move is forgotten, \n    // the loop gives us another chance\n    \n    int steps_since_loop = 0;\n    \n    while ((x != ti || y != tj) && path.length() < 200) {\n        // Determine best direction\n        int best_dir = -1;\n        int best_value = -1000;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(x, y, dir)) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                // Heuristic: prefer moves that get us closer to target\n                int value = -(abs(nx - ti) + abs(ny - tj));\n                \n                // Slight preference for right/down moves to maintain progress\n                if (dir == 1 || dir == 3) value += 1;\n                \n                if (value > best_value) {\n                    best_value = value;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            path += dir_char[best_dir];\n            x += dx[best_dir];\n            y += dy[best_dir];\n            steps_since_loop++;\n            \n            // Every few steps, add a small redundant loop if space allows\n            if (steps_since_loop >= 4 && path.length() < 190) {\n                // Try to add a small 2-step loop\n                int perpendicular_dir1 = (best_dir + 1) % 4;\n                int perpendicular_dir2 = (best_dir + 3) % 4;\n                \n                if (can_move(x, y, perpendicular_dir1) && \n                    can_move(x + dx[perpendicular_dir1], y + dy[perpendicular_dir1], \n                             (perpendicular_dir1 + 2) % 4) &&\n                    path.length() < 198) {\n                    path += dir_char[perpendicular_dir1];\n                    path += dir_char[(perpendicular_dir1 + 2) % 4];\n                    steps_since_loop = 0;\n                } else if (can_move(x, y, perpendicular_dir2) && \n                           can_move(x + dx[perpendicular_dir2], y + dy[perpendicular_dir2], \n                                    (perpendicular_dir2 + 2) % 4) &&\n                           path.length() < 198) {\n                    path += dir_char[perpendicular_dir2];\n                    path += dir_char[(perpendicular_dir2 + 2) % 4];\n                    steps_since_loop = 0;\n                }\n            }\n        } else {\n            break; // No valid moves\n        }\n    }\n    \n    return path;\n}\n\nint main() {\n    // Read input\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N-1; j++) {\n            h_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N-1; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            v_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Generate path - try the redundant approach\n    string result = create_redundant_path();\n    \n    // Fallback to simpler approach if needed\n    if (result.empty() || result.length() > 200) {\n        result = create_robust_path();\n    }\n    \n    // Ensure we don't exceed 200 characters\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction: 0=left, 1=up, 2=right, 3=down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Transition table: to[tile_type][entry_direction] = exit_direction (-1 if invalid)\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // tile 0\n    {3, -1, -1, 0},  // tile 1\n    {-1, -1, 3, 2},  // tile 2\n    {-1, 2, 1, -1},  // tile 3\n    {1, 0, 3, 2},    // tile 4\n    {3, 2, 1, 0},    // tile 5\n    {2, -1, 0, -1},  // tile 6\n    {-1, 3, -1, 1}   // tile 7\n};\n\nconst int N = 30;\nint grid[N][N];\nint rotation[N][N];\n\n// Get actual tile type after rotation\nint get_rotated_tile(int base_tile, int rot) {\n    static const int rotation_map[8][4] = {\n        {0, 1, 2, 3},  // tile 0\n        {1, 2, 3, 0},  // tile 1\n        {2, 3, 0, 1},  // tile 2\n        {3, 0, 1, 2},  // tile 3\n        {4, 5, 4, 5},  // tile 4\n        {5, 4, 5, 4},  // tile 5\n        {6, 7, 6, 7},  // tile 6\n        {7, 6, 7, 6}   // tile 7\n    };\n    return rotation_map[base_tile][rot % 4];\n}\n\n// Check if coordinates are valid\nbool valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\n// Find loop length starting from position (si,sj) entering from direction sd\nint find_loop_length(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        int tile_type = get_rotated_tile(grid[i][j], rotation[i][j]);\n        int d2 = to[tile_type][d];\n        \n        if (d2 == -1) return 0;  // Broken line\n        \n        i += di[d2];\n        j += dj[d2];\n        \n        if (!valid(i, j)) return 0;  // Out of bounds\n        \n        d = (d2 + 2) % 4;  // Reverse direction\n        length++;\n        \n        if (length > 10000) return 0;  // Prevent infinite loops\n        \n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\n// Find all loops and return their lengths\nvector<int> find_all_loops() {\n    vector<int> loops;\n    bool visited[N][N][4] = {};\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int tile_type = get_rotated_tile(grid[i][j], rotation[i][j]);\n                    if (to[tile_type][d] != -1) {\n                        int length = find_loop_length(i, j, d);\n                        if (length > 0) {\n                            loops.push_back(length);\n                            \n                            // Mark all positions in this loop as visited\n                            int ci = i, cj = j, cd = d;\n                            do {\n                                visited[ci][cj][cd] = true;\n                                int tile_type2 = get_rotated_tile(grid[ci][cj], rotation[ci][cj]);\n                                int d2 = to[tile_type2][cd];\n                                ci += di[d2];\n                                cj += dj[d2];\n                                cd = (d2 + 2) % 4;\n                            } while (!(ci == i && cj == j && cd == d));\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    sort(loops.rbegin(), loops.rend());\n    return loops;\n}\n\n// Calculate score\nlong long calculate_score() {\n    vector<int> loops = find_all_loops();\n    if (loops.size() < 2) return 0;\n    return 1LL * loops[0] * loops[1];\n}\n\n// Initialize with random rotations\nvoid initialize_random() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> dis(0, 3);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            rotation[i][j] = dis(gen);\n        }\n    }\n}\n\n// Greedy local search improvement\nvoid local_search() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    \n    long long current_score = calculate_score();\n    \n    for (int iter = 0; iter < 50000; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        int new_rotation = (old_rotation + 1 + (gen() % 3)) % 4;\n        \n        rotation[i][j] = new_rotation;\n        long long new_score = calculate_score();\n        \n        if (new_score >= current_score) {\n            current_score = new_score;\n        } else {\n            rotation[i][j] = old_rotation;  // Revert\n        }\n    }\n}\n\n// Simulated annealing approach\nvoid simulated_annealing() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    uniform_real_distribution<> prob_dis(0.0, 1.0);\n    \n    long long current_score = calculate_score();\n    double temperature = 10000.0;\n    double cooling_rate = 0.9995;\n    \n    for (int iter = 0; iter < 100000 && temperature > 0.1; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        int new_rotation = (old_rotation + 1 + (gen() % 3)) % 4;\n        \n        rotation[i][j] = new_rotation;\n        long long new_score = calculate_score();\n        \n        double delta = new_score - current_score;\n        \n        if (delta > 0 || prob_dis(gen) < exp(delta / temperature)) {\n            current_score = new_score;\n        } else {\n            rotation[i][j] = old_rotation;  // Revert\n        }\n        \n        temperature *= cooling_rate;\n    }\n}\n\nint main() {\n    // Read input\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Initialize with some strategy\n    initialize_random();\n    \n    // Improve using local search\n    local_search();\n    \n    // Further improve with simulated annealing\n    simulated_annealing();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 10;\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst char inv_dir_chars[4] = {'D', 'U', 'R', 'L'};\n\nint N, T;\nint board[MAX_N][MAX_N];\nint empty_x, empty_y;\n\n// Check if two adjacent tiles are connected\nbool isConnected(int x1, int y1, int x2, int y2) {\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (board[x1][y1] == 0 || board[x2][y2] == 0) return false;\n    \n    // Check if they connect\n    if (x1 == x2 && y1 == y2 - 1) { // Right connection\n        return (board[x1][y1] & 4) && (board[x2][y2] & 1);\n    }\n    if (x1 == x2 && y1 == y2 + 1) { // Left connection\n        return (board[x1][y1] & 1) && (board[x2][y2] & 4);\n    }\n    if (x1 == x2 - 1 && y1 == y2) { // Down connection\n        return (board[x1][y1] & 8) && (board[x2][y2] & 2);\n    }\n    if (x1 == x2 + 1 && y1 == y2) { // Up connection\n        return (board[x1][y1] & 2) && (board[x2][y2] & 8);\n    }\n    return false;\n}\n\n// Find the size of the largest connected component\nint findLargestTree() {\n    bool visited[MAX_N][MAX_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 = 1;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                \n                // Check 4 neighbors\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dx[k];\n                    int ny = y + dy[k];\n                    \n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && \n                        !visited[nx][ny] && board[nx][ny] != 0 && \n                        isConnected(x, y, nx, ny)) {\n                        visited[nx][ny] = true;\n                        size++;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            max_size = max(max_size, size);\n        }\n    }\n    \n    return max_size;\n}\n\n// Calculate how many new connections would be made by a move\nint calculateGain(int from_x, int from_y) {\n    int gain = 0;\n    \n    // Temporarily move the tile\n    int temp = board[from_x][from_y];\n    board[from_x][from_y] = 0;\n    board[empty_x][empty_y] = temp;\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    \n    // Count connections for the moved tile\n    for (int k = 0; k < 4; k++) {\n        int nx = empty_x + dx[k];\n        int ny = empty_y + dy[k];\n        if (isConnected(empty_x, empty_y, nx, ny)) {\n            gain++;\n        }\n    }\n    \n    // Restore\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    board[empty_x][empty_y] = 0;\n    board[from_x][from_y] = temp;\n    \n    return gain;\n}\n\n// Try to make a move\nbool makeMove(char move, string& result) {\n    int dir = -1;\n    for (int i = 0; i < 4; i++) {\n        if (dir_chars[i] == move) {\n            dir = i;\n            break;\n        }\n    }\n    \n    int new_x = empty_x + dx[dir];\n    int new_y = empty_y + dy[dir];\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) {\n        return false;\n    }\n    \n    // Perform move\n    board[empty_x][empty_y] = board[new_x][new_y];\n    board[new_x][new_y] = 0;\n    empty_x = new_x;\n    empty_y = new_y;\n    result += move;\n    \n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    \n    // Read board\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_x = i;\n                empty_y = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int last_dir = -1;\n    \n    // Greedy approach: try to maximize connections\n    for (int step = 0; step < T && (int)result.length() < T; step++) {\n        int best_gain = -1;\n        int best_dir = -1;\n        \n        // Try all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            // Don't go back immediately\n            if (dir == (last_dir ^ 1)) continue;\n            \n            int from_x = empty_x + dx[dir];\n            int from_y = empty_y + dy[dir];\n            \n            if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n            \n            int gain = calculateGain(from_x, from_y);\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_dir = dir;\n            }\n        }\n        \n        // If no good move, pick any valid move\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                if (dir == (last_dir ^ 1)) continue;\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                if (from_x >= 0 && from_x < N && from_y >= 0 && from_y < N) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir == -1) {\n            // Still no move, just pick the first valid one\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                if (from_x >= 0 && from_x < N && from_y >= 0 && from_y < N) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            makeMove(dir_chars[best_dir], result);\n            last_dir = best_dir;\n        } else {\n            break;\n        }\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing P = pair<int, int>;\n\nconst int MAX_N = 10000;\nconst int RADIUS = 10000;\nconst int BOUND = 1000000000;\n\nstruct Strawberry {\n    int x, y, d;\n    int id;\n};\n\nint N, K;\nint a[11]; // a[1] to a[10]\nvector<Strawberry> strawberries;\nvector<tuple<ll, ll, ll, ll>> lines;\n\n// Count strawberries in each piece after all cuts\nvector<int> count_strawberries() {\n    // This is a simplified approach - in practice we'd need to compute actual regions\n    // For now, we'll use a heuristic approach\n    vector<int> counts(N + 1, 0);\n    \n    // Simple heuristic: count how many strawberries are on each side of each line\n    // This is an approximation - a full implementation would require computational geometry\n    if (strawberries.empty()) return counts;\n    \n    // For demonstration, let's just return some dummy values\n    // In a real implementation, this would compute the actual partitioning\n    for (int i = 0; i < min(10, (int)strawberries.size()); i++) {\n        counts[1]++;\n    }\n    \n    return counts;\n}\n\n// Generate a random line\ntuple<ll, ll, ll, ll> generate_random_line() {\n    ll px = rand() % (2 * BOUND) - BOUND;\n    ll py = rand() % (2 * BOUND) - BOUND;\n    ll qx = rand() % (2 * BOUND) - BOUND;\n    ll qy = rand() % (2 * BOUND) - BOUND;\n    \n    // Ensure points are different\n    if (px == qx && py == qy) {\n        qx += 1;\n    }\n    \n    return {px, py, qx, qy};\n}\n\n// Generate line through two points\ntuple<ll, ll, ll, ll> line_through_points(int x1, int y1, int x2, int y2) {\n    if (x1 == x2 && y1 == y2) {\n        x2 += 1;\n    }\n    return {x1, y1, x2, y2};\n}\n\n// Try to separate individual strawberries\nvoid separate_single_strawberries() {\n    int used_lines = 0;\n    \n    // Try to isolate single strawberries first\n    for (int i = 0; i < min(K, (int)strawberries.size()); i++) {\n        if (used_lines >= K) break;\n        \n        // Create lines that try to isolate this strawberry\n        int x = strawberries[i].x;\n        int y = strawberries[i].y;\n        \n        // Create a few lines around this point\n        if (used_lines < K) {\n            lines.push_back(line_through_points(x - 100, y, x + 100, y + 1));\n            used_lines++;\n        }\n        if (used_lines < K) {\n            lines.push_back(line_through_points(x, y - 100, x + 1, y + 100));\n            used_lines++;\n        }\n    }\n}\n\n// Create radial cuts from center\nvoid create_radial_cuts() {\n    int current_lines = lines.size();\n    int remaining = K - current_lines;\n    \n    if (remaining <= 0) return;\n    \n    // Create radial lines from center\n    for (int i = 0; i < min(remaining, 20); i++) {\n        double angle = 2.0 * M_PI * i / min(remaining, 20);\n        ll px = (ll)(100000 * cos(angle));\n        ll py = (ll)(100000 * sin(angle));\n        ll qx = (ll)(-100000 * cos(angle));\n        ll qy = (ll)(-100000 * sin(angle));\n        \n        lines.push_back({px, py, qx, qy});\n    }\n}\n\n// Create grid-like cuts\nvoid create_grid_cuts() {\n    int current_lines = lines.size();\n    int remaining = K - current_lines;\n    \n    if (remaining <= 0) return;\n    \n    // Create horizontal and vertical lines\n    int grid_size = (int)sqrt(remaining / 2) + 1;\n    \n    for (int i = 0; i < min(grid_size, (int)sqrt(remaining/2) + 5); i++) {\n        if (lines.size() >= K) break;\n        int pos = -RADIUS + (2 * RADIUS * i) / max(1, grid_size);\n        lines.push_back(line_through_points(pos, -BOUND, pos, BOUND));\n    }\n    \n    for (int i = 0; i < min(grid_size, (int)sqrt(remaining/2) + 5); i++) {\n        if (lines.size() >= K) break;\n        int pos = -RADIUS + (2 * RADIUS * i) / max(1, grid_size);\n        lines.push_back(line_through_points(-BOUND, pos, BOUND, pos));\n    }\n}\n\n// Random approach\nvoid random_lines() {\n    while (lines.size() < K) {\n        lines.push_back(generate_random_line());\n    }\n}\n\n// Smart line placement based on strawberry positions\nvoid smart_line_placement() {\n    if (strawberries.empty()) {\n        random_lines();\n        return;\n    }\n    \n    // Sort strawberries by x-coordinate\n    sort(strawberries.begin(), strawberries.end(), [](const Strawberry& a, const Strawberry& b) {\n        return a.x < b.x;\n    });\n    \n    // Create vertical lines between strawberries\n    for (int i = 1; i < min(K/2 + 1, (int)strawberries.size()); i++) {\n        if (lines.size() >= K) break;\n        int mid_x = (strawberries[i-1].x + strawberries[i].x) / 2;\n        lines.push_back(line_through_points(mid_x, -BOUND, mid_x, BOUND));\n    }\n    \n    // Sort by y-coordinate\n    sort(strawberries.begin(), strawberries.end(), [](const Strawberry& a, const Strawberry& b) {\n        return a.y < b.y;\n    });\n    \n    // Create horizontal lines between strawberries\n    for (int i = 1; i < min(K - (int)lines.size() + 1, (int)strawberries.size()); i++) {\n        if (lines.size() >= K) break;\n        int mid_y = (strawberries[i-1].y + strawberries[i].y) / 2;\n        lines.push_back(line_through_points(-BOUND, mid_y, BOUND, mid_y));\n    }\n    \n    // Fill remaining with random lines\n    while (lines.size() < K) {\n        lines.push_back(generate_random_line());\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    \n    int total_demand = 0;\n    for (int d = 1; d <= 10; d++) {\n        cin >> a[d];\n        total_demand += a[d];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n        // For simplicity, we're not using the 'd' field as in the problem each strawberry is just a point\n    }\n    \n    // Use smart line placement strategy\n    smart_line_placement();\n    \n    // Ensure we don't exceed K lines\n    if (lines.size() > K) {\n        lines.resize(K);\n    }\n    \n    // Output result\n    cout << lines.size() << \"\\n\";\n    for (const auto& line : lines) {\n        auto [px, py, qx, qy] = line;\n        cout << px << \" \" << py << \" \" << qx << \" \" << qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int MAX_N = 65;\nbool grid[MAX_N][MAX_N];\nint N, M;\nvector<pair<int, int>> initial_dots;\nvector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n// For time management\nauto start_time = high_resolution_clock::now();\nconst double TIME_LIMIT = 4.8;\n\n// Weight calculation\ninline long long weight(int x, int y) {\n    int c = (N - 1) / 2;\n    int dx = x - c;\n    int dy = y - c;\n    return (long long)dx * dx + (long long)dy * dy + 1;\n}\n\n// Check if we should stop due to time limit\nbool time_limit_exceeded() {\n    auto now = high_resolution_clock::now();\n    auto duration = duration_cast<milliseconds>(now - start_time);\n    return duration.count() > TIME_LIMIT * 1000;\n}\n\n// Check if a point is valid (within bounds)\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Check if four points form a valid rectangle (axis-parallel or 45-degree)\nbool is_valid_rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check if it's a parallelogram first\n    if (x1 + x3 != x2 + x4 || y1 + y3 != y2 + y4) return false;\n    \n    // Calculate squared distances to check if it's a rectangle\n    long long d1 = (long long)(x2 - x1) * (x2 - x1) + (long long)(y2 - y1) * (y2 - y1);\n    long long d2 = (long long)(x3 - x2) * (x3 - x2) + (long long)(y3 - y2) * (y3 - y2);\n    long long d3 = (long long)(x4 - x3) * (x4 - x3) + (long long)(y4 - y3) * (y4 - y3);\n    long long d4 = (long long)(x1 - x4) * (x1 - x4) + (long long)(y1 - y4) * (y1 - y4);\n    \n    // All sides equal in pairs and diagonals equal\n    long long diag1 = (long long)(x3 - x1) * (x3 - x1) + (long long)(y3 - y1) * (y3 - y1);\n    long long diag2 = (long long)(x4 - x2) * (x4 - x2) + (long long)(y4 - y2) * (y4 - y2);\n    \n    if (!((d1 == d3 && d2 == d4) || (d1 == d2 && d3 == d4))) return false;\n    if (diag1 != diag2) return false;\n    \n    // Check if it's axis-parallel or 45-degree\n    int dx1 = x2 - x1, dy1 = y2 - y1;\n    int dx2 = x3 - x2, dy2 = y3 - y2;\n    \n    // Axis parallel: dx=0 or dy=0\n    // 45-degree: |dx| = |dy|\n    bool side1_valid = (dx1 == 0 || dy1 == 0 || abs(dx1) == abs(dy1));\n    bool side2_valid = (dx2 == 0 || dy2 == 0 || abs(dx2) == abs(dy2));\n    \n    return side1_valid && side2_valid;\n}\n\n// Check if there are no dots on the perimeter of the rectangle\nbool no_dots_on_perimeter(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Generate all points on the perimeter\n    vector<pair<int, int>> perimeter;\n    \n    // Side 1: from (x1,y1) to (x2,y2)\n    int dx = x2 - x1, dy = y2 - y1;\n    int steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x1 + (dx * i) / steps;\n            int y = y1 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Side 2: from (x2,y2) to (x3,y3)\n    dx = x3 - x2; dy = y3 - y2;\n    steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x2 + (dx * i) / steps;\n            int y = y2 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Side 3: from (x3,y3) to (x4,y4)\n    dx = x4 - x3; dy = y4 - y3;\n    steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x3 + (dx * i) / steps;\n            int y = y3 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Side 4: from (x4,y4) to (x1,y1)\n    dx = x1 - x4; dy = y1 - y4;\n    steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x4 + (dx * i) / steps;\n            int y = y4 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Check if any of the perimeter points (except the 4 corners) have dots\n    set<pair<int, int>> corners = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    for (auto& p : perimeter) {\n        if (corners.count(p)) continue;\n        if (grid[p.first][p.second]) return false;\n    }\n    \n    return true;\n}\n\n// Simple approach: try all combinations\nvoid solve() {\n    // Collect all current dot positions\n    vector<pair<int, int>> dots;\n    for (int i = 0; i < M; i++) {\n        dots.push_back(initial_dots[i]);\n        grid[initial_dots[i].first][initial_dots[i].second] = true;\n    }\n    \n    // Try to add new dots\n    while (!time_limit_exceeded()) {\n        bool found = false;\n        \n        // Create a list of candidate positions sorted by weight (descending)\n        vector<tuple<long long, int, int>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    candidates.push_back({weight(x, y), x, y});\n                }\n            }\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Try each candidate position\n        for (auto& cand : candidates) {\n            if (time_limit_exceeded()) break;\n            \n            int x1 = get<1>(cand);\n            int y1 = get<2>(cand);\n            \n            // Try all combinations of 3 existing dots\n            int sz = dots.size();\n            for (int i = 0; i < sz && !found; i++) {\n                for (int j = i + 1; j < sz && !found; j++) {\n                    for (int k = j + 1; k < sz && !found; k++) {\n                        if (time_limit_exceeded()) return;\n                        \n                        int x2 = dots[i].first, y2 = dots[i].second;\n                        int x3 = dots[j].first, y3 = dots[j].second;\n                        int x4 = dots[k].first, y4 = dots[k].second;\n                        \n                        // Try all permutations of the 3 dots as p2, p3, p4\n                        vector<vector<int>> perms = {\n                            {x2, y2, x3, y3, x4, y4},\n                            {x2, y2, x4, y4, x3, y3},\n                            {x3, y3, x2, y2, x4, y4},\n                            {x3, y3, x4, y4, x2, y2},\n                            {x4, y4, x2, y2, x3, y3},\n                            {x4, y4, x3, y3, x2, y2}\n                        };\n                        \n                        for (auto& perm : perms) {\n                            // Check if these 4 points can form a valid rectangle\n                            if (is_valid_rectangle(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                if (no_dots_on_perimeter(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                    // Valid operation found\n                                    operations.push_back(make_tuple(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]));\n                                    grid[x1][y1] = true;\n                                    dots.push_back({x1, y1});\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!found) break; // No more valid operations\n    }\n}\n\nint main() {\n    start_time = high_resolution_clock::now();\n    \n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    initial_dots.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> initial_dots[i].first >> initial_dots[i].second;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" \n             << get<2>(op) << \" \" << get<3>(op) << \" \"\n             << get<4>(op) << \" \" << get<5>(op) << \" \"\n             << get<6>(op) << \" \" << get<7>(op) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 10;\nconst int TOTAL_CANDIES = 100;\n\n// Directions: F(forward/up), B(backward/down), L(left), R(right)\nconst vector<pair<int, int>> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"FBLR\";\n\nclass CandyBox {\nprivate:\n    vector<vector<int>> grid; // 0 = empty, 1,2,3 = flavors\n    vector<int> flavor_counts;\n\npublic:\n    CandyBox() : grid(GRID_SIZE, vector<int>(GRID_SIZE, 0)), flavor_counts(4, 0) {}\n\n    void place_candy(int pos, int flavor) {\n        int empty_count = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] == 0) {\n                    empty_count++;\n                    if (empty_count == pos) {\n                        grid[i][j] = flavor;\n                        flavor_counts[flavor]++;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulate tilting in given direction\n    void tilt(int dir_idx) {\n        auto [di, dj] = DIRS[dir_idx];\n        \n        if (dir_idx == 0) { // Forward (up) - move rows from top to bottom\n            for (int i = 0; i < GRID_SIZE; i++) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 1) { // Backward (down) - move rows from bottom to top\n            for (int i = GRID_SIZE - 1; i >= 0; i--) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 2) { // Left - move columns from left to right\n            for (int j = 0; j < GRID_SIZE; j++) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else { // Right - move columns from right to left\n            for (int j = GRID_SIZE - 1; j >= 0; j--) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        }\n    }\n\nprivate:\n    void move_candy(int i, int j, int di, int dj) {\n        int flavor = grid[i][j];\n        grid[i][j] = 0;\n        \n        int ni = i + di, nj = j + dj;\n        while (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == 0) {\n            i = ni;\n            j = nj;\n            ni += di;\n            nj += dj;\n        }\n        \n        grid[i][j] = flavor;\n    }\n\npublic:\n    // Evaluate clustering quality\n    int evaluate_clustering() {\n        vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n        int total_score = 0;\n        \n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int component_size = dfs_component(i, j, grid[i][j], visited);\n                    total_score += component_size * component_size;\n                }\n            }\n        }\n        \n        return total_score;\n    }\n\nprivate:\n    int dfs_component(int i, int j, int flavor, vector<vector<bool>>& visited) {\n        if (i < 0 || i >= GRID_SIZE || j < 0 || j >= GRID_SIZE || \n            visited[i][j] || grid[i][j] != flavor) {\n            return 0;\n        }\n        \n        visited[i][j] = true;\n        int size = 1;\n        \n        // Check 4 adjacent cells\n        for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n            size += dfs_component(i + di, j + dj, flavor, visited);\n        }\n        \n        return size;\n    }\n\npublic:\n    CandyBox copy() const {\n        CandyBox new_box;\n        new_box.grid = grid;\n        new_box.flavor_counts = flavor_counts;\n        return new_box;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<int> flavors(TOTAL_CANDIES);\n    for (int i = 0; i < TOTAL_CANDIES; i++) {\n        cin >> flavors[i];\n    }\n    \n    CandyBox box;\n    \n    for (int t = 0; t < TOTAL_CANDIES; t++) {\n        int pos;\n        cin >> pos;\n        \n        // Place the candy\n        box.place_candy(pos, flavors[t]);\n        \n        if (t == TOTAL_CANDIES - 1) {\n            // No need to output direction for last candy\n            break;\n        }\n        \n        // Evaluate each possible tilt direction\n        int best_direction = 0;\n        int best_score = -1;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            CandyBox temp_box = box.copy();\n            temp_box.tilt(dir);\n            int score = temp_box.evaluate_clustering();\n            \n            if (score > best_score) {\n                best_score = score;\n                best_direction = dir;\n            }\n        }\n        \n        cout << DIR_CHARS[best_direction] << endl;\n        cout.flush();\n        \n        // Actually perform the tilt\n        box.tilt(best_direction);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <boost/graph/adjacency_list.hpp>\n#include <boost/graph/graph_traits.hpp>\n#include <Eigen/Dense>\n\nusing namespace std;\nusing namespace Eigen;\n\n// Fast I/O optimization\nstatic auto fast_io = []() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n    return 0;\n}();\n\nconst int MAX_N = 100;\nconst int MIN_N = 4;\n\n// Convert adjacency matrix to string representation\nstring graphToString(const vector<vector<int>>& adj, int n) {\n    string result;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            result += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return result;\n}\n\n// Convert string to adjacency matrix\nvector<vector<int>> stringToGraph(const string& s, int n) {\n    vector<vector<int>> adj(n, vector<int>(n, 0));\n    int idx = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[idx] == '1') {\n                adj[i][j] = adj[j][i] = 1;\n            }\n            idx++;\n        }\n    }\n    return adj;\n}\n\n// Calculate degree sequence histogram\nvector<int> getDegreeHistogram(const vector<vector<int>>& adj, int n) {\n    vector<int> degrees(n, 0);\n    for (int i = 0; i < n; ++i) {\n        degrees[i] = accumulate(adj[i].begin(), adj[i].end(), 0);\n    }\n    vector<int> hist(n, 0);\n    for (int d : degrees) {\n        if (d < n) hist[d]++;\n    }\n    return hist;\n}\n\n// Count triangles in graph\nint countTriangles(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (adj[i][j]) {\n                for (int k = j + 1; k < n; ++k) {\n                    if (adj[i][k] && adj[j][k]) {\n                        count++;\n                    }\n                }\n            }\n        }\n    }\n    return count;\n}\n\n// Count 4-cycles\nint count4Cycles(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (!adj[i][j]) continue;\n            for (int k = j + 1; k < n; ++k) {\n                if (!adj[j][k]) continue;\n                for (int l = k + 1; l < n; ++l) {\n                    if (adj[k][l] && adj[l][i]) {\n                        count++;\n                    }\n                }\n            }\n        }\n    }\n    return count;\n}\n\n// Calculate edge count\nint countEdges(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            count += adj[i][j];\n        }\n    }\n    return count;\n}\n\n// Generate diverse graphs for encoding\nvector<string> generateGraphs(int M, int N) {\n    vector<string> graphs;\n    \n    // Strategy: Create graphs with different structural properties\n    for (int k = 0; k < M; ++k) {\n        vector<vector<int>> adj(N, vector<int>(N, 0));\n        \n        // Different strategies based on k\n        if (k < M/4) {\n            // Sparse graphs - path-like structures\n            int edges = max(1, min(N-1, (k * (N-1)) / (M/4)));\n            for (int i = 0; i < edges && i < N-1; ++i) {\n                adj[i][i+1] = adj[i+1][i] = 1;\n            }\n        } else if (k < M/2) {\n            // Medium density - varying edge counts\n            int target_edges = ((k - M/4) * N * (N-1) / 8) / (M/4);\n            int edges_added = 0;\n            for (int i = 0; i < N && edges_added < target_edges; ++i) {\n                for (int j = i + 1; j < N && edges_added < target_edges; ++j) {\n                    if ((i + j + k) % 3 == 0) {\n                        adj[i][j] = adj[j][i] = 1;\n                        edges_added++;\n                    }\n                }\n            }\n        } else if (k < 3*M/4) {\n            // Higher density with specific patterns\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i * j + k) % 5 < 3) {\n                        adj[i][j] = adj[j][i] = 1;\n                    }\n                }\n            }\n        } else {\n            // Dense graphs with specific structures\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i + j + k) % 7 < 5) {\n                        adj[i][j] = adj[j][i] = 1;\n                    }\n                }\n            }\n        }\n        \n        graphs.push_back(graphToString(adj, N));\n    }\n    \n    return graphs;\n}\n\n// Precompute signatures for all template graphs\nstruct GraphSignature {\n    vector<int> degree_hist;\n    int edge_count;\n    int triangle_count;\n    int cycle4_count;\n};\n\nvector<GraphSignature> computeSignatures(const vector<string>& graphs, int N) {\n    vector<GraphSignature> signatures;\n    for (const string& g_str : graphs) {\n        auto adj = stringToGraph(g_str, N);\n        GraphSignature sig;\n        sig.degree_hist = getDegreeHistogram(adj, N);\n        sig.edge_count = countEdges(adj, N);\n        sig.triangle_count = countTriangles(adj, N);\n        sig.cycle4_count = count4Cycles(adj, N);\n        signatures.push_back(sig);\n    }\n    return signatures;\n}\n\n// Score how well a noisy graph matches a template signature\ndouble scoreMatch(const vector<vector<int>>& noisy_adj, \n                  const GraphSignature& template_sig, \n                  int N, double epsilon) {\n    // Get noisy graph properties\n    auto noisy_degree_hist = getDegreeHistogram(noisy_adj, N);\n    int noisy_edge_count = countEdges(noisy_adj, N);\n    int noisy_triangle_count = countTriangles(noisy_adj, N);\n    int noisy_cycle4_count = count4Cycles(noisy_adj, N);\n    \n    // Compute similarity score\n    double score = 0.0;\n    \n    // Degree histogram similarity\n    double degree_score = 0.0;\n    for (int i = 0; i < N; ++i) {\n        degree_score -= abs(noisy_degree_hist[i] - template_sig.degree_hist[i]);\n    }\n    score += degree_score * 2.0;\n    \n    // Edge count similarity (adjusted for expected noise)\n    double expected_noise = N * (N-1) / 2 * epsilon;\n    double edge_diff = abs(noisy_edge_count - template_sig.edge_count);\n    if (edge_diff <= 2 * expected_noise) {\n        score += (2 * expected_noise - edge_diff) / max(1.0, expected_noise);\n    }\n    \n    // Triangle count similarity (more sensitive to noise)\n    double triangle_diff = abs(noisy_triangle_count - template_sig.triangle_count);\n    score -= triangle_diff * 0.1;\n    \n    // 4-cycle similarity\n    double cycle4_diff = abs(noisy_cycle4_count - template_sig.cycle4_count);\n    score -= cycle4_diff * 0.05;\n    \n    return score;\n}\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n    \n    // Choose N based on M and epsilon\n    int N = min(50, max(10, M/2 + 10));  // Adaptive sizing\n    N = min(N, 100);\n    \n    // Generate template graphs\n    auto graphs = generateGraphs(M, N);\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute signatures\n    auto signatures = computeSignatures(graphs, N);\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        auto noisy_adj = stringToGraph(h_str, N);\n        \n        // Find best match\n        int best_match = 0;\n        double best_score = -1e9;\n        \n        for (int i = 0; i < M; ++i) {\n            double score = scoreMatch(noisy_adj, signatures[i], N, epsilon);\n            if (score > best_score) {\n                best_score = score;\n                best_match = i;\n            }\n        }\n        \n        cout << best_match << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<vector<pair<int, int>>> adj; // {to, weight}\nvector<vector<int>> dist;\n\n// Calculate all-pairs shortest paths\nvoid calcDistances() {\n    dist.assign(N, vector<int>(N, INF));\n    for (int i = 0; i < N; i++) {\n        dist[i][i] = 0;\n    }\n    \n    for (const auto& e : edges) {\n        dist[e.u][e.v] = min(dist[e.u][e.v], e.w);\n        dist[e.v][e.u] = min(dist[e.v][e.u], e.w);\n    }\n    \n    // Floyd-Warshall\n    for (int k = 0; k < N; k++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (dist[i][k] < INF && dist[k][j] < INF) {\n                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n                }\n            }\n        }\n    }\n}\n\n// Calculate frustration for a specific day (edge set removal)\ndouble calculateFrustration(const vector<int>& removed_edges) {\n    // Create temporary adjacency list without removed edges\n    vector<vector<pair<int, int>>> temp_adj(N);\n    vector<bool> removed(M, false);\n    \n    for (int eid : removed_edges) {\n        removed[eid] = true;\n    }\n    \n    for (const auto& e : edges) {\n        if (!removed[e.id]) {\n            temp_adj[e.u].push_back({e.v, e.w});\n            temp_adj[e.v].push_back({e.u, e.w});\n        }\n    }\n    \n    double total_increase = 0.0;\n    int count = 0;\n    \n    // For a subset of vertex pairs to speed up calculation\n    vector<int> sample_vertices;\n    for (int i = 0; i < N && i < 100; i++) {\n        sample_vertices.push_back(i);\n    }\n    \n    for (int i : sample_vertices) {\n        // Dijkstra from vertex i\n        vector<int> d(N, INF);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        d[i] = 0;\n        pq.push({0, i});\n        \n        while (!pq.empty()) {\n            auto [cur_dist, u] = pq.top(); pq.pop();\n            if (cur_dist > d[u]) continue;\n            \n            for (auto& [v, w] : temp_adj[u]) {\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    pq.push({d[v], v});\n                }\n            }\n        }\n        \n        for (int j = 0; j < N; j++) {\n            if (i != j) {\n                int original_dist = dist[i][j];\n                int new_dist = d[j];\n                if (new_dist >= INF) new_dist = INF;\n                total_increase += max(0, new_dist - original_dist);\n                count++;\n            }\n        }\n    }\n    \n    return count > 0 ? total_increase / count : 0.0;\n}\n\n// Simple greedy approach based on edge betweenness-like metric\nvector<int> assignDays() {\n    vector<int> result(M);\n    vector<pair<double, int>> edge_scores(M);\n    \n    // Calculate a simple importance score for each edge\n    // Higher score = more important (should be repaired later)\n    for (int i = 0; i < M; i++) {\n        const auto& e = edges[i];\n        // Simple heuristic: edges with lower weights might be more critical\n        // But also consider degree of vertices\n        int degree_sum = 0;\n        for (const auto& adj_edge : adj[e.u]) degree_sum++;\n        for (const auto& adj_edge : adj[e.v]) degree_sum++;\n        \n        // Lower weight and higher degree = more critical\n        edge_scores[i] = {1.0 / (e.w * degree_sum), i};\n    }\n    \n    sort(edge_scores.begin(), edge_scores.end());\n    \n    // Assign days: less critical edges first\n    int edges_per_day = (M + D - 1) / D;\n    if (edges_per_day > K) edges_per_day = K;\n    \n    for (int i = 0; i < M; i++) {\n        int edge_id = edge_scores[i].second;\n        int day = min(i / K, D - 1);\n        result[edge_id] = day + 1; // Days are 1-indexed\n    }\n    \n    // Ensure constraint: at most K edges per day\n    vector<int> day_count(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_count[result[i]]++;\n    }\n    \n    // Fix violations\n    for (int day = 1; day <= D; day++) {\n        if (day_count[day] > K) {\n            // Move excess edges to other days\n            int excess = day_count[day] - K;\n            for (int i = 0; i < M && excess > 0; i++) {\n                if (result[i] == day) {\n                    // Try to find a day with space\n                    for (int new_day = 1; new_day <= D; new_day++) {\n                        if (day_count[new_day] < K) {\n                            result[i] = new_day;\n                            day_count[day]--;\n                            day_count[new_day]++;\n                            excess--;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Improved approach: consider impact of edge removal\nvector<int> improvedAssignDays() {\n    vector<int> result(M);\n    \n    // Calculate edge \"importance\" based on how much damage they do when removed\n    vector<pair<double, int>> edge_importance(M);\n    \n    for (int i = 0; i < M; i++) {\n        double importance = 0.0;\n        \n        // Sample-based estimation of edge importance\n        const int SAMPLE_SIZE = min(50, N);\n        for (int s = 0; s < SAMPLE_SIZE; s++) {\n            int u = rand() % N;\n            int v = rand() % N;\n            if (u == v) continue;\n            \n            // Original distance\n            int orig_dist = dist[u][v];\n            \n            // Estimate impact if this edge is removed\n            // This is a simplified approximation\n            importance += 1.0 / (orig_dist + 1);\n        }\n        \n        edge_importance[i] = {-importance, i}; // Negative because lower importance = better to repair early\n    }\n    \n    sort(edge_importance.begin(), edge_importance.end());\n    \n    // Assign to days ensuring constraints\n    vector<vector<int>> day_edges(D);\n    \n    // Distribute edges across days\n    for (int i = 0; i < M; i++) {\n        int edge_id = edge_importance[i].second;\n        // Try to place in earliest possible day\n        bool placed = false;\n        for (int day = 0; day < D; day++) {\n            if (day_edges[day].size() < K) {\n                day_edges[day].push_back(edge_id);\n                result[edge_id] = day + 1;\n                placed = true;\n                break;\n            }\n        }\n        // If all days are full, place in last day (shouldn't happen due to constraints)\n        if (!placed) {\n            day_edges[D-1].push_back(edge_id);\n            result[edge_id] = D;\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 >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--; // Convert to 0-indexed\n        edges[i] = {u, v, w, i};\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Build adjacency list\n    adj.assign(N, vector<pair<int, int>>());\n    for (const auto& e : edges) {\n        adj[e.u].push_back({e.v, e.w});\n        adj[e.v].push_back({e.u, e.w});\n    }\n    \n    // Calculate initial distances\n    calcDistances();\n    \n    // Assign days\n    vector<int> result = improvedAssignDays();\n    \n    // Output result\n    for (int i = 0; i < M; i++) {\n        cout << result[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_D = 14;\nint D;\nchar f[2][MAX_D][MAX_D];\nchar r[2][MAX_D][MAX_D];\n\n// 3D grid for each construction\nint b[2][MAX_D][MAX_D][MAX_D];\nvector<vector<pair<int,int>>> components[2];\n\n// For tracking connected components and creating actual blocks\nstruct Block {\n    vector<tuple<int,int,int>> cubes;\n    int id;\n};\n\nvector<Block> blocks;\nmap<vector<tuple<int,int,int>>, int> block_shapes; // To ensure consistent block IDs\n\n// Directions for 6-connectivity\nconst int dx[6] = {1, -1, 0, 0, 0, 0};\nconst int dy[6] = {0, 0, 1, -1, 0, 0};\nconst int dz[6] = {0, 0, 0, 0, 1, -1};\n\nbool isValid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n\n// Get connected component starting from (x,y,z)\nvector<tuple<int,int,int>> getComponent(int construction_id, int start_x, int start_y, int start_z,\n                                       vector<vector<vector<bool>>>& visited) {\n    vector<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push({start_x, start_y, start_z});\n    visited[start_x][start_y][start_z] = true;\n    component.push_back({start_x, start_y, start_z});\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front(); q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            \n            if (isValid(nx, ny, nz) && !visited[nx][ny][nz] && b[construction_id][nx][ny][nz] == 1) {\n                visited[nx][ny][nz] = true;\n                q.push({nx, ny, nz});\n                component.push_back({nx, ny, nz});\n            }\n        }\n    }\n    \n    return component;\n}\n\n// Normalize block shape for comparison (translate to origin)\nvector<tuple<int,int,int>> normalizeShape(vector<tuple<int,int,int>>& shape) {\n    if (shape.empty()) return shape;\n    \n    int min_x = get<0>(shape[0]), min_y = get<1>(shape[0]), min_z = get<2>(shape[0]);\n    \n    for (auto& cube : shape) {\n        min_x = min(min_x, get<0>(cube));\n        min_y = min(min_y, get<1>(cube));\n        min_z = min(min_z, get<2>(cube));\n    }\n    \n    vector<tuple<int,int,int>> normalized;\n    for (auto& cube : shape) {\n        normalized.push_back({get<0>(cube) - min_x, get<1>(cube) - min_y, get<2>(cube) - min_z});\n    }\n    \n    sort(normalized.begin(), normalized.end());\n    return normalized;\n}\n\nint getOrCreateBlock(vector<tuple<int,int,int>>& shape) {\n    auto normalized = normalizeShape(shape);\n    \n    if (block_shapes.find(normalized) != block_shapes.end()) {\n        return block_shapes[normalized];\n    } else {\n        int new_id = blocks.size() + 1;\n        block_shapes[normalized] = new_id;\n        blocks.push_back({normalized, new_id});\n        return new_id;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read input\n    for (int i = 0; i < 2; i++) {\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int x = 0; x < D; x++) {\n                f[i][z][x] = line[x];\n            }\n        }\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int y = 0; y < D; y++) {\n                r[i][z][y] = line[y];\n            }\n        }\n    }\n    \n    // Initialize grids\n    memset(b, 0, sizeof(b));\n    \n    // Create constructions - place unit cubes where both silhouettes allow\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                        b[i][x][y][z] = 1; // Mark as occupied\n                    }\n                }\n            }\n        }\n    }\n    \n    // Assign block IDs by finding connected components\n    int final_b[2][MAX_D][MAX_D][MAX_D] = {};\n    \n    for (int i = 0; i < 2; i++) {\n        vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (b[i][x][y][z] == 1 && !visited[x][y][z]) {\n                        auto component = getComponent(i, x, y, z, visited);\n                        int block_id = getOrCreateBlock(component);\n                        \n                        // Assign this block ID to all cubes in the component\n                        for (auto& cube : component) {\n                            final_b[i][get<0>(cube)][get<1>(cube)][get<2>(cube)] = block_id;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << blocks.size() << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        bool first = true;\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (!first) cout << \" \";\n                    cout << final_b[i][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\nusing ld = long double;\nusing pii = pair<int, int>;\nusing pll = pair<ll, ll>;\n\nconst int MAX_N = 100;\nconst int MAX_M = 300;\nconst int MAX_K = 5000;\nconst int MAX_POWER = 5000;\n\nint N, M, K;\nvector<pair<int, int>> vertices;\nvector<tuple<int, int, int>> edges;\nvector<pair<int, int>> residents;\n\n// Distance calculation\nint euclidean_distance(int i, int j) {\n    int dx = vertices[i].first - vertices[j].first;\n    int dy = vertices[i].second - vertices[j].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\nint resident_to_vertex_distance(int res_idx, int vert_idx) {\n    int dx = residents[res_idx].first - vertices[vert_idx].first;\n    int dy = residents[res_idx].second - vertices[vert_idx].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\n// Find minimum spanning tree using Prim's algorithm\nvector<bool> find_mst_edges() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vertex_reached[0] = true; // Start from vertex 1 (index 0)\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    \n    // Add all edges from vertex 1\n    for (int j = 0; j < M; j++) {\n        auto [u, v, w] = edges[j];\n        u--; v--; // Convert to 0-indexed\n        if (u == 0) {\n            pq.push({w, v, j});\n        } else if (v == 0) {\n            pq.push({w, u, j});\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [weight, to, edge_idx] = pq.top();\n        pq.pop();\n        \n        if (vertex_reached[to]) continue;\n        \n        vertex_reached[to] = true;\n        edge_used[edge_idx] = true;\n        \n        // Add edges from newly reached vertex\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            if (u == to && !vertex_reached[v]) {\n                pq.push({w, v, j});\n            } else if (v == to && !vertex_reached[u]) {\n                pq.push({w, u, j});\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\n// Calculate minimum power needed for each vertex to cover residents\nvector<int> calculate_min_power(const vector<bool>& vertex_active) {\n    vector<int> power(N, 0);\n    vector<bool> covered(K, false);\n    \n    // First pass: calculate required power for each active vertex\n    for (int i = 0; i < N; i++) {\n        if (!vertex_active[i]) continue;\n        \n        int max_dist = 0;\n        for (int k = 0; k < K; k++) {\n            int dist = resident_to_vertex_distance(k, i);\n            if (dist <= MAX_POWER) {\n                max_dist = max(max_dist, dist);\n            }\n        }\n        power[i] = max_dist;\n    }\n    \n    // Greedy approach: iteratively improve coverage\n    for (int iter = 0; iter < 3; iter++) {\n        fill(covered.begin(), covered.end(), false);\n        \n        // Mark covered residents\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i] || power[i] == 0) continue;\n            for (int k = 0; k < K; k++) {\n                if (resident_to_vertex_distance(k, i) <= power[i]) {\n                    covered[k] = true;\n                }\n            }\n        }\n        \n        // Find uncovered residents\n        vector<int> uncovered;\n        for (int k = 0; k < K; k++) {\n            if (!covered[k]) uncovered.push_back(k);\n        }\n        \n        if (uncovered.empty()) break;\n        \n        // For each active vertex, see how much additional power helps\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i]) continue;\n            \n            int max_needed = 0;\n            for (int k : uncovered) {\n                int dist = resident_to_vertex_distance(k, i);\n                if (dist <= MAX_POWER) {\n                    max_needed = max(max_needed, dist);\n                }\n            }\n            power[i] = max(power[i], max_needed);\n        }\n    }\n    \n    return power;\n}\n\n// Improved approach: use a more sophisticated method\nvector<bool> improved_edge_selection() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vector<bool> resident_covered(K, false);\n    vertex_reached[0] = true;\n    \n    // Precompute resident distances to all vertices\n    vector<vector<int>> resident_distances(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resident_distances[k][i] = resident_to_vertex_distance(k, i);\n        }\n    }\n    \n    // Greedily select edges that maximize coverage efficiency\n    for (int step = 0; step < N - 1; step++) {\n        int best_edge = -1;\n        double best_efficiency = -1e18;\n        \n        // Find the best edge to add\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            \n            // Check if this edge connects a reached and unreached vertex\n            bool connects = (vertex_reached[u] && !vertex_reached[v]) || \n                           (vertex_reached[v] && !vertex_reached[u]);\n            \n            if (!connects) continue;\n            \n            int new_vertex = vertex_reached[u] ? v : u;\n            \n            // Calculate how many new residents this would cover\n            int new_coverage = 0;\n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k] && resident_distances[k][new_vertex] <= MAX_POWER) {\n                    new_coverage++;\n                }\n            }\n            \n            // Efficiency = coverage per cost\n            double efficiency = (double)new_coverage / max(w, 1);\n            \n            if (efficiency > best_efficiency) {\n                best_efficiency = efficiency;\n                best_edge = j;\n            }\n        }\n        \n        if (best_edge == -1) break;\n        \n        edge_used[best_edge] = true;\n        auto [u, v, w] = edges[best_edge];\n        u--; v--;\n        int new_vertex = vertex_reached[u] ? v : u;\n        vertex_reached[new_vertex] = true;\n        \n        // Update covered residents\n        for (int k = 0; k < K; k++) {\n            if (resident_distances[k][new_vertex] <= MAX_POWER) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    \n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    edges.resize(M);\n    for (int j = 0; j < M; j++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n    }\n    \n    residents.resize(K);\n    for (int k = 0; k < K; k++) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n    \n    // Select edges using improved approach\n    vector<bool> edge_used = improved_edge_selection();\n    \n    // Determine which vertices are active\n    vector<bool> vertex_active(N, false);\n    vertex_active[0] = true; // Always include vertex 1\n    \n    // BFS to find all reachable vertices\n    queue<int> q;\n    q.push(0);\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int j = 0; j < M; j++) {\n            if (!edge_used[j]) continue;\n            \n            auto [v1, v2, w] = edges[j];\n            v1--; v2--; // Convert to 0-indexed\n            \n            if (v1 == u && !vertex_active[v2]) {\n                vertex_active[v2] = true;\n                q.push(v2);\n            } else if (v2 == u && !vertex_active[v1]) {\n                vertex_active[v1] = true;\n                q.push(v1);\n            }\n        }\n    }\n    \n    // Calculate power requirements\n    vector<int> power = calculate_min_power(vertex_active);\n    \n    // Output results\n    for (int i = 0; i < N; i++) {\n        cout << power[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    for (int j = 0; j < M; j++) {\n        cout << (edge_used[j] ? 1 : 0);\n        if (j < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 10000;\nconst int TOTAL_BALLS = N * (N + 1) / 2;\n\nstruct Position {\n    int x, y;\n    Position() : x(0), y(0) {}\n    Position(int _x, int _y) : x(_x), y(_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\n// Directions for adjacency (6 directions in triangular grid)\nconst vector<pair<int, int>> DIRECTIONS = {\n    {-1, -1}, {-1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1}\n};\n\nclass Pyramid {\npublic:\n    int grid[N][N];\n    vector<pair<Position, Position>> operations;\n    \n    Pyramid() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                cin >> grid[i][j];\n            }\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y <= x;\n    }\n    \n    bool is_adjacent(int x1, int y1, int x2, int y2) {\n        for (auto& dir : DIRECTIONS) {\n            int nx = x1 + dir.first;\n            int ny = y1 + dir.second;\n            if (nx == x2 && ny == y2) return true;\n        }\n        return false;\n    }\n    \n    vector<Position> get_neighbors(int x, int y) {\n        vector<Position> neighbors;\n        for (auto& dir : DIRECTIONS) {\n            int nx = x + dir.first;\n            int ny = y + dir.second;\n            if (is_valid(nx, ny)) {\n                neighbors.emplace_back(nx, ny);\n            }\n        }\n        return neighbors;\n    }\n    \n    int count_violations() {\n        int count = 0;\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] > grid[i+1][j]) count++;\n                if (grid[i][j] > grid[i+1][j+1]) count++;\n            }\n        }\n        return count;\n    }\n    \n    void swap_balls(int x1, int y1, int x2, int y2) {\n        if (!is_adjacent(x1, y1, x2, y2)) return;\n        if (operations.size() >= MAX_OPS) return;\n        \n        swap(grid[x1][y1], grid[x2][y2]);\n        operations.emplace_back(Position(x1, y1), Position(x2, y2));\n    }\n    \n    // BFS to find path between two positions\n    vector<pair<Position, Position>> find_path(Position start, Position end) {\n        if (start == end) return {};\n        \n        queue<Position> q;\n        map<pair<int, int>, pair<int, int>> parent;\n        set<pair<int, int>> visited;\n        \n        q.push(start);\n        visited.insert({start.x, start.y});\n        \n        while (!q.empty()) {\n            Position current = q.front();\n            q.pop();\n            \n            if (current == end) {\n                // Reconstruct path\n                vector<Position> path;\n                Position pos = end;\n                while (!(pos == start)) {\n                    path.push_back(pos);\n                    auto p = parent[{pos.x, pos.y}];\n                    pos = Position(p.first, p.second);\n                }\n                path.push_back(start);\n                reverse(path.begin(), path.end());\n                \n                vector<pair<Position, Position>> swaps;\n                for (size_t i = 0; i + 1 < path.size(); i++) {\n                    swaps.emplace_back(path[i], path[i+1]);\n                }\n                return swaps;\n            }\n            \n            for (auto& neighbor : get_neighbors(current.x, current.y)) {\n                if (visited.find({neighbor.x, neighbor.y}) == visited.end()) {\n                    visited.insert({neighbor.x, neighbor.y});\n                    parent[{neighbor.x, neighbor.y}] = {current.x, current.y};\n                    q.push(neighbor);\n                }\n            }\n        }\n        \n        return {}; // No path found\n    }\n    \n    // Find position of a specific value\n    Position find_position(int value) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] == value) {\n                    return Position(i, j);\n                }\n            }\n        }\n        return Position(-1, -1);\n    }\n    \n    void output() {\n        cout << operations.size() << \"\\n\";\n        for (auto& op : operations) {\n            cout << op.first.x << \" \" << op.first.y << \" \" \n                 << op.second.x << \" \" << op.second.y << \"\\n\";\n        }\n    }\n};\n\n// Heuristic approach: Try to fix violations greedily\nvoid solve(Pyramid& pyramid) {\n    // Simple greedy approach: try to fix top violations first\n    for (int iteration = 0; iteration < 5 && pyramid.operations.size() < MAX_OPS; iteration++) {\n        bool improved = false;\n        \n        // Check each position and see if we can improve it\n        for (int i = 0; i < N - 1 && pyramid.operations.size() < MAX_OPS; i++) {\n            for (int j = 0; j <= i && pyramid.operations.size() < MAX_OPS; j++) {\n                int current = pyramid.grid[i][j];\n                int left_child = pyramid.grid[i+1][j];\n                int right_child = pyramid.grid[i+1][j+1];\n                \n                // If violation exists\n                if (current > left_child || current > right_child) {\n                    // Try to find a better value for this position\n                    int min_required = max(left_child, right_child);\n                    \n                    // Look for a suitable value in the pyramid\n                    Position best_pos(-1, -1);\n                    int best_value = INT_MAX;\n                    \n                    // Search in lower rows\n                    for (int x = i + 1; x < N && best_pos.x == -1; x++) {\n                        for (int y = 0; y <= x; y++) {\n                            if (pyramid.grid[x][y] < min_required && pyramid.grid[x][y] < best_value) {\n                                best_value = pyramid.grid[x][y];\n                                best_pos = Position(x, y);\n                            }\n                        }\n                    }\n                    \n                    // If found, try to swap\n                    if (best_pos.x != -1) {\n                        Position current_pos(i, j);\n                        auto path = pyramid.find_path(best_pos, current_pos);\n                        \n                        // Execute swaps along the path\n                        for (auto& swap_op : path) {\n                            if (pyramid.operations.size() >= MAX_OPS) break;\n                            pyramid.swap_balls(swap_op.first.x, swap_op.first.y,\n                                             swap_op.second.x, swap_op.second.y);\n                        }\n                        if (!path.empty()) improved = true;\n                    }\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Additional simple swaps to reduce violations\n    if (pyramid.operations.size() < MAX_OPS - 100) {\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (pyramid.operations.size() >= MAX_OPS - 2) break;\n                \n                int current = pyramid.grid[i][j];\n                int left_child = pyramid.grid[i+1][j];\n                int right_child = pyramid.grid[i+1][j+1];\n                \n                if (current > left_child) {\n                    pyramid.swap_balls(i, j, i+1, j);\n                } else if (current > right_child) {\n                    pyramid.swap_balls(i, j, i+1, j+1);\n                }\n            }\n            if (pyramid.operations.size() >= MAX_OPS - 2) break;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    Pyramid pyramid;\n    pyramid.read_input();\n    \n    solve(pyramid);\n    \n    pyramid.output();\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int D = 9;\nconst int ENTRANCE_ROW = 0;\nconst int ENTRANCE_COL = 4;\n\nint N;\nbool is_obstacle[D][D];\nbool has_container[D][D];\nint container_number[D][D];\nvector<pair<int, int>> obstacles;\n\n// Directions: up, down, left, right\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\n\n// Check if coordinates are valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\n// Check if a cell is the entrance\nbool is_entrance(int x, int y) {\n    return x == ENTRANCE_ROW && y == ENTRANCE_COL;\n}\n\n// BFS to find all reachable empty cells from entrance\nvector<vector<bool>> get_reachable() {\n    vector<vector<bool>> reachable(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    reachable[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !has_container[nx][ny] && !reachable[nx][ny]) {\n                reachable[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\n// BFS to find all reachable cells with containers from entrance\nvector<pair<int, int>> get_reachable_containers() {\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    vector<pair<int, int>> result;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    visited[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        // If this cell has a container, add it to result\n        if (has_container[x][y]) {\n            result.push_back({x, y});\n        }\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Calculate Manhattan distance from entrance\nint manhattan_distance(int x, int y) {\n    return abs(x - ENTRANCE_ROW) + abs(y - ENTRANCE_COL);\n}\n\n// Find best position to place a container\npair<int, int> find_best_position(int container_num, int total_containers) {\n    auto reachable = get_reachable();\n    \n    pair<int, int> best_pos = {-1, -1};\n    double best_score = -1e18;\n    \n    // Try all positions\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            // Skip if it's entrance, obstacle, or already has container\n            if (is_entrance(i, j) || is_obstacle[i][j] || has_container[i][j]) {\n                continue;\n            }\n            \n            // Skip if not reachable\n            if (!reachable[i][j]) {\n                continue;\n            }\n            \n            // Calculate score based on multiple factors\n            double distance_score = -manhattan_distance(i, j) * 0.1;\n            double position_score = 0;\n            \n            // Prefer positions that are less likely to block others\n            // Count how many cells would become unreachable if we place container here\n            has_container[i][j] = true;\n            auto new_reachable = get_reachable();\n            has_container[i][j] = false;\n            \n            int blocked_count = 0;\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (!is_entrance(x, y) && !is_obstacle[x][y] && !has_container[x][y]) {\n                        if (reachable[x][y] && !new_reachable[x][y]) {\n                            blocked_count++;\n                        }\n                    }\n                }\n            }\n            \n            double blocking_penalty = -blocked_count * 0.5;\n            \n            // Prefer corners and edges for higher numbers\n            double edge_bonus = 0;\n            if (i == 0 || i == D-1 || j == 0 || j == D-1) {\n                edge_bonus = 0.2;\n            }\n            \n            // For later containers, prefer positions further from entrance\n            double adaptive_distance = (double)container_num / total_containers;\n            double adaptive_score = -(manhattan_distance(i, j) - 4 * adaptive_distance) * 0.1;\n            \n            double total_score = distance_score + blocking_penalty + edge_bonus + adaptive_score;\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_pos = {i, j};\n            }\n        }\n    }\n    \n    return best_pos;\n}\n\nint main() {\n    // Read input\n    cin >> D >> N;\n    \n    // Initialize arrays\n    memset(is_obstacle, false, sizeof(is_obstacle));\n    memset(has_container, false, sizeof(has_container));\n    \n    // Read obstacles\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        obstacles.push_back({r, c});\n    }\n    \n    int total_containers = D * D - 1 - N;\n    vector<pair<int, int>> placement_order(total_containers);\n    \n    // Process each container as it arrives\n    for (int d = 0; d < total_containers; d++) {\n        int container_num;\n        cin >> container_num;\n        \n        // Find best position\n        auto pos = find_best_position(container_num, total_containers);\n        \n        // Place container\n        has_container[pos.first][pos.second] = true;\n        container_number[pos.first][pos.second] = container_num;\n        placement_order[d] = pos;\n        \n        // Output position\n        cout << pos.first << \" \" << pos.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieve containers in optimal order\n    vector<pair<int, int>> retrieval_order;\n    vector<bool> transported(total_containers, false);\n    \n    // Greedy approach: always pick the smallest accessible container number\n    while (retrieval_order.size() < total_containers) {\n        auto reachable_containers = get_reachable_containers();\n        \n        // Find the container with minimum number among reachable ones\n        int min_num = INT_MAX;\n        pair<int, int> best_container = {-1, -1};\n        \n        for (auto& pos : reachable_containers) {\n            int num = container_number[pos.first][pos.second];\n            if (num < min_num) {\n                min_num = num;\n                best_container = pos;\n            }\n        }\n        \n        // Remove this container and add to retrieval order\n        has_container[best_container.first][best_container.second] = false;\n        retrieval_order.push_back(best_container);\n    }\n    \n    // Output retrieval order\n    for (auto& pos : retrieval_order) {\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n = 50, m = 100;\nint input_grid[N][N];\nint output_grid[N][N];\n\n// Adjacency information\nvector<set<int>> adj_list(M + 1);\nvector<vector<bool>> is_adj(M + 1, vector<bool>(M + 1, false));\n\n// Position information for each color\nvector<vector<pair<int, int>>> color_positions(M + 1);\n\n// Find connected components and adjacencies\nvoid analyze_input() {\n    // Collect positions for each color\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            color_positions[color].push_back({i, j});\n        }\n    }\n    \n    // Find adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            // Check 4 directions\n            int dx[] = {-1, 1, 0, 0};\n            int dy[] = {0, 0, -1, 1};\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int neighbor_color = input_grid[ni][nj];\n                    if (color != neighbor_color) {\n                        is_adj[color][neighbor_color] = true;\n                        is_adj[neighbor_color][color] = true;\n                        adj_list[color].insert(neighbor_color);\n                        adj_list[neighbor_color].insert(color);\n                    }\n                } else {\n                    // Boundary - adjacent to outside (color 0)\n                    is_adj[color][0] = true;\n                    is_adj[0][color] = true;\n                    adj_list[color].insert(0);\n                    adj_list[0].insert(color);\n                }\n            }\n        }\n    }\n}\n\n// Simple greedy approach: place colors in a compact way\nvoid generate_output() {\n    // Initialize output grid with 0s\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output_grid[i][j] = 0;\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from center\n    int center_x = N / 2;\n    int center_y = N / 2;\n    \n    // Place color 0 (outside) everywhere first\n    // Then we'll overwrite with other colors\n    \n    vector<bool> placed(M + 1, false);\n    placed[0] = true;\n    \n    // Place colors in order, trying to make them adjacent as required\n    queue<int> to_place;\n    set<int> remaining;\n    \n    for (int i = 1; i <= m; i++) {\n        remaining.insert(i);\n    }\n    \n    // Start with color 1 at center\n    output_grid[center_x][center_y] = 1;\n    placed[1] = true;\n    remaining.erase(1);\n    to_place.push(1);\n    \n    // BFS-like placement to maintain adjacencies\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    while (!to_place.empty() && !remaining.empty()) {\n        int current_color = to_place.front();\n        to_place.pop();\n        \n        // Find adjacent positions that are still 0\n        vector<pair<int, int>> adjacent_empty;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (output_grid[i][j] == current_color) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dx[k];\n                        int nj = j + dy[k];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            if (output_grid[ni][nj] == 0) {\n                                adjacent_empty.push_back({ni, nj});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Place adjacent colors\n        for (int adj_color : adj_list[current_color]) {\n            if (!placed[adj_color] && !remaining.empty() && find(remaining.begin(), remaining.end(), adj_color) != remaining.end()) {\n                if (!adjacent_empty.empty()) {\n                    auto pos = adjacent_empty.back();\n                    adjacent_empty.pop_back();\n                    output_grid[pos.first][pos.second] = adj_color;\n                    placed[adj_color] = true;\n                    remaining.erase(adj_color);\n                    to_place.push(adj_color);\n                }\n            }\n        }\n    }\n    \n    // Place any remaining colors\n    for (int color : remaining) {\n        // Find any empty spot\n        bool placed_color = false;\n        for (int i = 0; i < N && !placed_color; i++) {\n            for (int j = 0; j < N && !placed_color; j++) {\n                if (output_grid[i][j] == 0) {\n                    output_grid[i][j] = color;\n                    placed_color = true;\n                }\n            }\n        }\n    }\n    \n    // Expand each color to make connected regions\n    for (int color = 1; color <= m; color++) {\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_grid[i][j] == color) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.empty()) continue;\n        \n        // Use BFS to expand this color to make it more connected\n        queue<pair<int, int>> q;\n        set<pair<int, int>> visited;\n        \n        for (auto pos : positions) {\n            q.push(pos);\n            visited.insert(pos);\n        }\n        \n        int expansions = min(3, 20 - (int)positions.size()); // Limit expansion\n        int expanded = 0;\n        \n        while (!q.empty() && expanded < expansions) {\n            auto current = q.front();\n            q.pop();\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = current.first + dx[k];\n                int nj = current.second + dy[k];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (output_grid[ni][nj] == 0 && visited.find({ni, nj}) == visited.end()) {\n                        output_grid[ni][nj] = color;\n                        visited.insert({ni, nj});\n                        q.push({ni, nj});\n                        expanded++;\n                        if (expanded >= expansions) break;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input_grid[i][j];\n        }\n    }\n    \n    // Analyze the input to understand adjacencies\n    analyze_input();\n    \n    // Generate optimized output\n    generate_output();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << output_grid[i][j];\n            if (j < N - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int MAX_N = 105;\nconst int MAX_Q = 32 * MAX_N;\n\nint N, D, Q;\nvector<vector<int>> comparisons;\nvector<char> results;\nvector<double> weight_estimates;\n\n// Function to query the balance\nstring query(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 result;\n    cin >> result;\n    return result;\n}\n\n// Estimate weights using pairwise comparisons\nvoid estimate_weights() {\n    weight_estimates.assign(N, 0.0);\n    vector<vector<pair<int, int>>> graph(N); // adjacency list\n    vector<int> indegree(N, 0);\n    \n    // Perform pairwise comparisons\n    int comparisons_made = 0;\n    vector<pair<int, int>> pairs;\n    \n    // Generate all pairs\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            pairs.push_back({i, j});\n        }\n    }\n    \n    // Shuffle pairs to randomize\n    shuffle(pairs.begin(), pairs.end(), mt19937(random_device{}()));\n    \n    // Make as many comparisons as we can\n    int max_comparisons = min(Q, (int)pairs.size());\n    map<pair<int, int>, char> comparison_results;\n    \n    for (int i = 0; i < max_comparisons && comparisons_made < Q; i++) {\n        int a = pairs[i].first;\n        int b = pairs[i].second;\n        \n        vector<int> left = {a};\n        vector<int> right = {b};\n        string result = query(left, right);\n        comparison_results[{a, b}] = result[0];\n        comparisons_made++;\n        \n        if (result == \">\") {\n            graph[a].push_back({b, 1}); // a > b\n            indegree[b]++;\n        } else if (result == \"<\") {\n            graph[b].push_back({a, 1}); // b > a\n            indegree[a]++;\n        }\n        // For '=' we don't add edges but could use for better estimation\n    }\n    \n    // Use topological sort to assign scores\n    queue<int> q;\n    vector<int> scores(N, 0);\n    \n    // Initialize nodes with no incoming edges\n    for (int i = 0; i < N; i++) {\n        if (indegree[i] == 0) {\n            q.push(i);\n            scores[i] = 0;\n        }\n    }\n    \n    // Topological sort\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (auto& edge : graph[u]) {\n            int v = edge.first;\n            scores[v] = max(scores[v], scores[u] + 1);\n            indegree[v]--;\n            if (indegree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n    \n    // Convert scores to weight estimates\n    for (int i = 0; i < N; i++) {\n        weight_estimates[i] = scores[i];\n    }\n    \n    // Use remaining queries for more precise comparisons\n    while (comparisons_made < Q) {\n        // Compare groups to refine estimates\n        // Simple approach: compare random pairs again or compare small groups\n        if (pairs.empty()) break;\n        \n        int idx = comparisons_made % pairs.size();\n        int a = pairs[idx].first;\n        int b = pairs[idx].second;\n        \n        // Skip if already compared\n        if (comparison_results.find({a, b}) != comparison_results.end()) {\n            comparisons_made++;\n            continue;\n        }\n        \n        vector<int> left = {a};\n        vector<int> right = {b};\n        string result = query(left, right);\n        comparison_results[{a, b}] = result[0];\n        comparisons_made++;\n    }\n}\n\n// Simple greedy partitioning\nvector<int> partition_items() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Create list of items with their estimated weights\n    vector<pair<double, int>> items_with_weights;\n    for (int i = 0; i < N; i++) {\n        items_with_weights.push_back({weight_estimates[i], i});\n    }\n    \n    // Sort by weight (descending) to place heavier items first\n    sort(items_with_weights.rbegin(), items_with_weights.rend());\n    \n    // Assign items greedily\n    for (auto& item : items_with_weights) {\n        double weight = item.first;\n        int item_id = item.second;\n        \n        // Find group with minimum current sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    return assignment;\n}\n\n// Improved partitioning using local search\nvector<int> improved_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Create list of items with their estimated weights\n    vector<pair<double, int>> items_with_weights;\n    for (int i = 0; i < N; i++) {\n        items_with_weights.push_back({weight_estimates[i], i});\n    }\n    \n    // Sort by weight (descending)\n    sort(items_with_weights.rbegin(), items_with_weights.rend());\n    \n    // Initial greedy assignment\n    for (auto& item : items_with_weights) {\n        double weight = item.first;\n        int item_id = item.second;\n        \n        // Find group with minimum current sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    // Local search improvement\n    bool improved = true;\n    int iterations = 0;\n    const int MAX_ITERATIONS = 1000;\n    \n    while (improved && iterations < MAX_ITERATIONS) {\n        improved = false;\n        iterations++;\n        \n        // Try moving each item to a different group\n        for (int i = 0; i < N; i++) {\n            int current_group = assignment[i];\n            double item_weight = weight_estimates[i];\n            \n            // Try moving to each other group\n            for (int new_group = 0; new_group < D; new_group++) {\n                if (new_group == current_group) continue;\n                \n                // Calculate current variance contribution\n                double old_mean = 0;\n                for (int g = 0; g < D; g++) old_mean += group_sums[g];\n                old_mean /= D;\n                \n                double old_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    old_variance += (group_sums[g] - old_mean) * (group_sums[g] - old_mean);\n                }\n                old_variance /= D;\n                \n                // Simulate move\n                group_sums[current_group] -= item_weight;\n                group_sums[new_group] += item_weight;\n                \n                // Calculate new variance\n                double new_mean = 0;\n                for (int g = 0; g < D; g++) new_mean += group_sums[g];\n                new_mean /= D;\n                \n                double new_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    new_variance += (group_sums[g] - new_mean) * (group_sums[g] - new_mean);\n                }\n                new_variance /= D;\n                \n                // If improvement, keep the move\n                if (new_variance < old_variance) {\n                    assignment[i] = new_group;\n                    improved = true;\n                    break;\n                } else {\n                    // Revert move\n                    group_sums[current_group] += item_weight;\n                    group_sums[new_group] -= item_weight;\n                }\n            }\n            \n            if (improved) break;\n        }\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Estimate weights using balance comparisons\n    estimate_weights();\n    \n    // Partition items into D groups\n    vector<int> result = improved_partition();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        cout << result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 200;\nconst int M = 10;\nconst int STACK_SIZE = N / M;\n\nstruct State {\n    vector<deque<int>> stacks;\n    vector<pair<int, int>> box_positions; // {stack_idx, position_in_stack}\n    vector<bool> removed;\n    int total_energy = 0;\n    vector<pair<int, int>> operations;\n    \n    State() : stacks(M), box_positions(N + 1), removed(N + 1, false) {}\n    \n    void initialize() {\n        for (int i = 0; i < M; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                int box = stacks[i][j];\n                box_positions[box] = {i, j};\n            }\n        }\n    }\n    \n    bool is_top(int box) {\n        auto [stack_idx, pos] = box_positions[box];\n        return pos == (int)stacks[stack_idx].size() - 1;\n    }\n    \n    int stack_height(int stack_idx) {\n        return stacks[stack_idx].size();\n    }\n    \n    pair<int, int> find_box_position(int box) {\n        return box_positions[box];\n    }\n};\n\nclass Solver {\nprivate:\n    State state;\n    \npublic:\n    Solver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Move target box to top if not already there\n            while (!state.is_top(target)) {\n                auto [stack_idx, pos] = state.find_box_position(target);\n                int boxes_above = state.stack_height(stack_idx) - pos - 1;\n                \n                // Find best destination stack\n                int best_dest = -1;\n                int min_cost = INT_MAX;\n                \n                for (int dest = 0; dest < M; dest++) {\n                    if (dest == stack_idx) continue;\n                    \n                    // Cost is number of boxes moved + 1\n                    int cost = boxes_above + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_dest = dest;\n                    }\n                }\n                \n                if (best_dest == -1) {\n                    // Fallback: pick any different stack\n                    best_dest = (stack_idx + 1) % M;\n                }\n                \n                // Execute move\n                execute_move(target, best_dest);\n            }\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\n// Improved solver with better heuristics\nclass ImprovedSolver {\nprivate:\n    State state;\n    \npublic:\n    ImprovedSolver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Bring target to top with optimized strategy\n            bring_to_top(target);\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void bring_to_top(int target) {\n        while (!state.is_top(target)) {\n            auto [source_stack, pos] = state.find_box_position(target);\n            int boxes_above = state.stack_height(source_stack) - pos - 1;\n            \n            // Smart destination selection\n            int best_dest = find_best_destination(source_stack, boxes_above);\n            \n            // Execute move\n            execute_move(target, best_dest);\n        }\n    }\n    \n    int find_best_destination(int source_stack, int boxes_above) {\n        // Prefer stacks with fewer boxes to minimize future conflicts\n        int best_dest = -1;\n        int min_height = INT_MAX;\n        \n        for (int dest = 0; dest < M; dest++) {\n            if (dest == source_stack) continue;\n            \n            int height = state.stack_height(dest);\n            if (height < min_height) {\n                min_height = height;\n                best_dest = dest;\n            }\n        }\n        \n        // If all stacks are full, pick one that's not the source\n        if (best_dest == -1) {\n            best_dest = (source_stack + 1) % M;\n        }\n        \n        return best_dest;\n    }\n    \n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    ImprovedSolver solver(stacks);\n    vector<pair<int, int>> operations = solver.solve();\n    \n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\nbool visited[MAXN][MAXN];\n\n// Directions: Right, Down, Left, Up\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\n// Check if we can move from (i,j) to direction dir\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check for walls\n    if (dir == 0 || dir == 2) { // Horizontal move\n        return v[i][min(j, nj)] == '0';\n    } else { // Vertical move\n        return h[min(i, ni)][j] == '0';\n    }\n}\n\n// DFS with priority to high dirtiness squares\nvoid dfs_priority(int i, int j, string& path) {\n    visited[i][j] = true;\n    \n    // Create list of valid unvisited neighbors\n    vector<pair<int, int>> neighbors;\n    for (int dir = 0; dir < 4; dir++) {\n        if (!can_move(i, j, dir)) continue;\n        \n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj]) {\n            neighbors.push_back({d[ni][nj], dir});\n        }\n    }\n    \n    // Sort by dirtiness (descending)\n    sort(neighbors.begin(), neighbors.end(), greater<pair<int, int>>());\n    \n    for (auto& neighbor : neighbors) {\n        int dir = neighbor.second;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        path += dir_char[dir];\n        dfs_priority(ni, nj, path);\n        path += dir_char[(dir + 2) % 4]; // Return move\n    }\n}\n\n// Create a more sophisticated path by doing multiple DFS passes\nvoid create_path(string& path) {\n    // First, do a basic DFS to ensure all squares are visited\n    memset(visited, false, sizeof(visited));\n    dfs_priority(0, 0, path);\n    \n    // If we have space, add more visits to high-value squares\n    if (path.length() < 80000) {\n        // Add a second pass, but be more selective\n        // We could implement a more complex strategy here\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    // Read dirtiness values\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    string path = \"\";\n    create_path(path);\n    \n    // Make sure path isn't too long\n    if (path.length() > 100000) {\n        path = path.substr(0, 100000);\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\n\nint n, m;\nint start_i, start_j;\nchar grid[N][N];\nvector<string> targets;\nvector<pair<int,int>> char_positions[26];\n\n// Find all positions of each character\nvoid preprocess() {\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// Find closest position of a character from current position\npair<int, int> find_closest(char c, int cur_i, int cur_j) {\n    int best_dist = 1e9;\n    pair<int, int> best_pos = {0, 0};\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int dist = abs(pos.first - cur_i) + abs(pos.second - cur_j);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Greedy superstring construction with overlap maximization\nstring construct_superstring() {\n    vector<string> strings = targets;\n    random_shuffle(strings.begin(), strings.end());\n    \n    // Keep merging until we have a reasonable number of strings\n    while (strings.size() > 20) {\n        int max_overlap = -1;\n        int best_i = 0, best_j = 1;\n        bool best_order = true;\n        \n        // Try pairs to find maximum overlap\n        for (int i = 0; i < min(15, (int)strings.size()); i++) {\n            for (int j = i + 1; j < min(15, (int)strings.size()); j++) {\n                // Try s[i] + s[j]\n                int overlap1 = 0;\n                for (int k = 1; k <= min((int)strings[i].length(), (int)strings[j].length()); k++) {\n                    if (strings[i].substr(strings[i].length() - k) == strings[j].substr(0, k)) {\n                        overlap1 = k;\n                    }\n                }\n                \n                // Try s[j] + s[i]\n                int overlap2 = 0;\n                for (int k = 1; k <= min((int)strings[i].length(), (int)strings[j].length()); k++) {\n                    if (strings[j].substr(strings[j].length() - k) == strings[i].substr(0, k)) {\n                        overlap2 = k;\n                    }\n                }\n                \n                if (overlap1 > max_overlap) {\n                    max_overlap = overlap1;\n                    best_i = i;\n                    best_j = j;\n                    best_order = true;\n                }\n                \n                if (overlap2 > max_overlap) {\n                    max_overlap = overlap2;\n                    best_i = i;\n                    best_j = j;\n                    best_order = false;\n                }\n            }\n        }\n        \n        string merged;\n        if (best_order) {\n            merged = strings[best_i] + strings[best_j].substr(max_overlap);\n        } else {\n            merged = strings[best_j] + strings[best_i].substr(max_overlap);\n        }\n        \n        // Remove the two strings and add merged one\n        if (best_i > best_j) swap(best_i, best_j);\n        strings.erase(strings.begin() + best_j);\n        strings.erase(strings.begin() + best_i);\n        strings.push_back(merged);\n    }\n    \n    // Concatenate remaining strings\n    string result = strings[0];\n    for (int i = 1; i < strings.size(); i++) {\n        result += strings[i];\n    }\n    \n    return result;\n}\n\n// Generate path for a string\nvector<pair<int, int>> generate_path(const string& s) {\n    vector<pair<int, int>> path;\n    int cur_i = start_i, cur_j = start_j;\n    \n    for (char c : s) {\n        auto pos = find_closest(c, cur_i, cur_j);\n        path.push_back(pos);\n        cur_i = pos.first;\n        cur_j = pos.second;\n    }\n    \n    return path;\n}\n\n// Count how many targets are contained\nint count_targets(const string& s) {\n    int count = 0;\n    for (const string& target : targets) {\n        if (s.find(target) != string::npos) {\n            count++;\n        }\n    }\n    return count;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    cin >> start_i >> start_j;\n    \n    for (int i = 0; i < n; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < n; j++) {\n            grid[i][j] = line[j];\n        }\n    }\n    \n    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i];\n    }\n    \n    preprocess();\n    \n    // Construct a good superstring\n    string best_string = construct_superstring();\n    \n    // Try to improve by adding missing targets\n    vector<bool> found(m, false);\n    for (int i = 0; i < m; i++) {\n        if (best_string.find(targets[i]) == string::npos) {\n            best_string += targets[i];\n        }\n    }\n    \n    // If string is too long, try a simpler approach\n    if (best_string.length() > 1000) {\n        best_string = \"\";\n        for (int i = 0; i < min(100, m); i++) {\n            best_string += targets[i];\n        }\n    }\n    \n    // Generate path\n    auto path = generate_path(best_string);\n    \n    // Limit to 5000 operations\n    if (path.size() > 5000) {\n        path.resize(5000);\n    }\n    \n    // Output coordinates\n    for (const auto& pos : path) {\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\n#include <boost/random.hpp>\n#include <boost/random/normal_distribution.hpp>\n\nusing namespace std;\n\n// Random number generator\nboost::random::mt19937 gen;\n\nconst int MAX_N = 20;\nconst int MAX_M = 20;\n\nint N, M;\ndouble epsilon;\nvector<vector<pair<int,int>>> oil_fields;\nvector<vector<double>> prob; // Probability that each square has oil\nvector<vector<bool>> known;  // Whether we know for sure\nvector<vector<int>> actual_values; // For tracking actual values (if needed)\nint total_operations = 0;\nconst int MAX_OPERATIONS = 2 * MAX_N * MAX_N;\n\n// Normal distribution for divination errors\nboost::random::normal_distribution<> normal_dist(0.0, 1.0);\n\nvoid initialize() {\n    prob.assign(N, vector<double>(N, 0.0));\n    known.assign(N, vector<bool>(N, false));\n    actual_values.assign(N, vector<int>(N, 0));\n    \n    // Initialize with uniform probability based on field sizes\n    int total_area = 0;\n    for (const auto& field : oil_fields) {\n        total_area += field.size();\n    }\n    \n    double base_prob = min(1.0, (double)total_area / (N * N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            prob[i][j] = base_prob;\n        }\n    }\n}\n\n// Query single square\nint query_single(int i, int j) {\n    if (total_operations >= MAX_OPERATIONS) return -1;\n    \n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    total_operations++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\n// Query multiple squares\nint query_multiple(const vector<pair<int,int>>& squares) {\n    if (total_operations >= MAX_OPERATIONS) return -1;\n    if (squares.size() < 2) return -1;\n    \n    cout << \"q \" << squares.size();\n    for (const auto& sq : squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << endl;\n    cout.flush();\n    total_operations++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\n// Make a guess\nbool make_guess() {\n    vector<pair<int,int>> guess_squares;\n    \n    // Include all squares we've definitely seen have oil\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (known[i][j] && actual_values[i][j] > 0) {\n                guess_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    // Add high probability squares\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!known[i][j] && prob[i][j] > 0.3) {\n                bool already_added = false;\n                for (const auto& sq : guess_squares) {\n                    if (sq.first == i && sq.second == j) {\n                        already_added = true;\n                        break;\n                    }\n                }\n                if (!already_added) {\n                    guess_squares.push_back({i, j});\n                }\n            }\n        }\n    }\n    \n    if (guess_squares.empty()) {\n        // Fallback: guess all squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                guess_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    cout << \"a \" << guess_squares.size();\n    for (const auto& sq : guess_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << endl;\n    cout.flush();\n    total_operations++;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\n// Update probabilities based on divination result\nvoid update_probabilities(const vector<pair<int,int>>& squares, int observed_sum) {\n    // Simple heuristic: distribute the observed sum proportionally to current probabilities\n    double current_total_prob = 0;\n    for (const auto& sq : squares) {\n        current_total_prob += prob[sq.first][sq.second];\n    }\n    \n    if (current_total_prob > 0) {\n        double ratio = (double)observed_sum / max(1.0, current_total_prob);\n        ratio = max(0.0, min(2.0, ratio)); // Bound the ratio\n        \n        for (const auto& sq : squares) {\n            prob[sq.first][sq.second] *= ratio;\n            prob[sq.first][sq.second] = max(0.0, min(1.0, prob[sq.first][sq.second]));\n        }\n    }\n}\n\n// Find best divination group\nvector<pair<int,int>> find_best_divination_group(int group_size) {\n    vector<pair<int,int>> best_group;\n    double best_score = -1e9;\n    \n    // Try random groups\n    for (int attempt = 0; attempt < 100; attempt++) {\n        set<pair<int,int>> group_set;\n        vector<pair<int,int>> group;\n        \n        // Start with a random square\n        int start_i = gen() % N;\n        int start_j = gen() % N;\n        group_set.insert({start_i, start_j});\n        group.push_back({start_i, start_j});\n        \n        // Expand to nearby squares to keep it connected\n        for (int i = 1; i < group_size; i++) {\n            vector<pair<int,int>> candidates;\n            for (const auto& sq : group) {\n                for (int di = -1; di <= 1; di++) {\n                    for (int dj = -1; dj <= 1; dj++) {\n                        if (abs(di) + abs(dj) == 1) { // Adjacent\n                            int ni = sq.first + di;\n                            int nj = sq.second + dj;\n                            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                                if (group_set.find({ni, nj}) == group_set.end()) {\n                                    candidates.push_back({ni, nj});\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (!candidates.empty()) {\n                int idx = gen() % candidates.size();\n                group_set.insert(candidates[idx]);\n                group.push_back(candidates[idx]);\n            } else {\n                // If no adjacent candidates, pick any random available square\n                bool found = false;\n                for (int tries = 0; tries < 50 && !found; tries++) {\n                    int ri = gen() % N;\n                    int rj = gen() % N;\n                    if (group_set.find({ri, rj}) == group_set.end()) {\n                        group_set.insert({ri, rj});\n                        group.push_back({ri, rj});\n                        found = true;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n        \n        if ((int)group.size() == group_size) {\n            // Score based on uncertainty (high entropy regions)\n            double score = 0;\n            for (const auto& sq : group) {\n                double p = prob[sq.first][sq.second];\n                // Higher score for mid-probability squares (most uncertain)\n                score += 0.5 - abs(p - 0.5);\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_group = group;\n            }\n        }\n    }\n    \n    return best_group;\n}\n\n// Strategic exploration\nvoid explore() {\n    // Phase 1: Coarse exploration with larger groups\n    for (int group_size = min(9, N*N/4); group_size >= 4 && total_operations < MAX_OPERATIONS * 0.3; group_size--) {\n        int queries_this_size = min(5, MAX_OPERATIONS / 10);\n        for (int q = 0; q < queries_this_size && total_operations < MAX_OPERATIONS * 0.3; q++) {\n            vector<pair<int,int>> group = find_best_divination_group(group_size);\n            if (!group.empty()) {\n                int result = query_multiple(group);\n                if (result >= 0) {\n                    update_probabilities(group, result);\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Medium exploration\n    for (int q = 0; q < 20 && total_operations < MAX_OPERATIONS * 0.6; q++) {\n        vector<pair<int,int>> group = find_best_divination_group(4);\n        if (!group.empty()) {\n            int result = query_multiple(group);\n            if (result >= 0) {\n                update_probabilities(group, result);\n            }\n        }\n    }\n    \n    // Phase 3: Targeted drilling of high probability squares\n    vector<pair<double, pair<int,int>>> candidates;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!known[i][j]) {\n                candidates.push_back({-prob[i][j], {i, j}}); // Negative for sorting\n            }\n        }\n    }\n    sort(candidates.begin(), candidates.end());\n    \n    int drill_count = min(30, (int)(MAX_OPERATIONS * 0.3));\n    for (int i = 0; i < min(drill_count, (int)candidates.size()) && total_operations < MAX_OPERATIONS - 5; i++) {\n        int ci = candidates[i].second.first;\n        int cj = candidates[i].second.second;\n        \n        int result = query_single(ci, cj);\n        if (result >= 0) {\n            actual_values[ci][cj] = result;\n            known[ci][cj] = true;\n            prob[ci][cj] = (result > 0) ? 1.0 : 0.0;\n        }\n    }\n}\n\nint main() {\n    gen.seed(time(nullptr));\n    \n    // Read input\n    cin >> N >> M >> epsilon;\n    oil_fields.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        int d;\n        cin >> d;\n        oil_fields[i].resize(d);\n        for (int j = 0; j < d; j++) {\n            cin >> oil_fields[i][j].first >> oil_fields[i][j].second;\n        }\n    }\n    \n    initialize();\n    \n    // Explore strategically\n    explore();\n    \n    // Make final guess\n    bool success = make_guess();\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int W = 1000;\nconst int COST_AREA_SHORTAGE = 100;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int _i0, int _j0, int _i1, int _j1) : i0(_i0), j0(_j0), i1(_i1), j1(_j1) {}\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// Function to calculate partition changes between two days\nint calculatePartitionCost(const vector<Rectangle>& prev_day, const vector<Rectangle>& curr_day) {\n    // For simplicity, we'll approximate this\n    // In a full implementation, we'd track actual partition states\n    int cost = 0;\n    // This is a simplified approximation - in practice we'd need to track\n    // all horizontal and vertical partition segments\n    return cost;\n}\n\n// Simple strip packing algorithm\nvector<Rectangle> packRectangles(const vector<int>& areas, int strip_height = 20) {\n    vector<Rectangle> result;\n    int current_row = 0;\n    int current_col = 0;\n    \n    for (int area : areas) {\n        // Try to make rectangle as square as possible\n        int height = max(1, min(strip_height, (int)sqrt(area)));\n        while (area % height != 0) {\n            height--;\n            if (height <= 0) {\n                height = 1;\n                break;\n            }\n        }\n        int width = area / height;\n        \n        // Adjust if dimensions are too large\n        if (height > strip_height) {\n            height = strip_height;\n            width = (area + height - 1) / height; // ceil division\n        }\n        \n        // Place rectangle\n        if (current_col + width > W) {\n            current_row += strip_height;\n            current_col = 0;\n        }\n        \n        if (current_row + height <= W && current_col + width <= W) {\n            result.emplace_back(current_row, current_col, current_row + height, current_col + width);\n            current_col += width;\n        } else {\n            // Fallback: place in remaining space\n            int avail_width = W - current_col;\n            int avail_height = W - current_row;\n            if (avail_width > 0 && avail_height > 0) {\n                // Adjust to fit available space\n                height = min(height, avail_height);\n                width = min(width, avail_width);\n                result.emplace_back(current_row, current_col, current_row + height, current_col + width);\n                current_col += width;\n            } else {\n                // Last resort: small rectangle\n                result.emplace_back(0, 0, min(10, W), min(10, W));\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Improved packing that tries to satisfy area requirements\nvector<Rectangle> improvedPack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    vector<int> actual_areas(required_areas.size());\n    \n    int row_height = W / max(1, (int)sqrt(required_areas.size()));\n    row_height = max(10, min(100, row_height));\n    \n    int current_row = 0;\n    int col = 0;\n    \n    for (int k = 0; k < (int)required_areas.size(); k++) {\n        int required = required_areas[k];\n        \n        // Try to make a reasonably shaped rectangle\n        int height = max(1, (int)sqrt(required));\n        int width = (required + height - 1) / height; // ceil division\n        \n        // Adjust to make it fit better\n        while (height * width < required) {\n            if (height < width) height++;\n            else width++;\n        }\n        \n        // Make sure it fits in the grid\n        if (col + width > W) {\n            current_row += row_height;\n            col = 0;\n            // Adjust row height if needed\n            if (current_row + height > W) {\n                height = max(1, W - current_row);\n            }\n        }\n        \n        if (current_row + height > W) {\n            current_row = W - height;\n            if (current_row < 0) current_row = 0;\n        }\n        \n        if (col + width > W) {\n            col = W - width;\n            if (col < 0) col = 0;\n        }\n        \n        // Final adjustment to ensure minimum size\n        if (width <= 0) width = 1;\n        if (height <= 0) height = 1;\n        \n        result.emplace_back(current_row, col, current_row + height, col + width);\n        actual_areas[k] = height * width;\n        col += width;\n    }\n    \n    // Post-process to better satisfy area requirements\n    for (int k = 0; k < (int)result.size(); k++) {\n        int required = required_areas[k];\n        auto& rect = result[k];\n        int current_area = rect.area();\n        \n        // If we're significantly undershooting, try to expand\n        if (current_area < required) {\n            int deficit = required - current_area;\n            // Try to expand width first\n            if (rect.j1 < W) {\n                int expand_width = min(deficit / max(1, rect.i1 - rect.i0), W - rect.j1);\n                rect.j1 += expand_width;\n            }\n            // If still not enough, try to expand height\n            if (rect.area() < required && rect.i1 < W) {\n                int remaining_deficit = required - rect.area();\n                int expand_height = min(remaining_deficit / max(1, rect.j1 - rect.j0), W - rect.i1);\n                rect.i1 += expand_height;\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Strategy: Try to maintain similar layouts across days to minimize partition changes\nvector<vector<Rectangle>> solve(const vector<vector<int>>& all_areas) {\n    int D = all_areas.size();\n    vector<vector<Rectangle>> result(D);\n    \n    // For day 0, use improved packing\n    result[0] = improvedPack(all_areas[0]);\n    \n    // For subsequent days, try to maintain similar structure\n    for (int d = 1; d < D; d++) {\n        result[d] = improvedPack(all_areas[d]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    \n    vector<vector<int>> all_areas(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> all_areas[d][k];\n        }\n    }\n    \n    // Solve\n    auto solution = solve(all_areas);\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << solution[d][k].i0 << \" \" << solution[d][k].j0 << \" \" \n                 << solution[d][k].i1 << \" \" << solution[d][k].j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint N = 9, M = 20, K = 81;\nlong long a[9][9];\nlong long s[20][3][3];\n\nstruct Operation {\n    int stamp, row, col;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> K;\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 (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n    \n    // Keep track of actual values (not modded yet)\n    long long board[9][9];\n    for (int i = 0; i < 9; i++) {\n        for (int j = 0; j < 9; j++) {\n            board[i][j] = a[i][j];\n        }\n    }\n    \n    vector<Operation> operations;\n    \n    // Simple strategy: Cover the board with non-overlapping 3x3 regions\n    // There are 9 such regions in a 9x9 grid\n    int stamp_regions = 0;\n    \n    for (int base_r = 0; base_r < 9; base_r += 3) {\n        for (int base_c = 0; base_c < 9; base_c += 3) {\n            if (stamp_regions >= K) break;\n            \n            // Find the best stamp for this region\n            long long best_increase = -1;\n            int best_stamp = 0;\n            \n            for (int stamp = 0; stamp < M; stamp++) {\n                long long increase = 0;\n                for (int i = 0; i < 3; i++) {\n                    for (int j = 0; j < 3; j++) {\n                        increase += s[stamp][i][j];\n                    }\n                }\n                \n                if (increase > best_increase) {\n                    best_increase = increase;\n                    best_stamp = stamp;\n                }\n            }\n            \n            // Apply the best stamp\n            operations.push_back({best_stamp, base_r, base_c});\n            \n            // Update board values\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[base_r + i][base_c + j] += s[best_stamp][i][j];\n                }\n            }\n            \n            stamp_regions++;\n        }\n        if (stamp_regions >= K) break;\n    }\n    \n    // Output result\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << op.stamp << \" \" << op.row << \" \" << op.col << \"\\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 container_to_row[N*N];\nvector<vector<int>> A(N, vector<int>(N));\nvector<string> result(N);\n\nvoid precompute() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            container_to_row[i * N + j] = i;\n        }\n    }\n}\n\n// Simple but effective strategy\nvoid solve() {\n    precompute();\n    \n    // Read input\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Greedy strategy: each crane processes its row\n    // Crane 0 (large) can help with complex movements\n    \n    for (int turn = 0; turn < 500; turn++) {\n        for (int crane = 0; crane < N; crane++) {\n            // Simple strategy: move right, pick up containers, move to right edge, drop off\n            if (turn * 2 < crane * 10) {\n                // Initial waiting period\n                result[crane] += '.';\n            } else if (turn < 100) {\n                // Movement pattern\n                int phase = (turn - crane * 5) % 20;\n                if (phase < 4) {\n                    result[crane] += 'R';\n                } else if (phase == 4) {\n                    result[crane] += 'P'; // Pick up\n                } else if (phase < 9) {\n                    result[crane] += 'R';\n                } else if (phase == 9) {\n                    result[crane] += 'Q'; // Drop off\n                } else if (phase < 14) {\n                    result[crane] += 'L';\n                } else {\n                    result[crane] += '.';\n                }\n            } else {\n                result[crane] += '.';\n            }\n        }\n    }\n    \n    // Ensure minimum length\n    int max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, (int)result[i].length());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (result[i].length() < max_len) {\n            result[i] += '.';\n        }\n        if (result[i].empty()) result[i] = \".\";\n        cout << result[i] << \"\\n\";\n    }\n}\n\nint main() {\n    solve();\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nstruct Cell {\n    int x, y, amount;\n    bool operator<(const Cell& other) const {\n        return amount > other.amount; // For priority queue, larger first\n    }\n};\n\n// Manhattan distance\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Get moves to go from (x1,y1) to (x2,y2)\nvector<string> get_path(int x1, int y1, int x2, int y2) {\n    vector<string> moves;\n    while (x1 < x2) {\n        moves.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        moves.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        moves.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        moves.push_back(\"L\");\n        y1--;\n    }\n    return moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<int>> grid(n, vector<int>(n));\n    vector<pair<int, int>> sources, sinks;\n    vector<int> source_amount, sink_amount;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n            if (grid[i][j] > 0) {\n                sources.push_back({i, j});\n                source_amount.push_back(grid[i][j]);\n            } else if (grid[i][j] < 0) {\n                sinks.push_back({i, j});\n                sink_amount.push_back(-grid[i][j]);\n            }\n        }\n    }\n    \n    vector<string> result;\n    int curr_x = 0, curr_y = 0;\n    \n    // Simple greedy pairing: pair each source with nearest sink\n    vector<bool> sink_used(sinks.size(), false);\n    \n    for (int i = 0; i < sources.size(); i++) {\n        auto [sx, sy] = sources[i];\n        int amount = source_amount[i];\n        \n        // Find nearest unused sink\n        int best_sink = -1;\n        int best_dist = 1e9;\n        \n        for (int j = 0; j < sinks.size(); j++) {\n            if (!sink_used[j]) {\n                auto [tx, ty] = sinks[j];\n                int dist = manhattan(sx, sy, tx, ty);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_sink = j;\n                }\n            }\n        }\n        \n        if (best_sink == -1) continue;\n        \n        auto [tx, ty] = sinks[best_sink];\n        int sink_amt = sink_amount[best_sink];\n        sink_used[best_sink] = true;\n        \n        // Go to source\n        if (curr_x != sx || curr_y != sy) {\n            auto moves = get_path(curr_x, curr_y, sx, sy);\n            result.insert(result.end(), moves.begin(), moves.end());\n            curr_x = sx;\n            curr_y = sy;\n        }\n        \n        // Load all soil from source\n        result.push_back(\"+\" + to_string(amount));\n        \n        // Go to sink\n        if (curr_x != tx || curr_y != ty) {\n            auto moves = get_path(curr_x, curr_y, tx, ty);\n            result.insert(result.end(), moves.begin(), moves.end());\n            curr_x = tx;\n            curr_y = ty;\n        }\n        \n        // Unload all soil to sink\n        result.push_back(\"-\" + to_string(amount));\n    }\n    \n    // Output results\n    for (const string& s : result) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int SEED_COUNT = 2 * N * (N - 1); // 72\n\n// Structure to hold seed information\nstruct Seed {\n    int id;\n    vector<int> values;\n    int total_value;\n    \n    Seed() : id(0), values(M, 0), total_value(0) {}\n    \n    Seed(int _id, const vector<int>& _values) : id(_id), values(_values) {\n        total_value = accumulate(values.begin(), values.end(), 0);\n    }\n};\n\n// Calculate distance between two seeds (for clustering similar seeds)\nint seedDistance(const Seed& a, const Seed& b) {\n    int dist = 0;\n    for (int i = 0; i < M; i++) {\n        dist += abs(a.values[i] - b.values[i]);\n    }\n    return dist;\n}\n\n// Greedy placement strategy\nvector<vector<int>> placeSeedsGreedy(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Take top N*N seeds\n    vector<Seed> top_seeds(seeds.begin(), seeds.begin() + N * N);\n    \n    // Simple placement: put highest value seeds in center area\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    // Sort positions by distance from center (place better seeds more centrally)\n    pair<int, int> center = {N/2, N/2};\n    sort(positions.begin(), positions.end(), [&center](const pair<int, int>& a, const pair<int, int>& b) {\n        int dist_a = abs(a.first - center.first) + abs(a.second - center.second);\n        int dist_b = abs(b.first - center.first) + abs(b.second - center.second);\n        return dist_a < dist_b;\n    });\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = top_seeds[i].id;\n    }\n    \n    return grid;\n}\n\n// Alternative placement: try to group similar high-value seeds\nvector<vector<int>> placeSeedsClustered(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Take top N*N seeds\n    vector<Seed> top_seeds(seeds.begin(), seeds.begin() + N * N);\n    \n    // Try to place similar seeds adjacent to each other\n    vector<bool> placed(N * N, false);\n    int placed_count = 0;\n    \n    // Start with the best seed in the center\n    grid[N/2][N/2] = top_seeds[0].id;\n    placed[0] = true;\n    placed_count++;\n    \n    // For remaining positions, try to place seeds similar to neighbors\n    vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    \n    while (placed_count < N * N) {\n        bool placed_something = false;\n        \n        // Look for an empty cell adjacent to a filled cell\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == -1) { // Empty cell\n                    // Check if it's adjacent to a filled cell\n                    for (auto& dir : directions) {\n                        int ni = i + dir.first;\n                        int nj = j + dir.second;\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                            // Found adjacent filled cell, find best seed to place here\n                            int best_seed_idx = -1;\n                            int best_similarity = -1;\n                            \n                            for (int s = 0; s < N * N; s++) {\n                                if (!placed[s]) {\n                                    int similarity = -seedDistance(top_seeds[s], \n                                        seeds[grid[ni][nj]]); // Negative because we want min distance\n                                    if (similarity > best_similarity) {\n                                        best_similarity = similarity;\n                                        best_seed_idx = s;\n                                    }\n                                }\n                            }\n                            \n                            if (best_seed_idx != -1) {\n                                grid[i][j] = top_seeds[best_seed_idx].id;\n                                placed[best_seed_idx] = true;\n                                placed_count++;\n                                placed_something = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (placed_something) break;\n                }\n            }\n            if (placed_something) break;\n        }\n        \n        // If we couldn't place anything, just fill sequentially\n        if (!placed_something) {\n            for (int i = 0; i < N * N; i++) {\n                if (!placed[i]) {\n                    // Find first empty spot\n                    for (int r = 0; r < N; r++) {\n                        for (int c = 0; c < N; c++) {\n                            if (grid[r][c] == -1) {\n                                grid[r][c] = top_seeds[i].id;\n                                placed[i] = true;\n                                placed_count++;\n                                break;\n                            }\n                        }\n                        if (placed[i]) break;\n                    }\n                }\n            }\n        }\n    }\n    \n    return grid;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N_input, M_input, T;\n    cin >> N_input >> M_input >> T;\n    \n    vector<Seed> seeds(SEED_COUNT);\n    \n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; i++) {\n        vector<int> values(M);\n        for (int j = 0; j < M; j++) {\n            cin >> values[j];\n        }\n        seeds[i] = Seed(i, values);\n    }\n    \n    // Process each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Place seeds on grid\n        vector<vector<int>> grid = placeSeedsGreedy(seeds);\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            vector<int> values(M);\n            for (int j = 0; j < M; j++) {\n                cin >> values[j];\n            }\n            seeds[i] = Seed(i, values);\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 30;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'R', 'D', 'L', 'U'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Edge {\n    int parent, length;\n    Edge() : parent(0), length(0) {}\n    Edge(int p, int l) : parent(p), length(l) {}\n};\n\nclass Solution {\npublic:\n    int N, M, V;\n    vector<vector<int>> source, target;\n    \n    Solution(int n, int m, int v) : N(n), M(m), V(v) {\n        source.assign(N, vector<int>(N, 0));\n        target.assign(N, vector<int>(N, 0));\n    }\n    \n    void read_input() {\n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                source[i][j] = line[j] - '0';\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    void design_arm() {\n        // Create a star-like tree with root at center\n        int num_edges = min(V - 1, 8);\n        \n        cout << num_edges + 1 << endl; // Number of vertices\n        \n        // Create edges from root (0) to fingertips\n        for (int i = 1; i <= num_edges; i++) {\n            cout << 0 << \" \" << 1 << endl; // parent, length\n        }\n        \n        // Initial root position\n        cout << N/2 << \" \" << N/2 << endl;\n    }\n    \n    int manhattan_distance(int x1, int y1, int x2, int y2) {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    vector<pair<int, int>> get_positions_to_visit() {\n        vector<pair<int, int>> positions;\n        \n        // Collect source positions (where takoyaki are)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        return positions;\n    }\n    \n    void solve() {\n        read_input();\n        design_arm();\n        \n        // Simple greedy approach\n        vector<pair<int, int>> sources, targets;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1 && target[i][j] == 0) {\n                    sources.push_back({i, j});\n                }\n                if (target[i][j] == 1 && source[i][j] == 0) {\n                    targets.push_back({i, j});\n                }\n            }\n        }\n        \n        // For demonstration, just do random moves\n        int root_x = N/2, root_y = N/2;\n        vector<bool> held(min(V, 9), false);\n        \n        for (int turn = 0; turn < 2000; turn++) {\n            string command(2 * min(V, 9), '.');\n            \n            // Move root randomly but stay in bounds\n            int dir = rand() % 5;\n            if (dir < 4) {\n                int nx = root_x + dx[dir];\n                int ny = root_y + dy[dir];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    root_x = nx;\n                    root_y = ny;\n                    command[0] = dir_char[dir];\n                }\n            }\n            \n            // Check if we can pick up or drop takoyaki\n            for (int finger = 1; finger < min(V, 9); finger++) {\n                int fx = root_x;\n                int fy = root_y + finger; // Simple positioning\n                \n                if (fx >= 0 && fx < N && fy >= 0 && fy < N) {\n                    // Try to pick up\n                    if (!held[finger] && source[fx][fy] == 1 && target[fx][fy] == 0) {\n                        source[fx][fy] = 0;\n                        held[finger] = true;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                    // Try to drop\n                    else if (held[finger] && source[fx][fy] == 0 && target[fx][fy] == 1) {\n                        source[fx][fy] = 1;\n                        held[finger] = false;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(time(nullptr));\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    Solution solution(N, M, V);\n    solution.solve();\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 5000;\nconst int MAX_COORD = 100000;\nconst int MAX_VERTICES = 1000;\nconst long long MAX_PERIMETER = 400000LL;\n\nstruct Point {\n    int x, y;\n    bool is_mackerel; // true for mackerel, false for sardine\n    \n    Point() : x(0), y(0), is_mackerel(false) {}\n    Point(int _x, int _y, bool _is_mackerel) : x(_x), y(_y), is_mackerel(_is_mackerel) {}\n    \n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n};\n\n// Rectangle representation\nstruct Rectangle {\n    int x1, y1, x2, y2; // bottom-left (x1,y1), top-right (x2,y2)\n    \n    Rectangle() : x1(0), y1(0), x2(0), y2(0) {}\n    Rectangle(int _x1, int _y1, int _x2, int _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {}\n    \n    long long perimeter() const {\n        return 2LL * (abs(x2 - x1) + abs(y2 - y1));\n    }\n    \n    long long area() const {\n        return 1LL * abs(x2 - x1) * abs(y2 - y1);\n    }\n};\n\nvector<Point> points;\nvector<Point> mackerels, sardines;\n\n// Count points in rectangle\npair<int, int> countPointsInRect(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    for (const auto& p : points) {\n        if (p.x >= rect.x1 && p.x <= rect.x2 && p.y >= rect.y1 && p.y <= rect.y2) {\n            if (p.is_mackerel) {\n                mackerel_count++;\n            } else {\n                sardine_count++;\n            }\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\n// Calculate score for rectangle\nint calculateScore(const Rectangle& rect) {\n    auto [m, s] = countPointsInRect(rect);\n    return max(0, m - s + 1);\n}\n\n// Generate a simple rectangle solution\nvector<pair<int, int>> generateRectangleSolution() {\n    // Try different approaches and pick the best one\n    \n    // Approach 1: Bounding box of all mackerels\n    int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n    for (const auto& p : mackerels) {\n        min_x = min(min_x, p.x);\n        max_x = max(max_x, p.x);\n        min_y = min(min_y, p.y);\n        max_y = max(max_y, p.y);\n    }\n    \n    Rectangle bbox(min_x, min_y, max_x, max_y);\n    int bbox_score = calculateScore(bbox);\n    \n    // Approach 2: Try expanding bounding box strategically\n    vector<Rectangle> candidates;\n    \n    // Add some padding\n    int pad = 100;\n    Rectangle padded(\n        max(0, min_x - pad),\n        max(0, min_y - pad),\n        min(MAX_COORD, max_x + pad),\n        min(MAX_COORD, max_y + pad)\n    );\n    candidates.push_back(padded);\n    \n    // Try different sized rectangles centered around mackerel clusters\n    // Simple clustering approach\n    if (!mackerels.empty()) {\n        sort(mackerels.begin(), mackerels.end());\n        \n        // Take a sample of mackerels and create rectangles around them\n        for (int i = 0; i < min(50, (int)mackerels.size()); i += 5) {\n            int center_x = mackerels[i].x;\n            int center_y = mackerels[i].y;\n            \n            int size = 5000;\n            Rectangle rect(\n                max(0, center_x - size),\n                max(0, center_y - size),\n                min(MAX_COORD, center_x + size),\n                min(MAX_COORD, center_y + size)\n            );\n            candidates.push_back(rect);\n        }\n    }\n    \n    // Find best candidate\n    Rectangle best_rect = bbox;\n    int best_score = bbox_score;\n    \n    for (const auto& rect : candidates) {\n        int score = calculateScore(rect);\n        if (score > best_score) {\n            best_score = score;\n            best_rect = rect;\n        }\n    }\n    \n    // Convert rectangle to polygon (counter-clockwise)\n    vector<pair<int, int>> polygon;\n    polygon.push_back({best_rect.x1, best_rect.y1});\n    polygon.push_back({best_rect.x2, best_rect.y1});\n    polygon.push_back({best_rect.x2, best_rect.y2});\n    polygon.push_back({best_rect.x1, best_rect.y2});\n    \n    return polygon;\n}\n\n// Improve solution by trying to remove sardines\nvector<pair<int, int>> improveSolution(const vector<pair<int, int>>& initial_polygon) {\n    if (initial_polygon.size() < 4) return initial_polygon;\n    \n    // For now, just return the initial solution\n    // More sophisticated improvement could be added here\n    return initial_polygon;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    points.reserve(2 * N);\n    mackerels.reserve(N);\n    sardines.reserve(N);\n    \n    // Read mackerels\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, true);\n        points.push_back(p);\n        mackerels.push_back(p);\n    }\n    \n    // Read sardines\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, false);\n        points.push_back(p);\n        sardines.push_back(p);\n    }\n    \n    // Generate initial solution\n    auto polygon = generateRectangleSolution();\n    \n    // Improve solution\n    polygon = improveSolution(polygon);\n    \n    // Output result\n    cout << polygon.size() << \"\\n\";\n    for (const auto& vertex : polygon) {\n        cout << vertex.first << \" \" << vertex.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Random number generator\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Utility functions\ninline double random_double() {\n    return uniform_real_distribution<double>(0, 1)(rng);\n}\n\ninline int random_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rectangle {\n    int w, h;\n    int idx;\n    \n    Rectangle() : w(0), h(0), idx(0) {}\n    Rectangle(int _w, int _h, int _idx) : w(_w), h(_h), idx(_idx) {}\n    \n    long long area() const { return 1LL * w * h; }\n    int perimeter() const { return w + h; }\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n    \n    Placement(int _p, int _r, char _d, int _b) : p(_p), r(_r), d(_d), b(_b) {}\n};\n\nclass Packer {\nprivate:\n    int N, T, sigma;\n    vector<Rectangle> rectangles;\n    vector<Rectangle> true_rectangles; // For estimation\n    \npublic:\n    Packer() {\n        cin >> N >> T >> sigma;\n        rectangles.resize(N);\n        true_rectangles.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            int w, h;\n            cin >> w >> h;\n            rectangles[i] = Rectangle(w, h, i);\n            true_rectangles[i] = Rectangle(w, h, i);\n        }\n    }\n    \n    // Simple skyline-based packing algorithm\n    vector<Placement> skyLinePacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Start with first rectangle at origin\n        int first_idx = selected_indices[0];\n        placements.emplace_back(first_idx, 0, 'U', -1);\n        \n        // For remaining rectangles, try to place them optimally\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            \n            // Randomly decide rotation\n            int rotate = random_int(0, 1);\n            \n            // Randomly decide direction and base\n            char dir = (random_int(0, 1) == 0) ? 'U' : 'L';\n            int base = random_int(-1, i - 1);\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Corner-based packing\n    vector<Placement> cornerPacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle\n        int first_idx = selected_indices[0];\n        placements.emplace_back(first_idx, random_int(0, 1), 'U', -1);\n        \n        // Try to fill corners\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            \n            // Prefer corner filling\n            char dir = (random_double() < 0.7) ? 'U' : 'L';\n            int base = random_int(-1, min(i - 1, 3)); // Prefer recent placements for corners\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Greedy approach: select largest rectangles first\n    vector<int> selectLargeRectangles(int max_count) {\n        vector<pair<long long, int>> areas;\n        for (int i = 0; i < N; i++) {\n            areas.emplace_back(rectangles[i].area(), i);\n        }\n        \n        sort(areas.rbegin(), areas.rend());\n        \n        vector<int> selected;\n        int count = min(max_count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(areas[i].second);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n    \n    // Select middle-sized rectangles\n    vector<int> selectMiddleRectangles(int max_count) {\n        vector<pair<int, int>> perimeters;\n        for (int i = 0; i < N; i++) {\n            perimeters.emplace_back(rectangles[i].perimeter(), i);\n        }\n        \n        sort(perimeters.begin(), perimeters.end());\n        \n        vector<int> selected;\n        int start = N / 4;\n        int end = min(start + max_count, N);\n        \n        for (int i = start; i < end; i++) {\n            selected.push_back(perimeters[i].second);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n    \n    // Random selection\n    vector<int> selectRandom(int count) {\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        \n        shuffle(indices.begin(), indices.end(), rng);\n        \n        vector<int> selected;\n        count = min(count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(indices[i]);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n    \n    void run() {\n        vector<vector<Placement>> strategies;\n        \n        for (int t = 0; t < T; t++) {\n            vector<Placement> best_placement;\n            \n            // Strategy 1: All rectangles, skyline packing\n            if (t < T/3) {\n                vector<int> all_indices(N);\n                iota(all_indices.begin(), all_indices.end(), 0);\n                best_placement = skyLinePacking(all_indices);\n            }\n            // Strategy 2: Large rectangles only\n            else if (t < 2*T/3) {\n                int count = max(N/2, 10);\n                vector<int> large = selectLargeRectangles(count);\n                best_placement = cornerPacking(large);\n            }\n            // Strategy 3: Random selection\n            else {\n                int count = max(N/2, 15);\n                vector<int> random_sel = selectRandom(count);\n                best_placement = skyLinePacking(random_sel);\n            }\n            \n            // Output placement\n            cout << best_placement.size() << \"\\n\";\n            for (const auto& p : best_placement) {\n                cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n            }\n            cout.flush();\n            \n            // Read measurement result\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n            \n            // Update our estimates based on feedback (simple approach)\n            // In a more sophisticated solution, we'd maintain probabilistic models\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.run();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int MAXH = 10;\n\nint N, M, H;\nvector<int> beauty;\nvector<vector<int>> adj;\nvector<pair<int, int>> coords;\nvector<int> parent;\n\n// Structure to represent a tree node with its level\nstruct TreeNode {\n    int vertex;\n    int level;\n    TreeNode(int v, int l) : vertex(v), level(l) {}\n};\n\n// Compare function to prioritize high beauty vertices\nstruct BeautyComparator {\n    bool operator()(int a, int b) const {\n        return beauty[a] < beauty[b]; // Max heap - higher beauty first\n    }\n};\n\nvoid solve() {\n    // Initialize parent array\n    parent.assign(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Priority queue for unassigned vertices (highest beauty first)\n    priority_queue<pair<int, int>> vertex_queue;\n    for (int i = 0; i < N; i++) {\n        vertex_queue.push({beauty[i], i});\n    }\n    \n    // Build trees until all vertices are assigned\n    while (!vertex_queue.empty()) {\n        // Find the highest beauty unassigned vertex\n        int root_vertex = -1;\n        while (!vertex_queue.empty()) {\n            auto [beauty_val, vertex] = vertex_queue.top();\n            vertex_queue.pop();\n            if (!assigned[vertex]) {\n                root_vertex = vertex;\n                break;\n            }\n        }\n        \n        if (root_vertex == -1) break; // All vertices assigned\n        \n        // Create new tree with this vertex as root\n        assigned[root_vertex] = true;\n        parent[root_vertex] = -1;\n        \n        // BFS to build the tree level by level\n        queue<TreeNode> bfs_queue;\n        bfs_queue.push(TreeNode(root_vertex, 0));\n        \n        // For each level, collect candidates for next level\n        while (!bfs_queue.empty() && bfs_queue.front().level < H) {\n            int current_level = bfs_queue.front().level;\n            vector<TreeNode> current_level_nodes;\n            \n            // Collect all nodes at current level\n            while (!bfs_queue.empty() && bfs_queue.front().level == current_level) {\n                current_level_nodes.push_back(bfs_queue.front());\n                bfs_queue.pop();\n            }\n            \n            // Collect all unassigned neighbors of current level nodes\n            vector<pair<int, int>> candidates; // {beauty, vertex}\n            vector<int> candidate_parents;\n            \n            for (const auto& node : current_level_nodes) {\n                for (int neighbor : adj[node.vertex]) {\n                    if (!assigned[neighbor]) {\n                        candidates.push_back({beauty[neighbor], neighbor});\n                        candidate_parents.push_back(node.vertex);\n                    }\n                }\n            }\n            \n            // Sort candidates by beauty (descending)\n            vector<pair<pair<int, int>, int>> candidate_info;\n            for (int i = 0; i < (int)candidates.size(); i++) {\n                candidate_info.push_back({candidates[i], candidate_parents[i]});\n            }\n            sort(candidate_info.begin(), candidate_info.end(), \n                 [](const auto& a, const auto& b) {\n                     return a.first.first > b.first.first; // Higher beauty first\n                 });\n            \n            // Assign best candidates to next level\n            int next_level = current_level + 1;\n            int assigned_count = 0;\n            for (const auto& info : candidate_info) {\n                if (assigned_count >= 20) break; // Limit to avoid over-expansion\n                int vertex = info.first.second;\n                int parent_vertex = info.second;\n                \n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    parent[vertex] = parent_vertex;\n                    bfs_queue.push(TreeNode(vertex, next_level));\n                    assigned_count++;\n                }\n            }\n        }\n    }\n}\n\n// Alternative greedy approach focusing on local optimization\nvoid solve_optimized() {\n    parent.assign(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Priority queue for unassigned vertices\n    priority_queue<pair<int, int>> pq;\n    for (int i = 0; i < N; i++) {\n        pq.push({beauty[i], i});\n    }\n    \n    while (!pq.empty()) {\n        // Get highest beauty unassigned vertex\n        int best_vertex = -1;\n        while (!pq.empty()) {\n            auto [b, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                best_vertex = v;\n                break;\n            }\n        }\n        \n        if (best_vertex == -1) break;\n        \n        // Make it a root\n        assigned[best_vertex] = true;\n        parent[best_vertex] = -1;\n        \n        // Build tree using BFS with priority to high beauty vertices\n        vector<vector<int>> tree_levels(H + 1);\n        tree_levels[0].push_back(best_vertex);\n        \n        for (int level = 0; level < H; level++) {\n            // Collect all unassigned neighbors of current level\n            vector<pair<int, int>> candidates; // {beauty, vertex}\n            map<int, int> best_parent; // vertex -> parent\n            \n            for (int u : tree_levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        if (best_parent.find(v) == best_parent.end() || beauty[u] > beauty[best_parent[v]]) {\n                            best_parent[v] = u;\n                        }\n                        candidates.push_back({beauty[v], v});\n                    }\n                }\n            }\n            \n            // Sort by beauty and assign top ones\n            sort(candidates.begin(), candidates.end(), greater<pair<int, int>>());\n            \n            int count = 0;\n            for (auto& [b, v] : candidates) {\n                if (count >= 15) break; // Limit per level\n                if (!assigned[v]) {\n                    assigned[v] = true;\n                    parent[v] = best_parent[v];\n                    tree_levels[level + 1].push_back(v);\n                    count++;\n                }\n            }\n            \n            if (tree_levels[level + 1].empty()) break;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> H;\n    \n    beauty.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> beauty[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    solve_optimized();\n    \n    for (int i = 0; i < N; i++) {\n        cout << parent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nstruct OniInfo {\n    int row, col;\n    char direction; // 'U', 'D', 'L', 'R'\n    int moves;\n};\n\n// Check if column j has any Fukunokami above row i\nbool hasFukuAbove(vector<vector<char>>& board, int i, int j) {\n    for (int r = 0; r < i; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if column j has any Fukunokami below row i\nbool hasFukuBelow(vector<vector<char>>& board, int i, int j) {\n    for (int r = i + 1; r < N; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the left of column j\nbool hasFukuLeft(vector<vector<char>>& board, int i, int j) {\n    for (int c = 0; c < j; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the right of column j\nbool hasFukuRight(vector<vector<char>>& board, int i, int j) {\n    for (int c = j + 1; c < N; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Find best direction to remove Oni at (i,j)\nOniInfo findBestDirection(vector<vector<char>>& board, int i, int j) {\n    OniInfo best = {i, j, 'U', N}; // default with high cost\n    \n    // Check up\n    if (!hasFukuAbove(board, i, j)) {\n        if (i < best.moves) {\n            best.direction = 'U';\n            best.moves = i;\n        }\n    }\n    \n    // Check down\n    if (!hasFukuBelow(board, i, j)) {\n        int moves = N - 1 - i;\n        if (moves < best.moves) {\n            best.direction = 'D';\n            best.moves = moves;\n        }\n    }\n    \n    // Check left\n    if (!hasFukuLeft(board, i, j)) {\n        if (j < best.moves) {\n            best.direction = 'L';\n            best.moves = j;\n        }\n    }\n    \n    // Check right\n    if (!hasFukuRight(board, i, j)) {\n        int moves = N - 1 - j;\n        if (moves < best.moves) {\n            best.direction = 'R';\n            best.moves = moves;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    vector<vector<char>> board(N, vector<char>(N));\n    vector<pair<int, int>> oniPositions;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            board[i][j] = line[j];\n            if (line[j] == 'x') {\n                oniPositions.push_back({i, j});\n            }\n        }\n    }\n    \n    vector<OniInfo> oniInfos;\n    \n    // Find best direction for each Oni\n    for (auto& pos : oniPositions) {\n        int i = pos.first, j = pos.second;\n        OniInfo info = findBestDirection(board, i, j);\n        oniInfos.push_back(info);\n    }\n    \n    // Sort by moves needed (greedy approach)\n    sort(oniInfos.begin(), oniInfos.end(), [](const OniInfo& a, const OniInfo& b) {\n        return a.moves < b.moves;\n    });\n    \n    vector<pair<char, int>> moves;\n    \n    // Process each Oni\n    for (const auto& oni : oniInfos) {\n        int i = oni.row, j = oni.col;\n        char dir = oni.direction;\n        int numMoves = oni.moves;\n        \n        if (dir == 'U') {\n            // Move up: shift column j upward numMoves times\n            for (int k = 0; k < numMoves; k++) {\n                moves.push_back({'U', j});\n            }\n        } else if (dir == 'D') {\n            // Move down: shift column j downward numMoves times\n            for (int k = 0; k < numMoves; k++) {\n                moves.push_back({'D', j});\n            }\n        } else if (dir == 'L') {\n            // Move left: shift row i left numMoves times\n            for (int k = 0; k < numMoves; k++) {\n                moves.push_back({'L', i});\n            }\n        } else if (dir == 'R') {\n            // Move right: shift row i right numMoves times\n            for (int k = 0; k < numMoves; k++) {\n                moves.push_back({'R', i});\n            }\n        }\n    }\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\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 target[N];\nint a[N], b[N];\nint actual[N];\n\n// Simulate the cleaning process to compute actual counts\nvoid simulate() {\n    fill(actual, actual + N, 0);\n    \n    int current = 0;\n    vector<int> count(N, 0);\n    \n    for (int week = 0; week < L; week++) {\n        actual[current]++;\n        count[current]++;\n        \n        if (count[current] % 2 == 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n    }\n}\n\n// Calculate error\nint calculate_error() {\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(actual[i] - target[i]);\n    }\n    return error;\n}\n\n// Initialize a and b arrays\nvoid initialize() {\n    // Create a rough approximation using greedy approach\n    vector<pair<int, int>> employees;\n    for (int i = 0; i < N; i++) {\n        employees.push_back({target[i], i});\n    }\n    \n    // Sort by target frequency (descending)\n    sort(employees.rbegin(), employees.rend());\n    \n    // Assign transitions to try to balance load\n    for (int i = 0; i < N; i++) {\n        int idx = employees[i].second;\n        // Point to employees with lower targets to distribute load\n        int next_idx1 = employees[(i + 1) % N].second;\n        int next_idx2 = employees[(i + 2) % N].second;\n        \n        a[idx] = next_idx1;\n        b[idx] = next_idx2;\n    }\n}\n\n// Improve the solution using local search\nvoid optimize() {\n    // Try swapping transitions to reduce error\n    for (int iter = 0; iter < 1000; iter++) {\n        simulate();\n        int current_error = calculate_error();\n        \n        // Try random swaps\n        int emp = rand() % N;\n        int choice = rand() % 2;\n        int old_val = (choice == 0) ? a[emp] : b[emp];\n        int new_val = rand() % N;\n        \n        if (choice == 0) {\n            a[emp] = new_val;\n        } else {\n            b[emp] = new_val;\n        }\n        \n        simulate();\n        int new_error = calculate_error();\n        \n        // Accept improvement or revert with some probability\n        if (new_error <= current_error) {\n            // Keep the change\n        } else {\n            // Revert with probability based on temperature\n            if (rand() % 100 < 10) {\n                // Keep it anyway sometimes\n            } else {\n                if (choice == 0) {\n                    a[emp] = old_val;\n                } else {\n                    b[emp] = old_val;\n                }\n            }\n        }\n    }\n}\n\n// Better initialization based on target distribution\nvoid smart_initialize() {\n    // For each employee, set a and b to point to employees \n    // that help balance the distribution\n    \n    // Simple approach: point to employees in a round-robin fashion\n    // but weighted by inverse of their targets\n    \n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    \n    // Sort indices by target (ascending - those needing more should be pointed to)\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return target[i] < target[j];\n    });\n    \n    for (int i = 0; i < N; i++) {\n        // Point to employees that need more assignments\n        a[i] = indices[(i + 1) % N];\n        b[i] = indices[(i + 2) % N];\n    }\n}\n\n// Even smarter approach: try to create cycles that match target distribution\nvoid cycle_based_initialize() {\n    // Create a more sophisticated assignment\n    \n    // Make sure everyone points somewhere\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    \n    // But adjust based on targets\n    // Employees with high targets should be pointed to more often\n    vector<pair<int, int>> target_pairs;\n    for (int i = 0; i < N; i++) {\n        target_pairs.push_back({target[i], i});\n    }\n    \n    sort(target_pairs.begin(), target_pairs.end());\n    \n    // Redistribute edges to favor high-target employees\n    for (int i = 0; i < N; i++) {\n        int from = target_pairs[i].second;\n        int to_high = target_pairs[(i + N/2) % N].second;\n        int to_medium = target_pairs[(i + N/4) % N].second;\n        \n        // With some probability, point to high-target employees\n        if (rand() % 3 == 0) {\n            a[from] = to_high;\n        }\n        if (rand() % 3 == 0) {\n            b[from] = to_medium;\n        }\n    }\n}\n\nint main() {\n    srand(time(nullptr));\n    \n    int dummy_L;\n    cin >> dummy_L >> dummy_L;\n    for (int i = 0; i < N; i++) {\n        cin >> target[i];\n    }\n    \n    // Initialize with a reasonable strategy\n    cycle_based_initialize();\n    \n    // Do some local optimization\n    for (int iter = 0; iter < 500; iter++) {\n        simulate();\n        int current_error = calculate_error();\n        \n        // Pick a random employee and modify their transitions\n        int emp = rand() % N;\n        int which = rand() % 2;\n        int old_val = (which == 0) ? a[emp] : b[emp];\n        int new_val = rand() % N;\n        \n        if (which == 0) {\n            a[emp] = new_val;\n        } else {\n            b[emp] = new_val;\n        }\n        \n        simulate();\n        int new_error = calculate_error();\n        \n        // If worse, only accept with small probability\n        if (new_error > current_error && rand() % 100 > 5) {\n            // Revert\n            if (which == 0) {\n                a[emp] = old_val;\n            } else {\n                b[emp] = old_val;\n            }\n        }\n    }\n    \n    // Output result\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>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 800;\nconst int MAX_Q = 400;\nconst int MAX_L = 15;\n\nint n, m, q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<pair<int, int>> centers;\nvector<vector<int>> groups;\nvector<set<pair<int, int>>> mst_edges;\nmap<pair<int, int>, int> edge_distances;\n\n// Calculate distance between two rectangles using their centers\nint calc_center_distance(int i, int j) {\n    int cx1 = (lx[i] + rx[i]) / 2;\n    int cy1 = (ly[i] + ry[i]) / 2;\n    int cx2 = (lx[j] + rx[j]) / 2;\n    int cy2 = (ly[j] + ry[j]) / 2;\n    return floor(sqrt(pow(cx1 - cx2, 2) + pow(cy1 - cy2, 2)));\n}\n\n// Query function\nvector<pair<int, int>> query(const vector<int>& cities) {\n    if (cities.size() < 2 || cities.size() > L) {\n        cerr << \"Invalid query size: \" << cities.size() << endl;\n        return {};\n    }\n    \n    cout << \"? \" << cities.size();\n    for (int city : cities) {\n        cout << \" \" << city;\n    }\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int, int>> result;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        if (u > v) swap(u, v);\n        result.push_back({u, v});\n        \n        // Store this edge information\n        edge_distances[{u, v}] = 1; // We don't know actual distance but we know it exists\n    }\n    \n    return result;\n}\n\n// Initial clustering based on centers\nvoid initial_clustering() {\n    // Calculate centers\n    centers.clear();\n    for (int i = 0; i < n; i++) {\n        int cx = (lx[i] + rx[i]) / 2;\n        int cy = (ly[i] + ry[i]) / 2;\n        centers.push_back({cx, cy});\n    }\n    \n    // Create list of cities with indices\n    vector<pair<pair<int, int>, int>> city_centers;\n    for (int i = 0; i < n; i++) {\n        city_centers.push_back({centers[i], i});\n    }\n    \n    // Sort by x-coordinate, then y-coordinate\n    sort(city_centers.begin(), city_centers.end());\n    \n    // Assign to groups sequentially\n    groups.clear();\n    groups.resize(m);\n    int idx = 0;\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(city_centers[idx].second);\n            idx++;\n        }\n    }\n}\n\n// Improve clustering using local search\nvoid improve_clustering() {\n    // Simple improvement: try moving cities between adjacent groups\n    bool improved = true;\n    int iterations = 0;\n    const int max_iterations = 5;\n    \n    while (improved && iterations < max_iterations) {\n        improved = false;\n        iterations++;\n        \n        // Try swapping cities between groups to reduce potential MST cost\n        for (int i = 0; i < m; i++) {\n            for (int j = i + 1; j < m; j++) {\n                // Try swapping one city from group i with one from group j\n                for (int ci = 0; ci < (int)groups[i].size(); ci++) {\n                    for (int cj = 0; cj < (int)groups[j].size(); cj++) {\n                        int city_i = groups[i][ci];\n                        int city_j = groups[j][cj];\n                        \n                        // Temporarily swap\n                        swap(groups[i][ci], groups[j][cj]);\n                        \n                        // Simple heuristic: if centers are closer to the other group, keep swap\n                        int dist_i_to_i_group = 0;\n                        int dist_i_to_j_group = 0;\n                        int dist_j_to_j_group = 0;\n                        int dist_j_to_i_group = 0;\n                        \n                        // Calculate approximate distances\n                        for (int k = 0; k < (int)groups[i].size(); k++) {\n                            if (k != ci) {\n                                dist_i_to_i_group += calc_center_distance(city_i, groups[i][k]);\n                                dist_j_to_i_group += calc_center_distance(city_j, groups[i][k]);\n                            }\n                        }\n                        \n                        for (int k = 0; k < (int)groups[j].size(); k++) {\n                            if (k != cj) {\n                                dist_i_to_j_group += calc_center_distance(city_i, groups[j][k]);\n                                dist_j_to_j_group += calc_center_distance(city_j, groups[j][k]);\n                            }\n                        }\n                        \n                        // If swap improves clustering, keep it\n                        if ((dist_j_to_i_group + dist_i_to_j_group) < (dist_i_to_i_group + dist_j_to_j_group)) {\n                            // Keep the swap\n                            improved = true;\n                        } else {\n                            // Revert the swap\n                            swap(groups[i][ci], groups[j][cj]);\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Use queries to learn about connections\nvoid learn_connections() {\n    int queries_used = 0;\n    \n    // For each group, perform queries to learn MST structure\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= 1) continue;\n        \n        // If group size is small enough, query the whole group\n        if (G[i] <= L && queries_used < q) {\n            vector<pair<int, int>> edges = query(groups[i]);\n            queries_used++;\n            continue;\n        }\n        \n        // For larger groups, do sliding window queries\n        for (int start = 0; start < G[i] - 1 && queries_used < q; start += L - 1) {\n            int end = min(start + L, G[i]);\n            vector<int> subset;\n            for (int j = start; j < end; j++) {\n                subset.push_back(groups[i][j]);\n            }\n            \n            if (subset.size() >= 2) {\n                vector<pair<int, int>> edges = query(subset);\n                queries_used++;\n            }\n            \n            if (queries_used >= q) break;\n        }\n    }\n    \n    // Use remaining queries for cross-group information\n    while (queries_used < q) {\n        // Pick a random small subset of cities from different groups\n        vector<int> subset;\n        int groups_picked = 0;\n        \n        for (int i = 0; i < m && groups_picked < 3; i++) {\n            if (!groups[i].empty()) {\n                subset.push_back(groups[i][0]);\n                groups_picked++;\n            }\n        }\n        \n        if (subset.size() >= 2) {\n            vector<pair<int, int>> edges = query(subset);\n            queries_used++;\n        } else {\n            break; // No more meaningful queries\n        }\n    }\n}\n\n// Build MST for each group\nvector<vector<pair<int, int>>> build_msts() {\n    vector<vector<pair<int, int>>> result(m);\n    \n    for (int i = 0; i < m; i++) {\n        if (G[i] <= 1) continue;\n        \n        // For small groups, we can query directly\n        if (G[i] <= L) {\n            vector<pair<int, int>> edges = query(groups[i]);\n            result[i] = edges;\n            continue;\n        }\n        \n        // For larger groups, build approximate MST\n        // Use a simple approach: connect in order (this is suboptimal but works)\n        for (int j = 0; j < G[i] - 1; j++) {\n            result[i].push_back({groups[i][j], groups[i][j+1]});\n        }\n    }\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++) {\n        cin >> G[i];\n    }\n    \n    lx.resize(n);\n    rx.resize(n);\n    ly.resize(n);\n    ry.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Perform initial clustering\n    initial_clustering();\n    \n    // Improve clustering\n    improve_clustering();\n    \n    // Learn connections through queries\n    learn_connections();\n    \n    // Build MSTs for final answer\n    vector<vector<pair<int, int>>> msts = build_msts();\n    \n    // Output final answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            cout << groups[i][j];\n            if (j < G[i] - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n        \n        for (const auto& edge : msts[i]) {\n            cout << edge.first << \" \" << edge.second << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int _x, int _y) : x(_x), y(_y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass SkatingSolver {\nprivate:\n    int grid[N][N]; // 0 = empty, 1 = block\n    Point pos;\n    vector<Point> targets;\n    vector<string> actions;\n    \npublic:\n    SkatingSolver() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        int n, m;\n        cin >> n >> m;\n        int x, y;\n        cin >> x >> y;\n        pos = Point(x, y);\n        \n        targets.resize(m);\n        for (int i = 0; i < m; i++) {\n            cin >> targets[i].x >> targets[i].y;\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void add_action(char action, char direction) {\n        actions.push_back(string(1, action) + \" \" + string(1, direction));\n    }\n    \n    // Move one step in given direction\n    bool move(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (!is_valid(nx, ny) || grid[nx][ny] == 1) {\n            return false;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('M', dir_chars[dir]);\n        return true;\n    }\n    \n    // Slide until hitting a block or boundary\n    void slide(int dir) {\n        int nx = pos.x, ny = pos.y;\n        \n        while (true) {\n            int tx = nx + dx[dir];\n            int ty = ny + dy[dir];\n            \n            if (!is_valid(tx, ty) || grid[tx][ty] == 1) {\n                break;\n            }\n            \n            nx = tx;\n            ny = ty;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('S', dir_chars[dir]);\n    }\n    \n    // Place or remove block\n    void alter(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            grid[nx][ny] = 1 - grid[nx][ny];\n        }\n        \n        add_action('A', dir_chars[dir]);\n    }\n    \n    // Find direction from point a to point b\n    int get_direction(Point a, Point b) {\n        if (a.x > b.x) return 0; // U\n        if (a.x < b.x) return 1; // D\n        if (a.y > b.y) return 2; // L\n        if (a.y < b.y) return 3; // R\n        return -1; // Same position\n    }\n    \n    // Manhattan distance\n    int manhattan_distance(Point a, Point b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Simple path finding using moves only\n    void move_to_target(Point target) {\n        // Use greedy approach - move in the direction that reduces distance\n        for (int step = 0; step < 1000 && !(pos == target); step++) {\n            int best_dir = -1;\n            int min_dist = manhattan_distance(pos, target);\n            \n            // Try all directions\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = pos.x + dx[dir];\n                int ny = pos.y + dy[dir];\n                \n                if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                    int dist = abs(nx - target.x) + abs(ny - target.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_dir = dir;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                move(best_dir);\n            } else {\n                // If stuck, try any valid move\n                bool moved = false;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (move(dir)) {\n                        moved = true;\n                        break;\n                    }\n                }\n                if (!moved) break;\n            }\n        }\n    }\n    \n    // Enhanced strategy using slides when possible\n    void smart_move_to_target(Point target) {\n        if (pos == target) return;\n        \n        // If in same row or column, consider sliding\n        if (pos.x == target.x || pos.y == target.y) {\n            int dir = get_direction(pos, target);\n            if (dir != -1) {\n                // Check if we can slide directly\n                bool can_slide_directly = true;\n                Point temp_pos = pos;\n                \n                while (!(temp_pos == target)) {\n                    int nx = temp_pos.x + dx[dir];\n                    int ny = temp_pos.y + dy[dir];\n                    \n                    if (!is_valid(nx, ny)) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    if (grid[nx][ny] == 1) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    temp_pos.x = nx;\n                    temp_pos.y = ny;\n                }\n                \n                if (can_slide_directly) {\n                    slide(dir);\n                    return;\n                }\n            }\n        }\n        \n        // Otherwise use regular move-to-target\n        move_to_target(target);\n    }\n    \n    void solve() {\n        // Visit each target in order\n        for (int i = 1; i < (int)targets.size(); i++) {\n            // If target has a block, remove it first\n            if (grid[targets[i].x][targets[i].y] == 1) {\n                // Find adjacent empty spot to remove block\n                for (int dir = 0; dir < 4; dir++) {\n                    int nx = targets[i].x + dx[dir];\n                    int ny = targets[i].y + dy[dir];\n                    \n                    if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                        // Move to adjacent position and remove block\n                        Point adj_pos(nx, ny);\n                        \n                        // Move to adjacent position\n                        move_to_target(adj_pos);\n                        \n                        // Remove block (opposite direction)\n                        int opposite_dir = (dir == 0) ? 1 : (dir == 1) ? 0 : (dir == 2) ? 3 : 2;\n                        alter(opposite_dir);\n                        break;\n                    }\n                }\n            }\n            \n            // Move to target\n            smart_move_to_target(targets[i]);\n        }\n    }\n    \n    void print_solution() {\n        for (const string& action : actions) {\n            cout << action << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    SkatingSolver solver;\n    solver.read_input();\n    solver.solve();\n    solver.print_solution();\n    \n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int id, x, y, r;\n    bool operator<(const Company& other) const {\n        return r > other.r; // Sort by area descending\n    }\n};\n\nstruct Rectangle {\n    int a, b, c, d; // (a,b) to (c,d)\n};\n\nconst int SIZE = 10000;\nvector<vector<bool>> occupied(SIZE, vector<bool>(SIZE, false));\nvector<Rectangle> result;\nvector<Company> companies;\n\n// Check if rectangle overlaps with existing ones\nbool is_valid(int a, int b, int c, int d) {\n    if (a < 0 || b < 0 || c > SIZE || d > SIZE) return false;\n    if (a >= c || b >= d) return false;\n    \n    for (int i = a; i < c; i++) {\n        for (int j = b; j < d; j++) {\n            if (occupied[i][j]) return false;\n        }\n    }\n    return true;\n}\n\n// Mark rectangle as occupied\nvoid mark_occupied(int a, int b, int c, int d, bool mark = true) {\n    for (int i = a; i < c; i++) {\n        for (int j = b; j < d; j++) {\n            occupied[i][j] = mark;\n        }\n    }\n}\n\n// Find factors of area\nvector<pair<int, int>> get_factors(int area) {\n    vector<pair<int, int>> factors;\n    for (int w = 1; w * w <= area; w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            factors.push_back({w, h});\n            if (w != h) factors.push_back({h, w});\n        }\n    }\n    return factors;\n}\n\n// Try to place rectangle for company\nbool place_company(const Company& comp) {\n    int target_x = comp.x;\n    int target_y = comp.y;\n    int area = comp.r;\n    \n    auto factors = get_factors(area);\n    \n    // Try different rectangle shapes\n    for (auto& factor : factors) {\n        int w = factor.first;\n        int h = factor.second;\n        \n        // Try different positions around the target point\n        for (int dx = -w/2; dx <= w/2; dx++) {\n            for (int dy = -h/2; dy <= h/2; dy++) {\n                int a = target_x + dx;\n                int b = target_y + dy;\n                int c = a + w;\n                int d = b + h;\n                \n                // Check if the target point is inside (using 0.5 offset)\n                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                    if (is_valid(a, b, c, d)) {\n                        mark_occupied(a, b, c, d);\n                        result[comp.id] = {a, b, c, d};\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // If exact area doesn't work, try approximate areas\n    for (int delta = 1; delta <= min(100, area/10); delta++) {\n        vector<int> test_areas = {area + delta, area - delta};\n        for (int test_area : test_areas) {\n            if (test_area <= 0) continue;\n            \n            auto test_factors = get_factors(test_area);\n            for (auto& factor : test_factors) {\n                int w = factor.first;\n                int h = factor.second;\n                \n                for (int dx = -w/2; dx <= w/2; dx++) {\n                    for (int dy = -h/2; dy <= h/2; dy++) {\n                        int a = target_x + dx;\n                        int b = target_y + dy;\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                            if (is_valid(a, b, c, d)) {\n                                mark_occupied(a, b, c, d);\n                                result[comp.id] = {a, b, c, d};\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Last resort: place any valid rectangle\n    for (int w = 1; w <= min(100, area); w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            for (int a = max(0, target_x - w + 1); a <= min(SIZE - w, target_x); a++) {\n                for (int b = max(0, target_y - h + 1); b <= min(SIZE - h, target_y); b++) {\n                    int c = a + w;\n                    int d = b + h;\n                    \n                    if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                        if (is_valid(a, b, c, d)) {\n                            mark_occupied(a, b, c, d);\n                            result[comp.id] = {a, b, c, d};\n                            return true;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Place smallest possible rectangle as fallback\n    int a = max(0, min(target_x, SIZE - 1));\n    int b = max(0, min(target_y, SIZE - 1));\n    int c = min(SIZE, a + 1);\n    int d = min(SIZE, b + 1);\n    a = max(0, c - 1);\n    b = max(0, d - 1);\n    \n    if (is_valid(a, b, c, d)) {\n        mark_occupied(a, b, c, d);\n        result[comp.id] = {a, b, c, d};\n        return true;\n    }\n    \n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    companies.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        companies[i].id = i;\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n    }\n    \n    // Sort by area descending\n    sort(companies.begin(), companies.end());\n    \n    // Place each company\n    for (const auto& company : companies) {\n        place_company(company);\n    }\n    \n    // Output results\n    for (const auto& rect : result) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SIZE = 50;\nint si, sj;\nint tile_id[SIZE][SIZE];\nint points[SIZE][SIZE];\nvector<pair<int,int>> tile_cells[2500]; // max possible tiles\nbool tile_visited[2500];\nstring best_path;\nint best_score = 0;\n\n// Directions: U, D, L, R\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nvoid preprocess_tiles() {\n    bool processed[2500] = {false};\n    int max_tile_id = 0;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            max_tile_id = max(max_tile_id, tile_id[i][j]);\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            int tid = tile_id[i][j];\n            tile_cells[tid].push_back({i, j});\n        }\n    }\n}\n\nint get_tile_value(int tile_id) {\n    int value = 0;\n    for (auto& cell : tile_cells[tile_id]) {\n        value += points[cell.first][cell.second];\n    }\n    return value;\n}\n\nbool is_valid_move(int x, int y) {\n    return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n}\n\nvector<pair<int,int>> get_adjacent_cells(int x, int y) {\n    vector<pair<int,int>> adj;\n    for (int d = 0; d < 4; d++) {\n        int nx = x + dx[d];\n        int ny = y + dy[d];\n        if (is_valid_move(nx, ny)) {\n            adj.push_back({nx, ny});\n        }\n    }\n    return adj;\n}\n\nset<int> get_adjacent_unvisited_tiles(int current_x, int current_y) {\n    set<int> adjacent_tiles;\n    \n    // Get all cells of current tile\n    int current_tile = tile_id[current_x][current_y];\n    \n    // Check all cells of current tile for adjacent cells\n    for (auto& cell : tile_cells[current_tile]) {\n        auto adj_cells = get_adjacent_cells(cell.first, cell.second);\n        for (auto& adj_cell : adj_cells) {\n            int adj_tile = tile_id[adj_cell.first][adj_cell.second];\n            if (!tile_visited[adj_tile]) {\n                adjacent_tiles.insert(adj_tile);\n            }\n        }\n    }\n    \n    return adjacent_tiles;\n}\n\n// Simple greedy approach with some lookahead\nstring greedy_search() {\n    // Reset visited status\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int current_x = si, current_y = sj;\n    int current_tile = tile_id[current_x][current_y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    // Look ahead a few steps\n    for (int step = 0; step < 2000; step++) { // Limit path length\n        auto adjacent_tiles = get_adjacent_unvisited_tiles(current_x, current_y);\n        \n        if (adjacent_tiles.empty()) {\n            break;\n        }\n        \n        // Find best next tile based on value and potential\n        int best_tile = -1;\n        int best_value = -1;\n        pair<int,int> best_cell;\n        char best_direction = ' ';\n        \n        // Check all adjacent unvisited tiles\n        for (int tile : adjacent_tiles) {\n            int tile_value = get_tile_value(tile);\n            \n            // Find the best cell in this tile to move to\n            for (auto& cell : tile_cells[tile]) {\n                // Check if this cell is adjacent to current position\n                bool is_adjacent = false;\n                char direction = ' ';\n                \n                // Get all cells of current tile\n                for (auto& cur_cell : tile_cells[current_tile]) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = cur_cell.first + dx[d];\n                        int ny = cur_cell.second + dy[d];\n                        if (is_valid_move(nx, ny) && nx == cell.first && ny == cell.second) {\n                            is_adjacent = true;\n                            direction = dir_char[d];\n                            break;\n                        }\n                    }\n                    if (is_adjacent) break;\n                }\n                \n                if (is_adjacent && tile_value > best_value) {\n                    best_value = tile_value;\n                    best_tile = tile;\n                    best_cell = cell;\n                    best_direction = direction;\n                }\n            }\n        }\n        \n        if (best_tile == -1) {\n            break;\n        }\n        \n        // Move to best tile\n        tile_visited[best_tile] = true;\n        current_x = best_cell.first;\n        current_y = best_cell.second;\n        current_tile = best_tile;\n        path += best_direction;\n    }\n    \n    return path;\n}\n\n// Improved greedy with better evaluation\nstring improved_greedy() {\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int current_x = si, current_y = sj;\n    int current_tile = tile_id[current_x][current_y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    int total_score = 0;\n    \n    // Add initial position score\n    for (auto& cell : tile_cells[current_tile]) {\n        total_score += points[cell.first][cell.second];\n    }\n    \n    for (int step = 0; step < 2500; step++) {\n        auto adjacent_tiles = get_adjacent_unvisited_tiles(current_x, current_y);\n        \n        if (adjacent_tiles.empty()) {\n            break;\n        }\n        \n        // Evaluate moves more carefully\n        struct Move {\n            int tile_id;\n            pair<int,int> target_cell;\n            char direction;\n            int value;\n            double score; // value + some heuristic\n        };\n        \n        vector<Move> possible_moves;\n        \n        // Collect all possible moves\n        for (int tile : adjacent_tiles) {\n            int tile_value = get_tile_value(tile);\n            \n            // Find all ways to reach this tile\n            for (auto& cell : tile_cells[tile]) {\n                // Check adjacency from current tile\n                for (auto& cur_cell : tile_cells[current_tile]) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = cur_cell.first + dx[d];\n                        int ny = cur_cell.second + dy[d];\n                        if (is_valid_move(nx, ny) && nx == cell.first && ny == cell.second) {\n                            Move move;\n                            move.tile_id = tile;\n                            move.target_cell = cell;\n                            move.direction = dir_char[d];\n                            move.value = tile_value;\n                            \n                            // Simple scoring: just the tile value\n                            move.score = tile_value;\n                            possible_moves.push_back(move);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (possible_moves.empty()) {\n            break;\n        }\n        \n        // Sort by score descending\n        sort(possible_moves.begin(), possible_moves.end(), \n             [](const Move& a, const Move& b) { return a.score > b.score; });\n        \n        // Take the best move\n        auto& best_move = possible_moves[0];\n        tile_visited[best_move.tile_id] = true;\n        current_x = best_move.target_cell.first;\n        current_y = best_move.target_cell.second;\n        current_tile = best_move.tile_id;\n        path += best_move.direction;\n        total_score += best_move.value;\n    }\n    \n    if (total_score > best_score) {\n        best_score = total_score;\n        best_path = path;\n    }\n    \n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> tile_id[i][j];\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess_tiles();\n    \n    // Try multiple approaches and take the best\n    string result = improved_greedy();\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int QUERY_COUNT = 1000;\n\n// Edge weight estimates with confidence\nvector<vector<double>> h_edges; // horizontal edges (i,j) to (i,j+1)\nvector<vector<double>> v_edges; // vertical edges (i,j) to (i+1,j)\nvector<vector<double>> h_confidence; // confidence in h_edge estimates\nvector<vector<double>> v_confidence; // confidence in v_edge estimates\n\n// Count of times each edge has been used\nvector<vector<int>> h_usage_count;\nvector<vector<int>> v_usage_count;\n\n// Initialize edge weights\nvoid initialize_weights() {\n    // Better initial estimate based on problem parameters\n    h_edges.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 5000.0));\n    v_edges.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 5000.0));\n    \n    // Initialize confidence (lower means less certain)\n    h_confidence.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 1.0));\n    v_confidence.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 1.0));\n    \n    // Usage counts\n    h_usage_count.assign(GRID_SIZE, vector<int>(GRID_SIZE - 1, 0));\n    v_usage_count.assign(GRID_SIZE - 1, vector<int>(GRID_SIZE, 0));\n}\n\n// Calculate path length using current estimates\ndouble calculate_estimated_length(const vector<pair<int,int>>& path) {\n    double length = 0.0;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) {\n            length += h_edges[r1][c1];\n        } else if (r1 == r2 && c2 == c1 - 1) {\n            length += h_edges[r1][c2];\n        } else if (c1 == c2 && r2 == r1 + 1) {\n            length += v_edges[r1][c1];\n        } else if (c1 == c2 && r2 == r1 - 1) {\n            length += v_edges[r2][c1];\n        }\n    }\n    return length;\n}\n\n// Get actual length from the last query\nint get_actual_length() {\n    int actual_length;\n    cin >> actual_length;\n    return actual_length;\n}\n\n// Find shortest path using A* with current estimates and some exploration\nvector<pair<int,int>> find_shortest_path(int start_r, int start_c, int end_r, int end_c, int query_num) {\n    // For very short distances, just use Manhattan path\n    int manhattan_dist = abs(start_r - end_r) + abs(start_c - end_c);\n    if (manhattan_dist <= 10 && query_num > 100) {\n        vector<pair<int,int>> path;\n        path.push_back({start_r, start_c});\n        int r = start_r, c = start_c;\n        \n        // Move vertically first\n        while (r < end_r) {\n            r++;\n            path.push_back({r, c});\n        }\n        while (r > end_r) {\n            r--;\n            path.push_back({r, c});\n        }\n        \n        // Then horizontally\n        while (c < end_c) {\n            c++;\n            path.push_back({r, c});\n        }\n        while (c > end_c) {\n            c--;\n            path.push_back({r, c});\n        }\n        return path;\n    }\n    \n    // Priority queue: {f_score, g_score, row, col}\n    priority_queue<tuple<double, double, int, int>, vector<tuple<double, double, int, int>>, greater<>> pq;\n    \n    // Distance and parent tracking\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int,int>>> parent(GRID_SIZE, vector<pair<int,int>>(GRID_SIZE, {-1, -1}));\n    \n    auto heuristic = [&](int r, int c) {\n        return abs(r - end_r) + abs(c - end_c); // Manhattan distance\n    };\n    \n    dist[start_r][start_c] = 0;\n    pq.push({heuristic(start_r, start_c), 0.0, start_r, start_c});\n    \n    vector<pair<int,int>> directions = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // U, D, L, R\n    \n    while (!pq.empty()) {\n        auto [f_score, g_score, r, c] = pq.top();\n        pq.pop();\n        \n        if (g_score > dist[r][c]) continue;\n        \n        if (r == end_r && c == end_c) break;\n        \n        // Explore neighbors\n        for (int dir = 0; dir < 4; dir++) {\n            int dr = directions[dir].first;\n            int dc = directions[dir].second;\n            int nr = r + dr;\n            int nc = c + dc;\n            \n            // Check bounds\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            \n            double edge_cost = 0;\n            if (dr == 0 && dc == 1) { // Right\n                edge_cost = h_edges[r][c];\n            } else if (dr == 0 && dc == -1) { // Left\n                edge_cost = h_edges[r][nc];\n            } else if (dr == 1 && dc == 0) { // Down\n                edge_cost = v_edges[r][c];\n            } else if (dr == -1 && dc == 0) { // Up\n                edge_cost = v_edges[nr][c];\n            }\n            \n            // Add exploration bonus for less confident edges (early queries)\n            if (query_num < 200) {\n                double exploration_bonus = 0;\n                if (dr == 0 && dc == 1) { // Right\n                    exploration_bonus = (1.0 / (h_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 0 && dc == -1) { // Left\n                    exploration_bonus = (1.0 / (h_confidence[r][nc] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 1 && dc == 0) { // Down\n                    exploration_bonus = (1.0 / (v_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == -1 && dc == 0) { // Up\n                    exploration_bonus = (1.0 / (v_confidence[nr][c] + 1e-6)) * (200 - query_num) * 0.1;\n                }\n                edge_cost += exploration_bonus;\n            }\n            \n            double new_g_score = g_score + edge_cost;\n            if (new_g_score < dist[nr][nc]) {\n                dist[nr][nc] = new_g_score;\n                parent[nr][nc] = {r, c};\n                double f_score = new_g_score + heuristic(nr, nc);\n                pq.push({f_score, new_g_score, nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int r = end_r, c = end_c;\n    while (r != -1 && c != -1) {\n        path.push_back({r, c});\n        auto p = parent[r][c];\n        r = p.first;\n        c = p.second;\n    }\n    reverse(path.begin(), path.end());\n    \n    return path;\n}\n\n// Convert path to direction string\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r2 == r1 - 1) result += 'U';\n        else if (r2 == r1 + 1) result += 'D';\n        else if (c2 == c1 - 1) result += 'L';\n        else if (c2 == c1 + 1) result += 'R';\n    }\n    return result;\n}\n\n// Update edge weights based on actual path performance with confidence tracking\nvoid update_weights(const vector<pair<int,int>>& path, int actual_length, int query_num) {\n    if (path.size() < 2) return;\n    \n    double estimated_length = calculate_estimated_length(path);\n    double error = actual_length - estimated_length;\n    \n    // Adaptive learning rate based on query number and path length\n    double base_learning_rate = 0.3;\n    double learning_rate = base_learning_rate * exp(-0.001 * query_num);\n    \n    // Update each edge in the path\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) { // Right\n            h_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c1] += learning_rate * edge_error;\n            h_edges[r1][c1] = max(100.0, min(10000.0, h_edges[r1][c1]));\n            // Update confidence - more usage means higher confidence\n            h_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (r1 == r2 && c2 == c1 - 1) { // Left\n            h_usage_count[r1][c2]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c2] += learning_rate * edge_error;\n            h_edges[r1][c2] = max(100.0, min(10000.0, h_edges[r1][c2]));\n            h_confidence[r1][c2] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 + 1) { // Down\n            v_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r1][c1] += learning_rate * edge_error;\n            v_edges[r1][c1] = max(100.0, min(10000.0, v_edges[r1][c1]));\n            v_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 - 1) { // Up\n            v_usage_count[r2][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r2][c1] += learning_rate * edge_error;\n            v_edges[r2][c1] = max(100.0, min(10000.0, v_edges[r2][c1]));\n            v_confidence[r2][c1] += learning_rate * 10.0;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_weights();\n    \n    for (int query = 0; query < QUERY_COUNT; query++) {\n        int start_r, start_c, end_r, end_c;\n        cin >> start_r >> start_c >> end_r >> end_c;\n        \n        vector<pair<int,int>> path = find_shortest_path(start_r, start_c, end_r, end_c, query);\n        \n        string path_str = path_to_string(path);\n        cout << path_str << endl;\n        cout.flush();\n        \n        // Get actual length and update weights\n        int actual_length = get_actual_length();\n        update_weights(path, actual_length, query);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst string ALPHABET = \"ABCDEFGH\";\n\nstruct StringInfo {\n    string s;\n    int id;\n    bool placed = false;\n    int row = -1, col = -1;\n    bool horizontal = true;\n};\n\nvector<string> matrix(N, string(N, '.'));\nvector<StringInfo> strings;\nint M;\n\n// Check if string can be placed at position (r,c) in given direction\nbool canPlace(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        \n        if (matrix[nr][nc] != '.' && matrix[nr][nc] != s[i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place string at position (r,c) in given direction\nvoid placeString(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        matrix[nr][nc] = s[i];\n    }\n}\n\n// Count how many strings are currently matched\nint countMatches() {\n    int count = 0;\n    for (const auto& str_info : strings) {\n        const string& s = str_info.s;\n        bool found = false;\n        \n        // Check horizontal placements\n        for (int r = 0; r < N && !found; r++) {\n            for (int c = 0; c < N && !found; c++) {\n                bool match = true;\n                for (int i = 0; i < (int)s.length(); i++) {\n                    int nc = (c + i) % N;\n                    if (matrix[r][nc] != s[i]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) {\n                    found = true;\n                }\n            }\n        }\n        \n        // Check vertical placements\n        if (!found) {\n            for (int c = 0; c < N && !found; c++) {\n                for (int r = 0; r < N && !found; r++) {\n                    bool match = true;\n                    for (int i = 0; i < (int)s.length(); i++) {\n                        int nr = (r + i) % N;\n                        if (matrix[nr][c] != s[i]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                    }\n                }\n            }\n        }\n        \n        if (found) count++;\n    }\n    return count;\n}\n\n// Try to place as many strings as possible\nvoid greedyPlacement() {\n    // Sort strings by length (longer first might be better)\n    vector<pair<int, int>> str_lengths;\n    for (int i = 0; i < M; i++) {\n        str_lengths.push_back({(int)strings[i].s.length(), i});\n    }\n    sort(str_lengths.rbegin(), str_lengths.rend());\n    \n    for (const auto& p : str_lengths) {\n        int idx = p.second;\n        const string& s = strings[idx].s;\n        \n        // Try to place this string\n        bool placed = false;\n        \n        // Try horizontal placements first\n        for (int r = 0; r < N && !placed; r++) {\n            for (int c = 0; c < N && !placed; c++) {\n                if (canPlace(s, r, c, true)) {\n                    placeString(s, r, c, true);\n                    strings[idx].placed = true;\n                    strings[idx].row = r;\n                    strings[idx].col = c;\n                    strings[idx].horizontal = true;\n                    placed = true;\n                }\n            }\n        }\n        \n        // Try vertical placements if horizontal didn't work\n        if (!placed) {\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    if (canPlace(s, r, c, false)) {\n                        placeString(s, r, c, false);\n                        strings[idx].placed = true;\n                        strings[idx].row = r;\n                        strings[idx].col = c;\n                        strings[idx].horizontal = false;\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Improve by trying to fill empty spots\nvoid fillEmptySpots() {\n    // For each empty cell, try to determine the best character\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matrix[r][c] == '.') {\n                // Count which characters would help match more strings\n                map<char, int> char_score;\n                \n                for (char ch : ALPHABET) {\n                    matrix[r][c] = ch;\n                    int new_matches = countMatches();\n                    char_score[ch] = new_matches;\n                }\n                \n                // Choose character that maximizes matches\n                char best_char = '.';\n                int best_score = -1;\n                for (const auto& p : char_score) {\n                    if (p.second > best_score) {\n                        best_score = p.second;\n                        best_char = p.first;\n                    }\n                }\n                \n                matrix[r][c] = best_char;\n            }\n        }\n    }\n}\n\n// Simple randomized approach\nvoid randomImprovement() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    int current_matches = countMatches();\n    \n    // Try random changes\n    for (int iter = 0; iter < 1000; iter++) {\n        // Pick a random cell\n        int r = gen() % N;\n        int c = gen() % N;\n        char original = matrix[r][c];\n        \n        // Try a random character\n        char new_char = ALPHABET[gen() % ALPHABET.length()];\n        matrix[r][c] = new_char;\n        \n        int new_matches = countMatches();\n        if (new_matches < current_matches) {\n            matrix[r][c] = original; // Revert\n        } else {\n            current_matches = new_matches;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    strings.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> strings[i].s;\n        strings[i].id = i;\n    }\n    \n    // Initialize matrix\n    for (int i = 0; i < N; i++) {\n        matrix[i] = string(N, '.');\n    }\n    \n    // Greedy placement\n    greedyPlacement();\n    \n    // Try to improve\n    fillEmptySpots();\n    \n    // Final improvement\n    randomImprovement();\n    \n    // Output result\n    for (const string& row : matrix) {\n        cout << row << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 70;\nint N, si, sj;\nchar grid[MAX_N][MAX_N];\nbool is_road[MAX_N][MAX_N];\nint cost[MAX_N][MAX_N];\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Calculate visible squares from a given position\nset<pair<int,int>> get_visible_squares(int x, int y) {\n    set<pair<int,int>> visible;\n    \n    // Horizontal visibility (same row)\n    // Left direction\n    for (int j = y; j >= 0; j--) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    // Right direction\n    for (int j = y; j < N; j++) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    \n    // Vertical visibility (same column)\n    // Up direction\n    for (int i = x; i >= 0; i--) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    // Down direction\n    for (int i = x; i < N; i++) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    \n    return visible;\n}\n\n// Count total road squares\nint count_roads() {\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) cnt++;\n        }\n    }\n    return cnt;\n}\n\n// Check if position is valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && is_road[x][y];\n}\n\n// BFS to find shortest path between two points\nvector<char> bfs_path(int start_x, int start_y, int end_x, int end_y) {\n    if (start_x == end_x && start_y == end_y) return {};\n    \n    queue<pair<int,int>> q;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    \n    q.push({start_x, start_y});\n    visited[start_x][start_y] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            \n            if (is_valid(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = {x, y};\n                q.push({nx, ny});\n                \n                if (nx == end_x && ny == end_y) {\n                    // Reconstruct path\n                    vector<char> path;\n                    int cx = end_x, cy = end_y;\n                    \n                    while (parent[cx][cy].first != -1) {\n                        auto [px, py] = parent[cx][cy];\n                        // Determine direction from parent to current\n                        if (cx == px - 1 && cy == py) path.push_back('U');\n                        else if (cx == px + 1 && cy == py) path.push_back('D');\n                        else if (cx == px && cy == py - 1) path.push_back('L');\n                        else if (cx == px && cy == py + 1) path.push_back('R');\n                        \n                        cx = px;\n                        cy = py;\n                    }\n                    \n                    reverse(path.begin(), path.end());\n                    return path;\n                }\n            }\n        }\n    }\n    \n    return {}; // No path found\n}\n\n// Generate a systematic path that tries to cover area\nvector<char> generate_systematic_path() {\n    vector<char> path;\n    int x = si, y = sj;\n    \n    // Collect all road positions\n    vector<pair<int,int>> roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) {\n                roads.push_back({i, j});\n            }\n        }\n    }\n    \n    if (roads.empty()) return path;\n    \n    // Sort roads by distance from start, then visit them systematically\n    sort(roads.begin(), roads.end(), [&](const pair<int,int>& a, const pair<int,int>& b) {\n        int dist_a = abs(a.first - si) + abs(a.second - sj);\n        int dist_b = abs(b.first - si) + abs(b.second - sj);\n        return dist_a < dist_b;\n    });\n    \n    // Visit a subset of roads to avoid overly long path\n    int max_visits = min(200, (int)roads.size());\n    \n    int current_x = si, current_y = sj;\n    \n    for (int i = 0; i < max_visits && path.size() < 2500; i++) {\n        int target_x = roads[i].first;\n        int target_y = roads[i].second;\n        \n        // Get path to this road square\n        auto segment = bfs_path(current_x, current_y, target_x, target_y);\n        \n        // Add to overall path\n        path.insert(path.end(), segment.begin(), segment.end());\n        \n        current_x = target_x;\n        current_y = target_y;\n    }\n    \n    // Return to start\n    if (current_x != si || current_y != sj) {\n        auto return_segment = bfs_path(current_x, current_y, si, sj);\n        path.insert(path.end(), return_segment.begin(), return_segment.end());\n    }\n    \n    return path;\n}\n\n// Simplify path by removing unnecessary moves\nvector<char> simplify_path(const vector<char>& original_path) {\n    if (original_path.empty()) return original_path;\n    \n    // Simulate the path to get actual positions\n    vector<pair<int,int>> positions;\n    int x = si, y = sj;\n    positions.push_back({x, y});\n    \n    for (char c : original_path) {\n        int dir = -1;\n        for (int i = 0; i < 4; i++) {\n            if (dir_char[i] == c) {\n                dir = i;\n                break;\n            }\n        }\n        \n        if (dir != -1) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            if (is_valid(nx, ny)) {\n                x = nx;\n                y = ny;\n                positions.push_back({x, y});\n            }\n        }\n    }\n    \n    // If we don't end at start, this path is invalid\n    if (x != si || y != sj) {\n        // Try to force return to start\n        auto return_path = bfs_path(x, y, si, sj);\n        vector<char> fixed_path = original_path;\n        fixed_path.insert(fixed_path.end(), return_path.begin(), return_path.end());\n        return fixed_path;\n    }\n    \n    return original_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j];\n            if (line[j] == '#') {\n                is_road[i][j] = false;\n            } else {\n                is_road[i][j] = true;\n                cost[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    // Generate path\n    vector<char> path = generate_systematic_path();\n    \n    // Simplify and ensure validity\n    path = simplify_path(path);\n    \n    // Final check - limit length\n    if (path.size() > 2999) {\n        path.resize(2999);\n        path = simplify_path(path);\n    }\n    \n    // Output result\n    for (char c : path) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int MAX_N = 1000;\nconst int MAX_M = 20;\nconst int MAX_K = 20;\nconst int MAX_DAYS = 2000;\n\n// Global variables\nint N, M, K, R;\nvector<vector<int>> task_skills;  // [task][skill] = required level\nvector<vector<int>> member_skills; // [member][skill] = estimated level\nvector<vector<int>> task_times;    // [task][member] = observed time\nvector<vector<int>> dependencies;  // [task] = list of prerequisite tasks\nvector<vector<int>> reverse_dependencies; // [task] = list of dependent tasks\nvector<int> task_status;           // -1:not started, 0:in progress, 1:completed\nvector<int> member_status;         // -1:free, task_id:working on task\nvector<int> task_completion_day;   // when each task was completed\nvector<set<int>> completed_tasks_by_member; // track what each member completed\n\n// For skill estimation\nvector<int> task_start_day;\nvector<vector<pair<int,int>>> member_task_history; // {task_id, completion_time}\n\n// Topological sorting helper\nvector<int> in_degree;\nqueue<int> ready_tasks;\n\nvoid read_input() {\n    cin >> N >> M >> K >> R;\n    \n    task_skills.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_skills[i][j];\n        }\n    }\n    \n    dependencies.resize(N);\n    reverse_dependencies.resize(N);\n    in_degree.assign(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--; // Convert to 0-indexed\n        dependencies[v].push_back(u);\n        reverse_dependencies[u].push_back(v);\n        in_degree[v]++;\n    }\n}\n\n// Initialize data structures\nvoid initialize() {\n    task_status.assign(N, -1);\n    member_status.assign(M, -1);\n    task_completion_day.assign(N, -1);\n    task_start_day.assign(N, -1);\n    completed_tasks_by_member.resize(M);\n    member_task_history.resize(M);\n    \n    // Initialize skill estimates with reasonable defaults\n    member_skills.resize(M, vector<int>(K, 10)); // Start with moderate skills\n    task_times.resize(N, vector<int>(M, 1));     // Default time estimate\n    \n    // Find initially ready tasks (no dependencies)\n    for (int i = 0; i < N; i++) {\n        if (in_degree[i] == 0) {\n            ready_tasks.push(i);\n        }\n    }\n}\n\n// Estimate member skills based on history\nvoid update_skill_estimates() {\n    // Simple approach: for each member, look at tasks they completed quickly\n    for (int member = 0; member < M; member++) {\n        if (member_task_history[member].size() == 0) continue;\n        \n        // Look at recent successful completions (time = 1 day usually means skill >= difficulty)\n        map<int, vector<int>> skill_samples; // skill_index -> list of observed levels\n        \n        for (auto& [task_id, completion_time] : member_task_history[member]) {\n            if (completion_time <= 2) { // Completed quickly\n                for (int k = 0; k < K; k++) {\n                    // If completed quickly, member's skill is likely >= task requirement\n                    skill_samples[k].push_back(task_skills[task_id][k]);\n                }\n            }\n        }\n        \n        // Update skill estimates\n        for (int k = 0; k < K; k++) {\n            if (!skill_samples[k].empty()) {\n                // Take maximum observed requirement they handled well\n                sort(skill_samples[k].begin(), skill_samples[k].end());\n                member_skills[member][k] = max(member_skills[member][k], \n                                             skill_samples[k].back());\n            }\n        }\n    }\n}\n\n// Calculate estimated time for a member to complete a task\nint estimate_time(int task_id, int member_id) {\n    int w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0, task_skills[task_id][k] - member_skills[member_id][k]);\n    }\n    \n    if (w == 0) return 1;\n    else return max(1, w); // Simplified - ignoring randomness for planning\n}\n\n// Get best available member for a task\nint get_best_member(int task_id) {\n    int best_member = 0;\n    int min_time = estimate_time(task_id, 0);\n    \n    for (int member = 1; member < M; member++) {\n        int time = estimate_time(task_id, member);\n        if (time < min_time) {\n            min_time = time;\n            best_member = member;\n        }\n    }\n    \n    return best_member;\n}\n\n// Update ready tasks based on completed tasks\nvoid update_ready_tasks(int completed_task) {\n    for (int dependent : reverse_dependencies[completed_task]) {\n        in_degree[dependent]--;\n        if (in_degree[dependent] == 0) {\n            ready_tasks.push(dependent);\n        }\n    }\n}\n\n// Main assignment logic\nvector<pair<int, int>> assign_tasks(int current_day) {\n    vector<pair<int, int>> assignments;\n    \n    // Find free members\n    vector<int> free_members;\n    for (int member = 0; member < M; member++) {\n        if (member_status[member] == -1) {\n            free_members.push_back(member);\n        }\n    }\n    \n    if (free_members.empty() || ready_tasks.empty()) {\n        return assignments;\n    }\n    \n    // Create list of ready tasks with priorities\n    vector<pair<int, int>> task_priority; // {priority, task_id}\n    queue<int> temp_queue = ready_tasks; // Copy to avoid modifying original\n    \n    while (!temp_queue.empty()) {\n        int task_id = temp_queue.front();\n        temp_queue.pop();\n        \n        // Priority: tasks with more dependents first, then lower ID\n        int priority = -reverse_dependencies[task_id].size() * 1000 - task_id;\n        task_priority.push_back({priority, task_id});\n    }\n    \n    sort(task_priority.begin(), task_priority.end());\n    \n    // Assign tasks to free members\n    int task_count = min((int)free_members.size(), (int)task_priority.size());\n    \n    for (int i = 0; i < task_count; i++) {\n        int member_id = free_members[i];\n        int task_id = task_priority[i].second;\n        \n        // Remove this task from ready queue (we'll re-add if not assigned)\n        // Actually, let's handle this more carefully in the main loop\n        \n        assignments.push_back({member_id, task_id});\n        task_status[task_id] = 0; // Mark as in progress\n        member_status[member_id] = task_id;\n        task_start_day[task_id] = current_day;\n    }\n    \n    return assignments;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    read_input();\n    initialize();\n    \n    int day = 0;\n    \n    while (day < MAX_DAYS) {\n        day++;\n        \n        // Process completed tasks from previous day\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) {\n            break; // Done\n        }\n        \n        vector<int> completed_members(n_completed);\n        for (int i = 0; i < n_completed; i++) {\n            cin >> completed_members[i];\n            completed_members[i]--; // Convert to 0-indexed\n        }\n        \n        // Update based on completed tasks\n        for (int member_idx : completed_members) {\n            int task_id = member_status[member_idx];\n            if (task_id != -1) {\n                task_status[task_id] = 1;\n                task_completion_day[task_id] = day;\n                member_status[member_idx] = -1;\n                completed_tasks_by_member[member_idx].insert(task_id);\n                \n                // Record completion for skill estimation\n                int duration = day - task_start_day[task_id];\n                member_task_history[member_idx].push_back({task_id, duration});\n                \n                // Update ready tasks\n                update_ready_tasks(task_id);\n            }\n        }\n        \n        // Update skill estimates periodically\n        if (day % 10 == 0) {\n            update_skill_estimates();\n        }\n        \n        // Make new assignments\n        vector<pair<int, int>> assignments = assign_tasks(day);\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& [member, task] : assignments) {\n            cout << \" \" << (member + 1) << \" \" << (task + 1);\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst int NUM_ORDERS = 1000;\nconst int SELECT_COUNT = 50;\n\nstruct Order {\n    int id, a, b, c, d;\n    int pickup_dist_from_depot;\n    int delivery_dist_from_depot;\n    int direct_distance;\n};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan_distance(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nint manhattan_distance(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Calculate total distance of a route\nlong long calculate_route_distance(const vector<Point>& route) {\n    long long total = 0;\n    for (size_t i = 0; i + 1 < route.size(); i++) {\n        total += manhattan_distance(route[i], route[i + 1]);\n    }\n    return total;\n}\n\n// Greedy insertion to build route\nvector<Point> build_route(const vector<Order>& selected_orders) {\n    vector<pair<Point, int>> points; // point and order_id (negative for pickup, positive for delivery)\n    \n    for (const auto& order : selected_orders) {\n        points.emplace_back(Point(order.a, order.b), -order.id); // pickup (negative id)\n        points.emplace_back(Point(order.c, order.d), order.id);  // delivery (positive id)\n    }\n    \n    // Start with depot\n    vector<Point> route = {Point(DEPOT_X, DEPOT_Y)};\n    vector<bool> picked_up(selected_orders.size(), false);\n    vector<bool> delivered(selected_orders.size(), false);\n    vector<int> order_position(selected_orders.size() + 1, -1); // position in route for each order pickup\n    \n    // Simple greedy insertion\n    while (points.size() > 0) {\n        long long best_cost = 1e18;\n        size_t best_pos = 0;\n        size_t best_point_idx = 0;\n        bool valid_insertion = false;\n        \n        // Try inserting each remaining point at each possible position\n        for (size_t i = 0; i < points.size(); i++) {\n            auto& point = points[i];\n            int order_id = abs(point.second);\n            bool is_pickup = point.second < 0;\n            \n            // Check if insertion is valid\n            if (!is_pickup && !picked_up[order_id - 1]) continue; // Can't deliver before pickup\n            \n            for (size_t pos = 1; pos <= route.size(); pos++) {\n                route.insert(route.begin() + pos, point.first);\n                long long new_cost = calculate_route_distance(route);\n                route.erase(route.begin() + pos);\n                \n                if (new_cost < best_cost) {\n                    best_cost = new_cost;\n                    best_pos = pos;\n                    best_point_idx = i;\n                    valid_insertion = true;\n                }\n            }\n        }\n        \n        if (!valid_insertion) {\n            // Fallback: just append remaining points in some order\n            for (auto& point : points) {\n                route.push_back(point.first);\n            }\n            break;\n        }\n        \n        // Apply best insertion\n        auto point = points[best_point_idx];\n        int order_id = abs(point.second);\n        bool is_pickup = point.second < 0;\n        \n        route.insert(route.begin() + best_pos, point.first);\n        points.erase(points.begin() + best_point_idx);\n        \n        if (is_pickup) {\n            picked_up[order_id - 1] = true;\n            order_position[order_id] = best_pos;\n        } else {\n            delivered[order_id - 1] = true;\n        }\n    }\n    \n    // Return to depot\n    route.push_back(Point(DEPOT_X, DEPOT_Y));\n    \n    return route;\n}\n\n// Improved route construction using better heuristic\nvector<Point> build_better_route(const vector<Order>& selected_orders) {\n    vector<pair<Point, int>> points; // point and order_id\n    \n    for (const auto& order : selected_orders) {\n        points.emplace_back(Point(order.a, order.b), -order.id); // pickup\n        points.emplace_back(Point(order.c, order.d), order.id);  // delivery\n    }\n    \n    vector<Point> route = {Point(DEPOT_X, DEPOT_Y)};\n    vector<bool> served(selected_orders.size(), false);\n    \n    // Use nearest neighbor with constraint that pickup comes before delivery\n    vector<bool> picked_up(selected_orders.size(), false);\n    \n    while (points.size() > 0) {\n        int best_idx = -1;\n        long long best_dist = 1e18;\n        Point current = route.back();\n        \n        for (size_t i = 0; i < points.size(); i++) {\n            auto& point = points[i];\n            int order_id = abs(point.second) - 1;\n            bool is_pickup = point.second < 0;\n            \n            // Constraint: can only pick up if not picked up yet\n            // Constraint: can only deliver if picked up\n            if (is_pickup) {\n                if (!picked_up[order_id]) {\n                    long long dist = manhattan_distance(current, point.first);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            } else {\n                if (picked_up[order_id] && !served[order_id]) {\n                    long long dist = manhattan_distance(current, point.first);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_idx == -1) break;\n        \n        auto selected_point = points[best_idx];\n        int order_id = abs(selected_point.second) - 1;\n        bool is_pickup = selected_point.second < 0;\n        \n        route.push_back(selected_point.first);\n        points.erase(points.begin() + best_idx);\n        \n        if (is_pickup) {\n            picked_up[order_id] = true;\n        } else {\n            served[order_id] = true;\n        }\n    }\n    \n    route.push_back(Point(DEPOT_X, DEPOT_Y));\n    return route;\n}\n\n// Score-based selection of orders\nvector<Order> select_orders(vector<Order>& orders) {\n    // Calculate efficiency score for each order\n    for (auto& order : orders) {\n        order.pickup_dist_from_depot = manhattan_distance(DEPOT_X, DEPOT_Y, order.a, order.b);\n        order.delivery_dist_from_depot = manhattan_distance(DEPOT_X, DEPOT_Y, order.c, order.d);\n        order.direct_distance = manhattan_distance(order.a, order.b, order.c, order.d);\n    }\n    \n    // Sort by efficiency (lower is better)\n    // Efficiency = direct distance + min(pickup_to_depot, delivery_to_depot)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        int eff_a = a.direct_distance + min(a.pickup_dist_from_depot, a.delivery_dist_from_depot);\n        int eff_b = b.direct_distance + min(b.pickup_dist_from_depot, b.delivery_dist_from_depot);\n        return eff_a < eff_b;\n    });\n    \n    // Take first 50 orders\n    vector<Order> selected(orders.begin(), orders.begin() + SELECT_COUNT);\n    return selected;\n}\n\nint main() {\n    vector<Order> orders(NUM_ORDERS);\n    \n    // Read input\n    for (int i = 0; i < NUM_ORDERS; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i + 1;\n    }\n    \n    // Select orders\n    vector<Order> selected_orders = select_orders(orders);\n    \n    // Build route\n    vector<Point> route = build_better_route(selected_orders);\n    \n    // Output selected orders\n    cout << SELECT_COUNT;\n    for (const auto& order : selected_orders) {\n        cout << \" \" << order.id;\n    }\n    cout << endl;\n    \n    // Output route\n    cout << route.size();\n    for (const auto& point : route) {\n        cout << \" \" << point.x << \" \" << point.y;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u, v;\n    int d; // euclidean distance (rounded)\n    int l; // actual length (revealed online)\n    double ratio; // l/d ratio\n};\n\nvector<pair<int, int>> coords(N);\nvector<Edge> edges(M);\nvector<int> parent(N);\nint component_count = N;\n\nvoid init_union_find() {\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n}\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nbool unite(int x, int y) {\n    x = find(x);\n    y = find(y);\n    if (x == y) return false;\n    parent[x] = y;\n    component_count--;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read coordinates\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        \n        // Calculate euclidean distance\n        long long dx = coords[edges[i].u].first - coords[edges[i].v].first;\n        long long dy = coords[edges[i].u].second - coords[edges[i].v].second;\n        edges[i].d = (int)round(sqrt(dx * dx + dy * dy));\n    }\n    \n    init_union_find();\n    \n    // Process each edge as it comes\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        edges[i].l = l;\n        edges[i].ratio = (double)l / edges[i].d;\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        // Check if this edge connects two different components\n        bool would_connect = (find(u) != find(v));\n        \n        bool accept = false;\n        \n        // Always accept edges that connect different components until we have a spanning tree\n        if (would_connect && component_count > 1) {\n            accept = true;\n        }\n        // For remaining edges, be selective based on cost efficiency\n        else if (component_count == 1) {\n            // Even after connectivity, accept very cheap edges that could improve the tree\n            // Only accept if significantly better than average\n            if (edges[i].ratio <= 1.3) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            unite(u, v);\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nconst int INF = 100000000;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Point pos;\n    int type;\n    Pet() : pos(0, 0), type(0) {}\n    Pet(Point p, int t) : pos(p), type(t) {}\n};\n\nstruct Human {\n    Point pos;\n    Human() : pos(0, 0) {}\n    Human(Point p) : pos(p) {}\n};\n\n// Directions: up, down, left, right\nconst vector<Point> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"UDLR\";\nconst string BLOCK_CHARS = \"udlr\";\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nvector<vector<int>> grid; // 0 = passable, 1 = blocked\nvector<vector<int>> pet_count; // count of pets in each cell\n\n// Check if position is valid\nbool valid(int x, int y) {\n    return x >= 1 && x <= H && y >= 1 && y <= W;\n}\n\nbool valid_point(Point p) {\n    return valid(p.x, p.y);\n}\n\n// Get adjacent points\nvector<Point> get_adjacent(Point p) {\n    vector<Point> adj;\n    for (auto& d : DIRS) {\n        Point np = {p.x + d.x, p.y + d.y};\n        if (valid_point(np)) {\n            adj.push_back(np);\n        }\n    }\n    return adj;\n}\n\n// BFS to calculate reachable area size from a point\nint calculate_area_size(Point start) {\n    if (!valid_point(start) || grid[start.x][start.y] == 1) return 0;\n    \n    vector<vector<bool>> visited(H + 1, vector<bool>(W + 1, false));\n    queue<Point> q;\n    q.push(start);\n    visited[start.x][start.y] = true;\n    int size = 0;\n    \n    while (!q.empty()) {\n        Point cur = q.front(); q.pop();\n        size++;\n        \n        for (auto& d : DIRS) {\n            Point next = {cur.x + d.x, cur.y + d.y};\n            if (valid_point(next) && !visited[next.x][next.y] && grid[next.x][next.y] == 0) {\n                visited[next.x][next.y] = true;\n                q.push(next);\n            }\n        }\n    }\n    \n    return size;\n}\n\n// Count pets in reachable area from a point\nint count_pets_in_area(Point start) {\n    if (!valid_point(start) || grid[start.x][start.y] == 1) return 0;\n    \n    vector<vector<bool>> visited(H + 1, vector<bool>(W + 1, false));\n    queue<Point> q;\n    q.push(start);\n    visited[start.x][start.y] = true;\n    int pet_count_area = 0;\n    \n    while (!q.empty()) {\n        Point cur = q.front(); q.pop();\n        pet_count_area += pet_count[cur.x][cur.y];\n        \n        for (auto& d : DIRS) {\n            Point next = {cur.x + d.x, cur.y + d.y};\n            if (valid_point(next) && !visited[next.x][next.y] && grid[next.x][next.y] == 0) {\n                visited[next.x][next.y] = true;\n                q.push(next);\n            }\n        }\n    }\n    \n    return pet_count_area;\n}\n\n// Simple heuristic: if we can block a square that limits pet movement, do it\nstring decide_actions(int turn) {\n    string actions(M, '.');\n    \n    // Update pet count grid\n    pet_count.assign(H + 1, vector<int>(W + 1, 0));\n    for (const auto& pet : pets) {\n        if (valid_point(pet.pos)) {\n            pet_count[pet.pos.x][pet.pos.y]++;\n        }\n    }\n    \n    // Early turns: just observe and move away from pets\n    if (turn < 50) {\n        for (int i = 0; i < M; i++) {\n            // Move away from nearby pets if possible\n            Point cur = humans[i].pos;\n            bool moved = false;\n            \n            // Check if any pet is adjacent\n            for (auto& pet : pets) {\n                if (abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y) <= 2) {\n                    // Try to move away\n                    for (int d = 0; d < 4; d++) {\n                        Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                        if (valid_point(next) && grid[next.x][next.y] == 0) {\n                            // Check if this move takes us away from pets\n                            int dist_to_pet = abs(pet.pos.x - next.x) + abs(pet.pos.y - next.y);\n                            int cur_dist = abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y);\n                            if (dist_to_pet > cur_dist) {\n                                actions[i] = DIR_CHARS[d];\n                                moved = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (moved) break;\n                }\n            }\n            \n            // If we didn't move, try to block strategically\n            if (!moved && turn > 20) {\n                for (int d = 0; d < 4; d++) {\n                    Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                        // Don't block if pet is adjacent to the square we want to block\n                        bool pet_adjacent = false;\n                        for (auto& pet : pets) {\n                            if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                                pet_adjacent = true;\n                                break;\n                            }\n                        }\n                        if (!pet_adjacent) {\n                            actions[i] = BLOCK_CHARS[d];\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    // Mid game: start creating barriers\n    else if (turn < 200) {\n        for (int i = 0; i < M; i++) {\n            Point cur = humans[i].pos;\n            \n            // Try to block to create isolated areas\n            // Prefer blocking squares that separate areas with fewer pets\n            vector<pair<int, int>> candidates; // {score, direction}\n            \n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                    // Don't block if pet is adjacent\n                    bool pet_adjacent = false;\n                    for (auto& pet : pets) {\n                        if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                            pet_adjacent = true;\n                            break;\n                        }\n                    }\n                    if (!pet_adjacent) {\n                        // Score based on potential to create good areas\n                        grid[block_pos.x][block_pos.y] = 1;\n                        int area_size = calculate_area_size(cur);\n                        int pet_count_area = count_pets_in_area(cur);\n                        grid[block_pos.x][block_pos.y] = 0;\n                        \n                        double score = (double)area_size / (1 + pet_count_area);\n                        candidates.push_back({(int)(score * 1000), d});\n                    }\n                }\n            }\n            \n            if (!candidates.empty()) {\n                sort(candidates.rbegin(), candidates.rend());\n                actions[i] = BLOCK_CHARS[candidates[0].second];\n            } else {\n                // If no good blocking, try to move to better position\n                int best_score = -1;\n                int best_dir = -1;\n                \n                for (int d = 0; d < 4; d++) {\n                    Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                    if (valid_point(next) && grid[next.x][next.y] == 0) {\n                        int area_size = calculate_area_size(next);\n                        int pet_count_area = count_pets_in_area(next);\n                        int score = area_size - pet_count_area * 10;\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_dir = d;\n                        }\n                    }\n                }\n                \n                if (best_dir != -1) {\n                    actions[i] = DIR_CHARS[best_dir];\n                }\n            }\n        }\n    }\n    // Late game: optimize final positions\n    else {\n        for (int i = 0; i < M; i++) {\n            Point cur = humans[i].pos;\n            \n            // Calculate current situation\n            int current_area = calculate_area_size(cur);\n            int current_pets = count_pets_in_area(cur);\n            double current_score = (double)current_area / 900.0 * pow(2.0, -current_pets);\n            \n            // Try all possible actions and pick the best\n            double best_score = current_score;\n            char best_action = '.';\n            \n            // Try blocking\n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                    // Don't block if pet is adjacent\n                    bool pet_adjacent = false;\n                    for (auto& pet : pets) {\n                        if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                            pet_adjacent = true;\n                            break;\n                        }\n                    }\n                    if (!pet_adjacent) {\n                        grid[block_pos.x][block_pos.y] = 1;\n                        int new_area = calculate_area_size(cur);\n                        int new_pets = count_pets_in_area(cur);\n                        double new_score = (double)new_area / 900.0 * pow(2.0, -new_pets);\n                        grid[block_pos.x][block_pos.y] = 0;\n                        \n                        if (new_score > best_score) {\n                            best_score = new_score;\n                            best_action = BLOCK_CHARS[d];\n                        }\n                    }\n                }\n            }\n            \n            // Try moving\n            for (int d = 0; d < 4; d++) {\n                Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(next) && grid[next.x][next.y] == 0) {\n                    int new_area = calculate_area_size(next);\n                    int new_pets = count_pets_in_area(next);\n                    double new_score = (double)new_area / 900.0 * pow(2.0, -new_pets);\n                    \n                    if (new_score > best_score) {\n                        best_score = new_score;\n                        best_action = DIR_CHARS[d];\n                    }\n                }\n            }\n            \n            actions[i] = best_action;\n        }\n    }\n    \n    return actions;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Initialize grid\n    grid.assign(H + 1, vector<int>(W + 1, 0));\n    \n    // Read initial positions\n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t;\n        cin >> x >> y >> t;\n        pets[i] = Pet(Point(x, y), t);\n    }\n    \n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        humans[i] = Human(Point(x, y));\n    }\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // Decide actions\n        string actions = decide_actions(turn);\n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        string pet_moves;\n        getline(cin, pet_moves);\n        if (pet_moves.empty()) {\n            getline(cin, pet_moves);\n        }\n        \n        stringstream ss(pet_moves);\n        string move;\n        for (int i = 0; i < N && ss >> move; i++) {\n            // Update pet position based on movement\n            for (char c : move) {\n                switch (c) {\n                    case 'U': pets[i].pos.x--; break;\n                    case 'D': pets[i].pos.x++; break;\n                    case 'L': pets[i].pos.y--; break;\n                    case 'R': pets[i].pos.y++; break;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint si, sj, ti, tj;\ndouble p;\nbool h_wall[N][N-1]; // horizontal walls\nbool v_wall[N-1][N]; // vertical walls\n\n// Direction mappings\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nbool can_move(int x, int y, int dir) {\n    if (dir == 0) { // Up\n        if (x == 0) return false;\n        return !v_wall[x-1][y];\n    } else if (dir == 1) { // Down\n        if (x == N-1) return false;\n        return !v_wall[x][y];\n    } else if (dir == 2) { // Left\n        if (y == 0) return false;\n        return !h_wall[x][y-1];\n    } else { // Right\n        if (y == N-1) return false;\n        return !h_wall[x][y];\n    }\n}\n\n// Create a robust path using a strategy that builds in redundancy\nstring create_robust_path() {\n    string path;\n    \n    // Strategy: Create a path with built-in redundancy\n    // We'll use a \"thick path\" approach where we don't just follow\n    // the shortest route, but create a wider corridor\n    \n    int x = si, y = sj;\n    \n    // Since home is in top-left (0-4, 0-4) and office is in bottom-right (15-19, 15-19)\n    // We generally want to go right and down\n    \n    // Main strategy:\n    // 1. Go right in a robust manner\n    // 2. Go down in a robust manner\n    // 3. Fine-tune to exact position\n    \n    // Phase 1: Move toward target column with redundancy\n    while (y < tj && path.length() < 180) {\n        if (can_move(x, y, 3)) { // Right\n            path += 'R';\n            y++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try down then right\n            if (x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n                moved = true;\n            } else if (x > 0 && can_move(x, y, 0)) {\n                path += 'U';\n                x--;\n                moved = true;\n            }\n            \n            if (moved && y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n            } else if (moved) {\n                // Undo the vertical move if we can't go right\n                if (x > si) {\n                    path += 'U';\n                    x--;\n                } else {\n                    path += 'D';\n                    x++;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Move toward target row with redundancy\n    while (x < ti && path.length() < 195) {\n        if (can_move(x, y, 1)) { // Down\n            path += 'D';\n            x++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try right then down\n            if (y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n                moved = true;\n            } else if (y > 0 && can_move(x, y, 2)) {\n                path += 'L';\n                y--;\n                moved = true;\n            }\n            \n            if (moved && x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n            } else if (moved) {\n                // Undo the horizontal move if we can't go down\n                if (y > sj) {\n                    path += 'L';\n                    y--;\n                } else {\n                    path += 'R';\n                    y++;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Fine adjustment\n    while ((x != ti || y != tj) && path.length() < 200) {\n        if (x < ti && can_move(x, y, 1)) {\n            path += 'D';\n            x++;\n        } else if (x > ti && can_move(x, y, 0)) {\n            path += 'U';\n            x--;\n        } else if (y < tj && can_move(x, y, 3)) {\n            path += 'R';\n            y++;\n        } else if (y > tj && can_move(x, y, 2)) {\n            path += 'L';\n            y--;\n        } else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Alternative approach: Create a path with explicit redundancy\nstring create_redundant_path() {\n    string path;\n    int x = si, y = sj;\n    \n    // Create a path where every few steps, we add a small loop\n    // This provides redundancy - if one move is forgotten, \n    // the loop gives us another chance\n    \n    int steps_since_loop = 0;\n    \n    while ((x != ti || y != tj) && path.length() < 200) {\n        // Determine best direction\n        int best_dir = -1;\n        int best_value = -1000;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(x, y, dir)) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                // Heuristic: prefer moves that get us closer to target\n                int value = -(abs(nx - ti) + abs(ny - tj));\n                \n                // Slight preference for right/down moves to maintain progress\n                if (dir == 1 || dir == 3) value += 1;\n                \n                if (value > best_value) {\n                    best_value = value;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            path += dir_char[best_dir];\n            x += dx[best_dir];\n            y += dy[best_dir];\n            steps_since_loop++;\n            \n            // Every few steps, add a small redundant loop if space allows\n            if (steps_since_loop >= 4 && path.length() < 190) {\n                // Try to add a small 2-step loop\n                int perpendicular_dir1 = (best_dir + 1) % 4;\n                int perpendicular_dir2 = (best_dir + 3) % 4;\n                \n                if (can_move(x, y, perpendicular_dir1) && \n                    can_move(x + dx[perpendicular_dir1], y + dy[perpendicular_dir1], \n                             (perpendicular_dir1 + 2) % 4) &&\n                    path.length() < 198) {\n                    path += dir_char[perpendicular_dir1];\n                    path += dir_char[(perpendicular_dir1 + 2) % 4];\n                    steps_since_loop = 0;\n                } else if (can_move(x, y, perpendicular_dir2) && \n                           can_move(x + dx[perpendicular_dir2], y + dy[perpendicular_dir2], \n                                    (perpendicular_dir2 + 2) % 4) &&\n                           path.length() < 198) {\n                    path += dir_char[perpendicular_dir2];\n                    path += dir_char[(perpendicular_dir2 + 2) % 4];\n                    steps_since_loop = 0;\n                }\n            }\n        } else {\n            break; // No valid moves\n        }\n    }\n    \n    return path;\n}\n\nint main() {\n    // Read input\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N-1; j++) {\n            h_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N-1; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            v_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Generate path - try the redundant approach\n    string result = create_redundant_path();\n    \n    // Fallback to simpler approach if needed\n    if (result.empty() || result.length() > 200) {\n        result = create_robust_path();\n    }\n    \n    // Ensure we don't exceed 200 characters\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction: 0=left, 1=up, 2=right, 3=down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Transition table: to[tile_type][entry_direction] = exit_direction (-1 if invalid)\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // tile 0\n    {3, -1, -1, 0},  // tile 1\n    {-1, -1, 3, 2},  // tile 2\n    {-1, 2, 1, -1},  // tile 3\n    {1, 0, 3, 2},    // tile 4\n    {3, 2, 1, 0},    // tile 5\n    {2, -1, 0, -1},  // tile 6\n    {-1, 3, -1, 1}   // tile 7\n};\n\nconst int N = 30;\nint grid[N][N];\nint rotation[N][N];\n\n// Get actual tile type after rotation\nint get_rotated_tile(int base_tile, int rot) {\n    static const int rotation_map[8][4] = {\n        {0, 1, 2, 3},  // tile 0\n        {1, 2, 3, 0},  // tile 1\n        {2, 3, 0, 1},  // tile 2\n        {3, 0, 1, 2},  // tile 3\n        {4, 5, 4, 5},  // tile 4\n        {5, 4, 5, 4},  // tile 5\n        {6, 7, 6, 7},  // tile 6\n        {7, 6, 7, 6}   // tile 7\n    };\n    return rotation_map[base_tile][rot % 4];\n}\n\n// Check if coordinates are valid\nbool valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\n// Find loop length starting from position (si,sj) entering from direction sd\nint find_loop_length(int si, int sj, int sd, bool visited[N][N][4]) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        if (visited[i][j][d]) return 0;  // Already part of another loop\n        visited[i][j][d] = true;\n        \n        int tile_type = get_rotated_tile(grid[i][j], rotation[i][j]);\n        int d2 = to[tile_type][d];\n        \n        if (d2 == -1) return 0;  // Broken line\n        \n        i += di[d2];\n        j += dj[d2];\n        \n        if (!valid(i, j)) return 0;  // Out of bounds\n        \n        d = (d2 + 2) % 4;  // Reverse direction\n        length++;\n        \n        if (length > 1000) return 0;  // Prevent infinite loops\n        \n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\n// Find all loops and return their lengths\nvector<int> find_all_loops() {\n    vector<int> loops;\n    bool visited[N][N][4] = {};\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int length = find_loop_length(i, j, d, visited);\n                    if (length > 0) {\n                        loops.push_back(length);\n                    }\n                }\n            }\n        }\n    }\n    \n    sort(loops.rbegin(), loops.rend());\n    return loops;\n}\n\n// Calculate score\nlong long calculate_score() {\n    vector<int> loops = find_all_loops();\n    if (loops.size() < 2) return 0;\n    return 1LL * loops[0] * loops[1];\n}\n\n// Fast incremental evaluation - only check loops that might be affected\nlong long fast_evaluate_change(int ci, int cj, int new_rot) {\n    int old_rot = rotation[ci][cj];\n    rotation[ci][cj] = new_rot;\n    \n    long long score = calculate_score();\n    \n    rotation[ci][cj] = old_rot;  // Restore\n    return score;\n}\n\n// Simple greedy improvement with limited iterations\nvoid greedy_improve() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    \n    long long best_score = calculate_score();\n    \n    // Limited iterations for speed\n    for (int iter = 0; iter < 10000; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        int best_rotation = old_rotation;\n        long long best_local_score = 0;\n        \n        // Try all 3 other rotations\n        for (int r = 1; r < 4; r++) {\n            int new_rot = (old_rotation + r) % 4;\n            long long score = fast_evaluate_change(i, j, new_rot);\n            if (score > best_local_score) {\n                best_local_score = score;\n                best_rotation = new_rot;\n            }\n        }\n        \n        if (best_local_score > best_score) {\n            rotation[i][j] = best_rotation;\n            best_score = best_local_score;\n        }\n    }\n}\n\n// Initialize with a simple pattern\nvoid initialize_simple() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            // Simple initialization - try to make some connectivity\n            if (grid[i][j] >= 4 && grid[i][j] <= 5) {\n                rotation[i][j] = 0;  // Double curves as is\n            } else if (grid[i][j] >= 6 && grid[i][j] <= 7) {\n                rotation[i][j] = 0;  // Straights as is\n            } else {\n                rotation[i][j] = 0;  // Curves as is\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Initialize\n    initialize_simple();\n    \n    // Improve using greedy approach\n    greedy_improve();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 10;\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst char inv_dir_chars[4] = {'D', 'U', 'R', 'L'};\n\nint N, T;\nint board[MAX_N][MAX_N];\nint empty_x, empty_y;\n\n// Check if two adjacent tiles are connected\nbool isConnected(int x1, int y1, int x2, int y2) {\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (board[x1][y1] == 0 || board[x2][y2] == 0) return false;\n    \n    // Check if they connect\n    if (x1 == x2 && y1 == y2 - 1) { // Right connection\n        return (board[x1][y1] & 4) && (board[x2][y2] & 1);\n    }\n    if (x1 == x2 && y1 == y2 + 1) { // Left connection\n        return (board[x1][y1] & 1) && (board[x2][y2] & 4);\n    }\n    if (x1 == x2 - 1 && y1 == y2) { // Down connection\n        return (board[x1][y1] & 8) && (board[x2][y2] & 2);\n    }\n    if (x1 == x2 + 1 && y1 == y2) { // Up connection\n        return (board[x1][y1] & 2) && (board[x2][y2] & 8);\n    }\n    return false;\n}\n\n// Find connected components and return the largest one\npair<vector<vector<bool>>, int> findComponents() {\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            vector<vector<bool>> current_visited(N, vector<bool>(N, false));\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            current_visited[i][j] = true;\n            visited[i][j] = true;\n            int size = 1;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                \n                // Check 4 neighbors\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dx[k];\n                    int ny = y + dy[k];\n                    \n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && \n                        !visited[nx][ny] && board[nx][ny] != 0 && \n                        isConnected(x, y, nx, ny)) {\n                        visited[nx][ny] = true;\n                        current_visited[nx][ny] = true;\n                        size++;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            if (size > max_size) {\n                max_size = size;\n            }\n        }\n    }\n    \n    return {visited, max_size};\n}\n\n// Calculate potential gain of a move\nint calculatePotentialGain(int from_x, int from_y) {\n    // Temporarily move the tile\n    int temp = board[from_x][from_y];\n    board[from_x][from_y] = 0;\n    board[empty_x][empty_y] = temp;\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    \n    // Find new component sizes\n    auto [visited, max_size] = findComponents();\n    \n    // Restore\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    board[empty_x][empty_y] = 0;\n    board[from_x][from_y] = temp;\n    \n    return max_size;\n}\n\n// Try to make a move\nbool makeMove(char move, string& result) {\n    int dir = -1;\n    for (int i = 0; i < 4; i++) {\n        if (dir_chars[i] == move) {\n            dir = i;\n            break;\n        }\n    }\n    \n    int new_x = empty_x + dx[dir];\n    int new_y = empty_y + dy[dir];\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) {\n        return false;\n    }\n    \n    // Perform move\n    board[empty_x][empty_y] = board[new_x][new_y];\n    board[new_x][new_y] = 0;\n    empty_x = new_x;\n    empty_y = new_y;\n    result += move;\n    \n    return true;\n}\n\n// Get current largest tree size\nint getCurrentTreeSize() {\n    auto [visited, max_size] = findComponents();\n    return max_size;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    \n    // Read board\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_x = i;\n                empty_y = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int last_dir = -1;\n    \n    // More sophisticated approach: try to build a large connected component\n    for (int step = 0; step < T && (int)result.length() < T; step++) {\n        int best_gain = -1;\n        int best_dir = -1;\n        \n        // Try all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            // Don't go back immediately\n            if (dir == (last_dir ^ 1)) continue;\n            \n            int from_x = empty_x + dx[dir];\n            int from_y = empty_y + dy[dir];\n            \n            if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n            \n            int gain = calculatePotentialGain(from_x, from_y);\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_dir = dir;\n            }\n        }\n        \n        // If no good move found, try without the reversal constraint\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                \n                if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n                \n                int gain = calculatePotentialGain(from_x, from_y);\n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        // If still no move, pick any valid move\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                if (from_x >= 0 && from_x < N && from_y >= 0 && from_y < N) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            makeMove(dir_chars[best_dir], result);\n            last_dir = best_dir;\n        } else {\n            break;\n        }\n        \n        // Early termination if we have a good solution\n        if (getCurrentTreeSize() >= N * N - 1 && result.length() < T * 0.8) {\n            break;\n        }\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing P = pair<int, int>;\n\nconst int MAX_N = 10000;\nconst int RADIUS = 10000;\nconst int BOUND = 1000000000;\n\nstruct Strawberry {\n    int x, y;\n    int id;\n};\n\nint N, K;\nint a[11]; // a[1] to a[10]\nvector<Strawberry> strawberries;\nvector<tuple<ll, ll, ll, ll>> best_lines;\n\n// Generate line through two points\ntuple<ll, ll, ll, ll> line_through_points(ll x1, ll y1, ll x2, ll y2) {\n    if (x1 == x2 && y1 == y2) {\n        x2 += 1;\n    }\n    return {x1, y1, x2, y2};\n}\n\n// Create lines to isolate individual strawberries\nvoid strategy_isolate_singles(vector<tuple<ll, ll, ll, ll>>& lines) {\n    int used = 0;\n    \n    // For each strawberry, try to create bounding box around it\n    for (int i = 0; i < min(K/4, (int)strawberries.size()) && used < K; i++) {\n        int x = strawberries[i].x;\n        int y = strawberries[i].y;\n        \n        // Create a small bounding box\n        if (used < K) {\n            lines.push_back(line_through_points(x - 50, y - 50, x + 50, y - 50)); // top\n            used++;\n        }\n        if (used < K) {\n            lines.push_back(line_through_points(x - 50, y + 50, x + 50, y + 50)); // bottom\n            used++;\n        }\n        if (used < K) {\n            lines.push_back(line_through_points(x - 50, y - 50, x - 50, y + 50)); // left\n            used++;\n        }\n        if (used < K) {\n            lines.push_back(line_through_points(x + 50, y - 50, x + 50, y + 50)); // right\n            used++;\n        }\n    }\n    \n    // Fill remaining with radial lines\n    while (used < K) {\n        double angle = 2.0 * M_PI * used / K;\n        ll px = (ll)(100000 * cos(angle));\n        ll py = (ll)(100000 * sin(angle));\n        ll qx = (ll)(-100000 * cos(angle));\n        ll qy = (ll)(-100000 * sin(angle));\n        lines.push_back({px, py, qx, qy});\n        used++;\n    }\n}\n\n// Create grid-based approach\nvoid strategy_grid(vector<tuple<ll, ll, ll, ll>>& lines) {\n    // Determine grid size based on number of strawberries\n    int grid_dim = max(2, min(10, (int)sqrt(N)));\n    \n    // Create horizontal lines\n    for (int i = 0; i <= grid_dim && lines.size() < K/2; i++) {\n        int y_pos = -RADIUS + (2 * RADIUS * i) / grid_dim;\n        lines.push_back(line_through_points(-BOUND, y_pos, BOUND, y_pos));\n    }\n    \n    // Create vertical lines\n    for (int i = 0; i <= grid_dim && lines.size() < K; i++) {\n        int x_pos = -RADIUS + (2 * RADIUS * i) / grid_dim;\n        lines.push_back(line_through_points(x_pos, -BOUND, x_pos, BOUND));\n    }\n    \n    // Fill remaining with random lines\n    while (lines.size() < K) {\n        ll px = rand() % (2 * BOUND) - BOUND;\n        ll py = rand() % (2 * BOUND) - BOUND;\n        ll qx = rand() % (2 * BOUND) - BOUND;\n        ll qy = rand() % (2 * BOUND) - BOUND;\n        if (px == qx && py == qy) qx += 1;\n        lines.push_back({px, py, qx, qy});\n    }\n}\n\n// Create radial approach\nvoid strategy_radial(vector<tuple<ll, ll, ll, ll>>& lines) {\n    for (int i = 0; i < K; i++) {\n        double angle = 2.0 * M_PI * i / K;\n        ll px = (ll)(100000 * cos(angle));\n        ll py = (ll)(100000 * sin(angle));\n        ll qx = (ll)(-100000 * cos(angle));\n        ll qy = (ll)(-100000 * sin(angle));\n        lines.push_back({px, py, qx, qy});\n    }\n}\n\n// Create clustering-based approach\nvoid strategy_clustering(vector<tuple<ll, ll, ll, ll>>& lines) {\n    if (strawberries.empty()) return;\n    \n    // Simple k-means like approach - sort and divide\n    vector<Strawberry> sorted_x = strawberries;\n    vector<Strawberry> sorted_y = strawberries;\n    \n    sort(sorted_x.begin(), sorted_x.end(), [](const Strawberry& a, const Strawberry& b) {\n        return a.x < b.x;\n    });\n    \n    sort(sorted_y.begin(), sorted_y.end(), [](const Strawberry& a, const Strawberry& b) {\n        return a.y < b.y;\n    });\n    \n    // Create dividing lines\n    int num_cuts = min(K, max(10, (int)sqrt(N)));\n    \n    // Vertical divisions\n    for (int i = 1; i < num_cuts && lines.size() < K/2; i++) {\n        int idx = (sorted_x.size() * i) / num_cuts;\n        if (idx > 0 && idx < sorted_x.size()) {\n            int x_pos = (sorted_x[idx-1].x + sorted_x[idx].x) / 2;\n            lines.push_back(line_through_points(x_pos, -BOUND, x_pos, BOUND));\n        }\n    }\n    \n    // Horizontal divisions\n    for (int i = 1; i < num_cuts && lines.size() < K; i++) {\n        int idx = (sorted_y.size() * i) / num_cuts;\n        if (idx > 0 && idx < sorted_y.size()) {\n            int y_pos = (sorted_y[idx-1].y + sorted_y[idx].y) / 2;\n            lines.push_back(line_through_points(-BOUND, y_pos, BOUND, y_pos));\n        }\n    }\n    \n    // Fill remaining\n    while (lines.size() < K) {\n        ll px = rand() % (2 * BOUND) - BOUND;\n        ll py = rand() % (2 * BOUND) - BOUND;\n        ll qx = rand() % (2 * BOUND) - BOUND;\n        ll qy = rand() % (2 * BOUND) - BOUND;\n        if (px == qx && py == qy) qx += 1;\n        lines.push_back({px, py, qx, qy});\n    }\n}\n\n// Mixed strategy - combine different approaches\nvoid strategy_mixed(vector<tuple<ll, ll, ll, ll>>& lines) {\n    if (strawberries.empty()) return;\n    \n    int quarter_k = K / 4;\n    \n    // Strategy 1: Some radial lines\n    for (int i = 0; i < min(quarter_k, K/4); i++) {\n        double angle = 2.0 * M_PI * i / max(1, quarter_k);\n        ll px = (ll)(100000 * cos(angle));\n        ll py = (ll)(100000 * sin(angle));\n        ll qx = (ll)(-100000 * cos(angle));\n        ll qy = (ll)(-100000 * sin(angle));\n        lines.push_back({px, py, qx, qy});\n    }\n    \n    // Strategy 2: Grid lines\n    int grid_size = min(5, (int)sqrt(K/2));\n    for (int i = 0; i <= grid_size && lines.size() < K/2; i++) {\n        int pos = -RADIUS + (2 * RADIUS * i) / max(1, grid_size);\n        lines.push_back(line_through_points(-BOUND, pos, BOUND, pos));\n    }\n    \n    for (int i = 0; i <= grid_size && lines.size() < 3*K/4; i++) {\n        int pos = -RADIUS + (2 * RADIUS * i) / max(1, grid_size);\n        lines.push_back(line_through_points(pos, -BOUND, pos, BOUND));\n    }\n    \n    // Strategy 3: Separator lines between strawberries\n    if (!strawberries.empty()) {\n        sort(strawberries.begin(), strawberries.end(), [](const Strawberry& a, const Strawberry& b) {\n            return a.x < b.x;\n        });\n        \n        for (int i = 1; i < min(10, (int)strawberries.size()) && lines.size() < K; i++) {\n            int mid_x = (strawberries[i-1].x + strawberries[i].x) / 2;\n            lines.push_back(line_through_points(mid_x, -BOUND, mid_x, BOUND));\n        }\n    }\n    \n    // Fill remaining with random\n    while (lines.size() < K) {\n        ll px = rand() % (2 * BOUND) - BOUND;\n        ll py = rand() % (2 * BOUND) - BOUND;\n        ll qx = rand() % (2 * BOUND) - BOUND;\n        ll qy = rand() % (2 * BOUND) - BOUND;\n        if (px == qx && py == qy) qx += 1;\n        lines.push_back({px, py, qx, qy});\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    srand(time(nullptr));\n    \n    cin >> N >> K;\n    \n    int total_demand = 0;\n    for (int d = 1; d <= 10; d++) {\n        cin >> a[d];\n        total_demand += a[d];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n    }\n    \n    // Try multiple strategies and pick a reasonable one\n    vector<tuple<ll, ll, ll, ll>> lines;\n    \n    // Use mixed strategy as it combines multiple approaches\n    strategy_mixed(lines);\n    \n    // Ensure we don't exceed K lines\n    if (lines.size() > K) {\n        lines.resize(K);\n    }\n    \n    // Output result\n    cout << lines.size() << \"\\n\";\n    for (const auto& line : lines) {\n        auto [px, py, qx, qy] = line;\n        cout << px << \" \" << py << \" \" << qx << \" \" << qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int MAX_N = 65;\nbool grid[MAX_N][MAX_N];\nint N, M;\nvector<pair<int, int>> initial_dots;\nvector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n// For time management\nauto start_time = high_resolution_clock::now();\nconst double TIME_LIMIT = 4.8;\n\n// Weight calculation\ninline long long weight(int x, int y) {\n    int c = (N - 1) / 2;\n    int dx = x - c;\n    int dy = y - c;\n    return (long long)dx * dx + (long long)dy * dy + 1;\n}\n\n// Check if we should stop due to time limit\nbool time_limit_exceeded() {\n    auto now = high_resolution_clock::now();\n    auto duration = duration_cast<milliseconds>(now - start_time);\n    return duration.count() > TIME_LIMIT * 1000;\n}\n\n// Check if a point is valid (within bounds)\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\n// Check if four points form a valid rectangle (axis-parallel or 45-degree)\nbool is_valid_rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check if it's a parallelogram first\n    if (x1 + x3 != x2 + x4 || y1 + y3 != y2 + y4) return false;\n    \n    // Calculate squared distances to check if it's a rectangle\n    long long d1 = (long long)(x2 - x1) * (x2 - x1) + (long long)(y2 - y1) * (y2 - y1);\n    long long d2 = (long long)(x3 - x2) * (x3 - x2) + (long long)(y3 - y2) * (y3 - y2);\n    long long d3 = (long long)(x4 - x3) * (x4 - x3) + (long long)(y4 - y3) * (y4 - y3);\n    long long d4 = (long long)(x1 - x4) * (x1 - x4) + (long long)(y1 - y4) * (y1 - y4);\n    \n    // All sides equal in pairs and diagonals equal\n    long long diag1 = (long long)(x3 - x1) * (x3 - x1) + (long long)(y3 - y1) * (y3 - y1);\n    long long diag2 = (long long)(x4 - x2) * (x4 - x2) + (long long)(y4 - y2) * (y4 - y2);\n    \n    if (!((d1 == d3 && d2 == d4) || (d1 == d2 && d3 == d4))) return false;\n    if (diag1 != diag2) return false;\n    \n    // Check if it's axis-parallel or 45-degree\n    int dx1 = x2 - x1, dy1 = y2 - y1;\n    int dx2 = x3 - x2, dy2 = y3 - y2;\n    \n    // Axis parallel: dx=0 or dy=0\n    // 45-degree: |dx| = |dy|\n    bool side1_valid = (dx1 == 0 || dy1 == 0 || abs(dx1) == abs(dy1));\n    bool side2_valid = (dx2 == 0 || dy2 == 0 || abs(dx2) == abs(dy2));\n    \n    return side1_valid && side2_valid;\n}\n\n// Check if there are no dots on the perimeter of the rectangle\nbool no_dots_on_perimeter(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Generate all points on the perimeter\n    vector<pair<int, int>> perimeter;\n    \n    // Side 1: from (x1,y1) to (x2,y2)\n    int dx = x2 - x1, dy = y2 - y1;\n    int steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x1 + (dx * i) / steps;\n            int y = y1 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Side 2: from (x2,y2) to (x3,y3)\n    dx = x3 - x2; dy = y3 - y2;\n    steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x2 + (dx * i) / steps;\n            int y = y2 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Side 3: from (x3,y3) to (x4,y4)\n    dx = x4 - x3; dy = y4 - y3;\n    steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x3 + (dx * i) / steps;\n            int y = y3 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Side 4: from (x4,y4) to (x1,y1)\n    dx = x1 - x4; dy = y1 - y4;\n    steps = max(abs(dx), abs(dy));\n    if (steps > 0) {\n        for (int i = 0; i <= steps; i++) {\n            int x = x4 + (dx * i) / steps;\n            int y = y4 + (dy * i) / steps;\n            perimeter.push_back({x, y});\n        }\n    }\n    \n    // Check if any of the perimeter points (except the 4 corners) have dots\n    set<pair<int, int>> corners = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    for (auto& p : perimeter) {\n        if (corners.count(p)) continue;\n        if (grid[p.first][p.second]) return false;\n    }\n    \n    return true;\n}\n\n// Simple approach: try all combinations\nvoid solve() {\n    // Collect all current dot positions\n    vector<pair<int, int>> dots;\n    for (int i = 0; i < M; i++) {\n        dots.push_back(initial_dots[i]);\n        grid[initial_dots[i].first][initial_dots[i].second] = true;\n    }\n    \n    // Try to add new dots\n    while (!time_limit_exceeded()) {\n        bool found = false;\n        \n        // Create a list of candidate positions sorted by weight (descending)\n        vector<tuple<long long, int, int>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    candidates.push_back({weight(x, y), x, y});\n                }\n            }\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Try each candidate position\n        for (auto& cand : candidates) {\n            if (time_limit_exceeded()) break;\n            \n            int x1 = get<1>(cand);\n            int y1 = get<2>(cand);\n            \n            // Try all combinations of 3 existing dots\n            int sz = dots.size();\n            for (int i = 0; i < sz && !found; i++) {\n                for (int j = i + 1; j < sz && !found; j++) {\n                    for (int k = j + 1; k < sz && !found; k++) {\n                        if (time_limit_exceeded()) return;\n                        \n                        int x2 = dots[i].first, y2 = dots[i].second;\n                        int x3 = dots[j].first, y3 = dots[j].second;\n                        int x4 = dots[k].first, y4 = dots[k].second;\n                        \n                        // Try all permutations of the 3 dots as p2, p3, p4\n                        vector<vector<int>> perms = {\n                            {x2, y2, x3, y3, x4, y4},\n                            {x2, y2, x4, y4, x3, y3},\n                            {x3, y3, x2, y2, x4, y4},\n                            {x3, y3, x4, y4, x2, y2},\n                            {x4, y4, x2, y2, x3, y3},\n                            {x4, y4, x3, y3, x2, y2}\n                        };\n                        \n                        for (auto& perm : perms) {\n                            // Check if these 4 points can form a valid rectangle\n                            if (is_valid_rectangle(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                if (no_dots_on_perimeter(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                    // Valid operation found\n                                    operations.push_back(make_tuple(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]));\n                                    grid[x1][y1] = true;\n                                    dots.push_back({x1, y1});\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!found) break; // No more valid operations\n    }\n}\n\nint main() {\n    start_time = high_resolution_clock::now();\n    \n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    initial_dots.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> initial_dots[i].first >> initial_dots[i].second;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" \n             << get<2>(op) << \" \" << get<3>(op) << \" \"\n             << get<4>(op) << \" \" << get<5>(op) << \" \"\n             << get<6>(op) << \" \" << get<7>(op) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 10;\nconst int TOTAL_CANDIES = 100;\n\n// Directions: F(forward/up), B(backward/down), L(left), R(right)\nconst vector<pair<int, int>> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"FBLR\";\n\nclass CandyBox {\nprivate:\n    vector<vector<int>> grid; // 0 = empty, 1,2,3 = flavors\n    vector<int> flavor_counts;\n\npublic:\n    CandyBox() : grid(GRID_SIZE, vector<int>(GRID_SIZE, 0)), flavor_counts(4, 0) {}\n\n    void place_candy(int pos, int flavor) {\n        int empty_count = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] == 0) {\n                    empty_count++;\n                    if (empty_count == pos) {\n                        grid[i][j] = flavor;\n                        flavor_counts[flavor]++;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulate tilting in given direction\n    void tilt(int dir_idx) {\n        auto [di, dj] = DIRS[dir_idx];\n        \n        if (dir_idx == 0) { // Forward (up) - move rows from top to bottom\n            for (int i = 0; i < GRID_SIZE; i++) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 1) { // Backward (down) - move rows from bottom to top\n            for (int i = GRID_SIZE - 1; i >= 0; i--) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 2) { // Left - move columns from left to right\n            for (int j = 0; j < GRID_SIZE; j++) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else { // Right - move columns from right to left\n            for (int j = GRID_SIZE - 1; j >= 0; j--) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        }\n    }\n\nprivate:\n    void move_candy(int i, int j, int di, int dj) {\n        int flavor = grid[i][j];\n        grid[i][j] = 0;\n        \n        int ni = i + di, nj = j + dj;\n        while (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == 0) {\n            i = ni;\n            j = nj;\n            ni += di;\n            nj += dj;\n        }\n        \n        grid[i][j] = flavor;\n    }\n\npublic:\n    // Evaluate clustering quality\n    int evaluate_clustering() {\n        vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n        int total_score = 0;\n        \n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int component_size = dfs_component(i, j, grid[i][j], visited);\n                    total_score += component_size * component_size;\n                }\n            }\n        }\n        \n        return total_score;\n    }\n\nprivate:\n    int dfs_component(int i, int j, int flavor, vector<vector<bool>>& visited) {\n        if (i < 0 || i >= GRID_SIZE || j < 0 || j >= GRID_SIZE || \n            visited[i][j] || grid[i][j] != flavor) {\n            return 0;\n        }\n        \n        visited[i][j] = true;\n        int size = 1;\n        \n        // Check 4 adjacent cells\n        for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n            size += dfs_component(i + di, j + dj, flavor, visited);\n        }\n        \n        return size;\n    }\n\npublic:\n    CandyBox copy() const {\n        CandyBox new_box;\n        new_box.grid = grid;\n        new_box.flavor_counts = flavor_counts;\n        return new_box;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<int> flavors(TOTAL_CANDIES);\n    for (int i = 0; i < TOTAL_CANDIES; i++) {\n        cin >> flavors[i];\n    }\n    \n    CandyBox box;\n    \n    for (int t = 0; t < TOTAL_CANDIES; t++) {\n        int pos;\n        cin >> pos;\n        \n        // Place the candy\n        box.place_candy(pos, flavors[t]);\n        \n        if (t == TOTAL_CANDIES - 1) {\n            // No need to output direction for last candy\n            break;\n        }\n        \n        // Evaluate each possible tilt direction\n        int best_direction = 0;\n        int best_score = -1;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            CandyBox temp_box = box.copy();\n            temp_box.tilt(dir);\n            int score = temp_box.evaluate_clustering();\n            \n            if (score > best_score) {\n                best_score = score;\n                best_direction = dir;\n            }\n        }\n        \n        cout << DIR_CHARS[best_direction] << endl;\n        cout.flush();\n        \n        // Actually perform the tilt\n        box.tilt(best_direction);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <boost/graph/adjacency_list.hpp>\n#include <boost/graph/graph_traits.hpp>\n#include <Eigen/Dense>\n\nusing namespace std;\nusing namespace Eigen;\n\n// Fast I/O optimization\nstatic auto fast_io = []() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n    return 0;\n}();\n\nconst int MAX_N = 100;\nconst int MIN_N = 4;\n\n// Convert adjacency matrix to string representation\nstring graphToString(const vector<vector<int>>& adj, int n) {\n    string result;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            result += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return result;\n}\n\n// Convert string to adjacency matrix\nvector<vector<int>> stringToGraph(const string& s, int n) {\n    vector<vector<int>> adj(n, vector<int>(n, 0));\n    int idx = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[idx] == '1') {\n                adj[i][j] = adj[j][i] = 1;\n            }\n            idx++;\n        }\n    }\n    return adj;\n}\n\n// Calculate degree sequence histogram\nvector<int> getDegreeHistogram(const vector<vector<int>>& adj, int n) {\n    vector<int> degrees(n, 0);\n    for (int i = 0; i < n; ++i) {\n        degrees[i] = accumulate(adj[i].begin(), adj[i].end(), 0);\n    }\n    vector<int> hist(n, 0);\n    for (int d : degrees) {\n        if (d < n) hist[d]++;\n    }\n    return hist;\n}\n\n// Count triangles in graph\nint countTriangles(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (adj[i][j]) {\n                for (int k = j + 1; k < n; ++k) {\n                    if (adj[i][k] && adj[j][k]) {\n                        count++;\n                    }\n                }\n            }\n        }\n    }\n    return count;\n}\n\n// Count 4-cycles\nint count4Cycles(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (!adj[i][j]) continue;\n            for (int k = j + 1; k < n; ++k) {\n                if (!adj[j][k]) continue;\n                for (int l = k + 1; l < n; ++l) {\n                    if (adj[k][l] && adj[l][i]) {\n                        count++;\n                    }\n                }\n            }\n        }\n    }\n    return count;\n}\n\n// Calculate edge count\nint countEdges(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            count += adj[i][j];\n        }\n    }\n    return count;\n}\n\n// Generate diverse graphs for encoding\nvector<string> generateGraphs(int M, int N) {\n    vector<string> graphs;\n    \n    // Strategy: Create graphs with different structural properties\n    for (int k = 0; k < M; ++k) {\n        vector<vector<int>> adj(N, vector<int>(N, 0));\n        \n        // Different strategies based on k\n        if (k < M/4) {\n            // Sparse graphs - path-like structures\n            int edges = max(1, min(N-1, (k * (N-1)) / (M/4)));\n            for (int i = 0; i < edges && i < N-1; ++i) {\n                adj[i][i+1] = adj[i+1][i] = 1;\n            }\n        } else if (k < M/2) {\n            // Medium density - varying edge counts\n            int target_edges = ((k - M/4) * N * (N-1) / 8) / (M/4);\n            int edges_added = 0;\n            for (int i = 0; i < N && edges_added < target_edges; ++i) {\n                for (int j = i + 1; j < N && edges_added < target_edges; ++j) {\n                    if ((i + j + k) % 3 == 0) {\n                        adj[i][j] = adj[j][i] = 1;\n                        edges_added++;\n                    }\n                }\n            }\n        } else if (k < 3*M/4) {\n            // Higher density with specific patterns\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i * j + k) % 5 < 3) {\n                        adj[i][j] = adj[j][i] = 1;\n                    }\n                }\n            }\n        } else {\n            // Dense graphs with specific structures\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i + j + k) % 7 < 5) {\n                        adj[i][j] = adj[j][i] = 1;\n                    }\n                }\n            }\n        }\n        \n        graphs.push_back(graphToString(adj, N));\n    }\n    \n    return graphs;\n}\n\n// Precompute signatures for all template graphs\nstruct GraphSignature {\n    vector<int> degree_hist;\n    int edge_count;\n    int triangle_count;\n    int cycle4_count;\n};\n\nvector<GraphSignature> computeSignatures(const vector<string>& graphs, int N) {\n    vector<GraphSignature> signatures;\n    for (const string& g_str : graphs) {\n        auto adj = stringToGraph(g_str, N);\n        GraphSignature sig;\n        sig.degree_hist = getDegreeHistogram(adj, N);\n        sig.edge_count = countEdges(adj, N);\n        sig.triangle_count = countTriangles(adj, N);\n        sig.cycle4_count = count4Cycles(adj, N);\n        signatures.push_back(sig);\n    }\n    return signatures;\n}\n\n// Score how well a noisy graph matches a template signature\ndouble scoreMatch(const vector<vector<int>>& noisy_adj, \n                  const GraphSignature& template_sig, \n                  int N, double epsilon) {\n    // Get noisy graph properties\n    auto noisy_degree_hist = getDegreeHistogram(noisy_adj, N);\n    int noisy_edge_count = countEdges(noisy_adj, N);\n    int noisy_triangle_count = countTriangles(noisy_adj, N);\n    int noisy_cycle4_count = count4Cycles(noisy_adj, N);\n    \n    // Compute similarity score\n    double score = 0.0;\n    \n    // Degree histogram similarity\n    double degree_score = 0.0;\n    for (int i = 0; i < N; ++i) {\n        degree_score -= abs(noisy_degree_hist[i] - template_sig.degree_hist[i]);\n    }\n    score += degree_score * 2.0;\n    \n    // Edge count similarity (adjusted for expected noise)\n    double expected_noise = N * (N-1) / 2 * epsilon;\n    double edge_diff = abs(noisy_edge_count - template_sig.edge_count);\n    if (edge_diff <= 2 * expected_noise) {\n        score += (2 * expected_noise - edge_diff) / max(1.0, expected_noise);\n    }\n    \n    // Triangle count similarity (more sensitive to noise)\n    double triangle_diff = abs(noisy_triangle_count - template_sig.triangle_count);\n    score -= triangle_diff * 0.1;\n    \n    // 4-cycle similarity\n    double cycle4_diff = abs(noisy_cycle4_count - template_sig.cycle4_count);\n    score -= cycle4_diff * 0.05;\n    \n    return score;\n}\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n    \n    // Choose N based on M and epsilon\n    int N = min(50, max(10, M/2 + 10));  // Adaptive sizing\n    N = min(N, 100);\n    \n    // Generate template graphs\n    auto graphs = generateGraphs(M, N);\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute signatures\n    auto signatures = computeSignatures(graphs, N);\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        auto noisy_adj = stringToGraph(h_str, N);\n        \n        // Find best match\n        int best_match = 0;\n        double best_score = -1e9;\n        \n        for (int i = 0; i < M; ++i) {\n            double score = scoreMatch(noisy_adj, signatures[i], N, epsilon);\n            if (score > best_score) {\n                best_score = score;\n                best_match = i;\n            }\n        }\n        \n        cout << best_match << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int INF = 1e9;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<vector<pair<int, int>>> adj; // {to, weight}\nvector<vector<int>> dist;\n\n// Calculate all-pairs shortest paths\nvoid calcDistances() {\n    dist.assign(N, vector<int>(N, INF));\n    for (int i = 0; i < N; i++) {\n        dist[i][i] = 0;\n    }\n    \n    for (const auto& e : edges) {\n        dist[e.u][e.v] = min(dist[e.u][e.v], e.w);\n        dist[e.v][e.u] = min(dist[e.v][e.u], e.w);\n    }\n    \n    // Floyd-Warshall\n    for (int k = 0; k < N; k++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (dist[i][k] < INF && dist[k][j] < INF) {\n                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);\n                }\n            }\n        }\n    }\n}\n\n// Calculate frustration for a specific day (edge set removal)\ndouble calculateFrustration(const vector<int>& removed_edges) {\n    // Create temporary adjacency list without removed edges\n    vector<vector<pair<int, int>>> temp_adj(N);\n    vector<bool> removed(M, false);\n    \n    for (int eid : removed_edges) {\n        removed[eid] = true;\n    }\n    \n    for (const auto& e : edges) {\n        if (!removed[e.id]) {\n            temp_adj[e.u].push_back({e.v, e.w});\n            temp_adj[e.v].push_back({e.u, e.w});\n        }\n    }\n    \n    double total_increase = 0.0;\n    int count = 0;\n    \n    // For a subset of vertex pairs to speed up calculation\n    vector<int> sample_vertices;\n    for (int i = 0; i < N && i < 100; i++) {\n        sample_vertices.push_back(i);\n    }\n    \n    for (int i : sample_vertices) {\n        // Dijkstra from vertex i\n        vector<int> d(N, INF);\n        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n        d[i] = 0;\n        pq.push({0, i});\n        \n        while (!pq.empty()) {\n            auto [cur_dist, u] = pq.top(); pq.pop();\n            if (cur_dist > d[u]) continue;\n            \n            for (auto& [v, w] : temp_adj[u]) {\n                if (d[u] + w < d[v]) {\n                    d[v] = d[u] + w;\n                    pq.push({d[v], v});\n                }\n            }\n        }\n        \n        for (int j = 0; j < N; j++) {\n            if (i != j) {\n                int original_dist = dist[i][j];\n                int new_dist = d[j];\n                if (new_dist >= INF) new_dist = INF;\n                total_increase += max(0, new_dist - original_dist);\n                count++;\n            }\n        }\n    }\n    \n    return count > 0 ? total_increase / count : 0.0;\n}\n\n// Simple greedy approach based on edge betweenness-like metric\nvector<int> assignDays() {\n    vector<int> result(M);\n    vector<pair<double, int>> edge_scores(M);\n    \n    // Calculate a simple importance score for each edge\n    // Higher score = more important (should be repaired later)\n    for (int i = 0; i < M; i++) {\n        const auto& e = edges[i];\n        // Simple heuristic: edges with lower weights might be more critical\n        // But also consider degree of vertices\n        int degree_sum = 0;\n        for (const auto& adj_edge : adj[e.u]) degree_sum++;\n        for (const auto& adj_edge : adj[e.v]) degree_sum++;\n        \n        // Lower weight and higher degree = more critical\n        edge_scores[i] = {1.0 / (e.w * degree_sum), i};\n    }\n    \n    sort(edge_scores.begin(), edge_scores.end());\n    \n    // Assign days: less critical edges first\n    int edges_per_day = (M + D - 1) / D;\n    if (edges_per_day > K) edges_per_day = K;\n    \n    for (int i = 0; i < M; i++) {\n        int edge_id = edge_scores[i].second;\n        int day = min(i / K, D - 1);\n        result[edge_id] = day + 1; // Days are 1-indexed\n    }\n    \n    // Ensure constraint: at most K edges per day\n    vector<int> day_count(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_count[result[i]]++;\n    }\n    \n    // Fix violations\n    for (int day = 1; day <= D; day++) {\n        if (day_count[day] > K) {\n            // Move excess edges to other days\n            int excess = day_count[day] - K;\n            for (int i = 0; i < M && excess > 0; i++) {\n                if (result[i] == day) {\n                    // Try to find a day with space\n                    for (int new_day = 1; new_day <= D; new_day++) {\n                        if (day_count[new_day] < K) {\n                            result[i] = new_day;\n                            day_count[day]--;\n                            day_count[new_day]++;\n                            excess--;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Improved approach: consider impact of edge removal\nvector<int> improvedAssignDays() {\n    vector<int> result(M);\n    \n    // Calculate edge \"importance\" based on how much damage they do when removed\n    vector<pair<double, int>> edge_importance(M);\n    \n    for (int i = 0; i < M; i++) {\n        double importance = 0.0;\n        \n        // Sample-based estimation of edge importance\n        const int SAMPLE_SIZE = min(50, N);\n        for (int s = 0; s < SAMPLE_SIZE; s++) {\n            int u = rand() % N;\n            int v = rand() % N;\n            if (u == v) continue;\n            \n            // Original distance\n            int orig_dist = dist[u][v];\n            \n            // Estimate impact if this edge is removed\n            // This is a simplified approximation\n            importance += 1.0 / (orig_dist + 1);\n        }\n        \n        edge_importance[i] = {-importance, i}; // Negative because lower importance = better to repair early\n    }\n    \n    sort(edge_importance.begin(), edge_importance.end());\n    \n    // Assign to days ensuring constraints\n    vector<vector<int>> day_edges(D);\n    \n    // Distribute edges across days\n    for (int i = 0; i < M; i++) {\n        int edge_id = edge_importance[i].second;\n        // Try to place in earliest possible day\n        bool placed = false;\n        for (int day = 0; day < D; day++) {\n            if (day_edges[day].size() < K) {\n                day_edges[day].push_back(edge_id);\n                result[edge_id] = day + 1;\n                placed = true;\n                break;\n            }\n        }\n        // If all days are full, place in last day (shouldn't happen due to constraints)\n        if (!placed) {\n            day_edges[D-1].push_back(edge_id);\n            result[edge_id] = D;\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 >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--; // Convert to 0-indexed\n        edges[i] = {u, v, w, i};\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Build adjacency list\n    adj.assign(N, vector<pair<int, int>>());\n    for (const auto& e : edges) {\n        adj[e.u].push_back({e.v, e.w});\n        adj[e.v].push_back({e.u, e.w});\n    }\n    \n    // Calculate initial distances\n    calcDistances();\n    \n    // Assign days\n    vector<int> result = improvedAssignDays();\n    \n    // Output result\n    for (int i = 0; i < M; i++) {\n        cout << result[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_D = 14;\nint D;\nchar f[2][MAX_D][MAX_D];\nchar r[2][MAX_D][MAX_D];\n\n// 3D grid for each construction\nint b[2][MAX_D][MAX_D][MAX_D];\nvector<vector<pair<int,int>>> components[2];\n\n// For tracking connected components and creating actual blocks\nstruct Block {\n    vector<tuple<int,int,int>> cubes;\n    int id;\n};\n\nvector<Block> blocks;\nmap<vector<tuple<int,int,int>>, int> block_shapes; // To ensure consistent block IDs\n\n// Directions for 6-connectivity\nconst int dx[6] = {1, -1, 0, 0, 0, 0};\nconst int dy[6] = {0, 0, 1, -1, 0, 0};\nconst int dz[6] = {0, 0, 0, 0, 1, -1};\n\nbool isValid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n\n// Get connected component starting from (x,y,z)\nvector<tuple<int,int,int>> getComponent(int construction_id, int start_x, int start_y, int start_z,\n                                       vector<vector<vector<bool>>>& visited) {\n    vector<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push({start_x, start_y, start_z});\n    visited[start_x][start_y][start_z] = true;\n    component.push_back({start_x, start_y, start_z});\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front(); q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            \n            if (isValid(nx, ny, nz) && !visited[nx][ny][nz] && b[construction_id][nx][ny][nz] == 1) {\n                visited[nx][ny][nz] = true;\n                q.push({nx, ny, nz});\n                component.push_back({nx, ny, nz});\n            }\n        }\n    }\n    \n    return component;\n}\n\n// Normalize block shape for comparison (translate to origin)\nvector<tuple<int,int,int>> normalizeShape(vector<tuple<int,int,int>>& shape) {\n    if (shape.empty()) return shape;\n    \n    int min_x = get<0>(shape[0]), min_y = get<1>(shape[0]), min_z = get<2>(shape[0]);\n    \n    for (auto& cube : shape) {\n        min_x = min(min_x, get<0>(cube));\n        min_y = min(min_y, get<1>(cube));\n        min_z = min(min_z, get<2>(cube));\n    }\n    \n    vector<tuple<int,int,int>> normalized;\n    for (auto& cube : shape) {\n        normalized.push_back({get<0>(cube) - min_x, get<1>(cube) - min_y, get<2>(cube) - min_z});\n    }\n    \n    sort(normalized.begin(), normalized.end());\n    return normalized;\n}\n\nint getOrCreateBlock(vector<tuple<int,int,int>>& shape) {\n    auto normalized = normalizeShape(shape);\n    \n    if (block_shapes.find(normalized) != block_shapes.end()) {\n        return block_shapes[normalized];\n    } else {\n        int new_id = blocks.size() + 1;\n        block_shapes[normalized] = new_id;\n        blocks.push_back({normalized, new_id});\n        return new_id;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read input\n    for (int i = 0; i < 2; i++) {\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int x = 0; x < D; x++) {\n                f[i][z][x] = line[x];\n            }\n        }\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int y = 0; y < D; y++) {\n                r[i][z][y] = line[y];\n            }\n        }\n    }\n    \n    // Initialize grids\n    memset(b, 0, sizeof(b));\n    \n    // Create constructions - place unit cubes where both silhouettes allow\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                        b[i][x][y][z] = 1; // Mark as occupied\n                    }\n                }\n            }\n        }\n    }\n    \n    // Assign block IDs by finding connected components\n    int final_b[2][MAX_D][MAX_D][MAX_D] = {};\n    \n    for (int i = 0; i < 2; i++) {\n        vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (b[i][x][y][z] == 1 && !visited[x][y][z]) {\n                        auto component = getComponent(i, x, y, z, visited);\n                        int block_id = getOrCreateBlock(component);\n                        \n                        // Assign this block ID to all cubes in the component\n                        for (auto& cube : component) {\n                            final_b[i][get<0>(cube)][get<1>(cube)][get<2>(cube)] = block_id;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << blocks.size() << \"\\n\";\n    \n    for (int i = 0; i < 2; i++) {\n        bool first = true;\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (!first) cout << \" \";\n                    cout << final_b[i][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\nusing ld = long double;\nusing pii = pair<int, int>;\nusing pll = pair<ll, ll>;\n\nconst int MAX_N = 100;\nconst int MAX_M = 300;\nconst int MAX_K = 5000;\nconst int MAX_POWER = 5000;\n\nint N, M, K;\nvector<pair<int, int>> vertices;\nvector<tuple<int, int, int>> edges;\nvector<pair<int, int>> residents;\n\n// Distance calculation\nint euclidean_distance(int i, int j) {\n    int dx = vertices[i].first - vertices[j].first;\n    int dy = vertices[i].second - vertices[j].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\nint resident_to_vertex_distance(int res_idx, int vert_idx) {\n    int dx = residents[res_idx].first - vertices[vert_idx].first;\n    int dy = residents[res_idx].second - vertices[vert_idx].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\n// Find minimum spanning tree using Prim's algorithm\nvector<bool> find_mst_edges() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vertex_reached[0] = true; // Start from vertex 1 (index 0)\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    \n    // Add all edges from vertex 1\n    for (int j = 0; j < M; j++) {\n        auto [u, v, w] = edges[j];\n        u--; v--; // Convert to 0-indexed\n        if (u == 0) {\n            pq.push({w, v, j});\n        } else if (v == 0) {\n            pq.push({w, u, j});\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [weight, to, edge_idx] = pq.top();\n        pq.pop();\n        \n        if (vertex_reached[to]) continue;\n        \n        vertex_reached[to] = true;\n        edge_used[edge_idx] = true;\n        \n        // Add edges from newly reached vertex\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            if (u == to && !vertex_reached[v]) {\n                pq.push({w, v, j});\n            } else if (v == to && !vertex_reached[u]) {\n                pq.push({w, u, j});\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\n// Calculate minimum power needed for each vertex to cover residents\nvector<int> calculate_min_power(const vector<bool>& vertex_active) {\n    vector<int> power(N, 0);\n    vector<bool> covered(K, false);\n    \n    // First pass: calculate required power for each active vertex\n    for (int i = 0; i < N; i++) {\n        if (!vertex_active[i]) continue;\n        \n        int max_dist = 0;\n        for (int k = 0; k < K; k++) {\n            int dist = resident_to_vertex_distance(k, i);\n            if (dist <= MAX_POWER) {\n                max_dist = max(max_dist, dist);\n            }\n        }\n        power[i] = max_dist;\n    }\n    \n    // Greedy approach: iteratively improve coverage\n    for (int iter = 0; iter < 3; iter++) {\n        fill(covered.begin(), covered.end(), false);\n        \n        // Mark covered residents\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i] || power[i] == 0) continue;\n            for (int k = 0; k < K; k++) {\n                if (resident_to_vertex_distance(k, i) <= power[i]) {\n                    covered[k] = true;\n                }\n            }\n        }\n        \n        // Find uncovered residents\n        vector<int> uncovered;\n        for (int k = 0; k < K; k++) {\n            if (!covered[k]) uncovered.push_back(k);\n        }\n        \n        if (uncovered.empty()) break;\n        \n        // For each active vertex, see how much additional power helps\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i]) continue;\n            \n            int max_needed = 0;\n            for (int k : uncovered) {\n                int dist = resident_to_vertex_distance(k, i);\n                if (dist <= MAX_POWER) {\n                    max_needed = max(max_needed, dist);\n                }\n            }\n            power[i] = max(power[i], max_needed);\n        }\n    }\n    \n    return power;\n}\n\n// Improved approach: use a more sophisticated method\nvector<bool> improved_edge_selection() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vector<bool> resident_covered(K, false);\n    vertex_reached[0] = true;\n    \n    // Precompute resident distances to all vertices\n    vector<vector<int>> resident_distances(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resident_distances[k][i] = resident_to_vertex_distance(k, i);\n        }\n    }\n    \n    // Greedily select edges that maximize coverage efficiency\n    for (int step = 0; step < N - 1; step++) {\n        int best_edge = -1;\n        double best_efficiency = -1e18;\n        \n        // Find the best edge to add\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            \n            // Check if this edge connects a reached and unreached vertex\n            bool connects = (vertex_reached[u] && !vertex_reached[v]) || \n                           (vertex_reached[v] && !vertex_reached[u]);\n            \n            if (!connects) continue;\n            \n            int new_vertex = vertex_reached[u] ? v : u;\n            \n            // Calculate how many new residents this would cover\n            int new_coverage = 0;\n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k] && resident_distances[k][new_vertex] <= MAX_POWER) {\n                    new_coverage++;\n                }\n            }\n            \n            // Efficiency = coverage per cost\n            double efficiency = (double)new_coverage / max(w, 1);\n            \n            if (efficiency > best_efficiency) {\n                best_efficiency = efficiency;\n                best_edge = j;\n            }\n        }\n        \n        if (best_edge == -1) break;\n        \n        edge_used[best_edge] = true;\n        auto [u, v, w] = edges[best_edge];\n        u--; v--;\n        int new_vertex = vertex_reached[u] ? v : u;\n        vertex_reached[new_vertex] = true;\n        \n        // Update covered residents\n        for (int k = 0; k < K; k++) {\n            if (resident_distances[k][new_vertex] <= MAX_POWER) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    \n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    edges.resize(M);\n    for (int j = 0; j < M; j++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n    }\n    \n    residents.resize(K);\n    for (int k = 0; k < K; k++) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n    \n    // Select edges using improved approach\n    vector<bool> edge_used = improved_edge_selection();\n    \n    // Determine which vertices are active\n    vector<bool> vertex_active(N, false);\n    vertex_active[0] = true; // Always include vertex 1\n    \n    // BFS to find all reachable vertices\n    queue<int> q;\n    q.push(0);\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int j = 0; j < M; j++) {\n            if (!edge_used[j]) continue;\n            \n            auto [v1, v2, w] = edges[j];\n            v1--; v2--; // Convert to 0-indexed\n            \n            if (v1 == u && !vertex_active[v2]) {\n                vertex_active[v2] = true;\n                q.push(v2);\n            } else if (v2 == u && !vertex_active[v1]) {\n                vertex_active[v1] = true;\n                q.push(v1);\n            }\n        }\n    }\n    \n    // Calculate power requirements\n    vector<int> power = calculate_min_power(vertex_active);\n    \n    // Output results\n    for (int i = 0; i < N; i++) {\n        cout << power[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    for (int j = 0; j < M; j++) {\n        cout << (edge_used[j] ? 1 : 0);\n        if (j < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 10000;\nconst int TOTAL_BALLS = N * (N + 1) / 2;\n\nstruct Position {\n    int x, y;\n    Position() : x(0), y(0) {}\n    Position(int _x, int _y) : x(_x), y(_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\n// Directions for adjacency (6 directions in triangular grid)\nconst vector<pair<int, int>> DIRECTIONS = {\n    {-1, -1}, {-1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1}\n};\n\nclass Pyramid {\npublic:\n    int grid[N][N];\n    vector<pair<Position, Position>> operations;\n    \n    Pyramid() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                cin >> grid[i][j];\n            }\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y <= x;\n    }\n    \n    bool is_adjacent(int x1, int y1, int x2, int y2) {\n        for (auto& dir : DIRECTIONS) {\n            int nx = x1 + dir.first;\n            int ny = y1 + dir.second;\n            if (nx == x2 && ny == y2) return true;\n        }\n        return false;\n    }\n    \n    vector<Position> get_neighbors(int x, int y) {\n        vector<Position> neighbors;\n        for (auto& dir : DIRECTIONS) {\n            int nx = x + dir.first;\n            int ny = y + dir.second;\n            if (is_valid(nx, ny)) {\n                neighbors.emplace_back(nx, ny);\n            }\n        }\n        return neighbors;\n    }\n    \n    int count_violations() {\n        int count = 0;\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] > grid[i+1][j]) count++;\n                if (grid[i][j] > grid[i+1][j+1]) count++;\n            }\n        }\n        return count;\n    }\n    \n    void swap_balls(int x1, int y1, int x2, int y2) {\n        if (!is_adjacent(x1, y1, x2, y2)) return;\n        if (operations.size() >= MAX_OPS) return;\n        \n        swap(grid[x1][y1], grid[x2][y2]);\n        operations.emplace_back(Position(x1, y1), Position(x2, y2));\n    }\n    \n    // Find position of a specific value\n    Position find_position(int value) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] == value) {\n                    return Position(i, j);\n                }\n            }\n        }\n        return Position(-1, -1);\n    }\n    \n    void output() {\n        cout << operations.size() << \"\\n\";\n        for (auto& op : operations) {\n            cout << op.first.x << \" \" << op.first.y << \" \" \n                 << op.second.x << \" \" << op.second.y << \"\\n\";\n        }\n    }\n    \n    // Bubble sort approach: move larger elements down\n    void bubble_sort_approach() {\n        // Multiple passes of bubble sort-like approach\n        for (int pass = 0; pass < 20 && operations.size() < MAX_OPS - 10; pass++) {\n            bool changed = false;\n            \n            // Go through each level from top to bottom-1\n            for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 2; level++) {\n                // Go through each position in the level\n                for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 2; pos++) {\n                    int current = grid[level][pos];\n                    int left_child = grid[level+1][pos];\n                    int right_child = grid[level+1][pos+1];\n                    \n                    // If current is larger than either child, swap with the smaller child\n                    if (current > left_child || current > right_child) {\n                        if (left_child <= right_child) {\n                            swap_balls(level, pos, level+1, pos);\n                        } else {\n                            swap_balls(level, pos, level+1, pos+1);\n                        }\n                        changed = true;\n                    }\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n    \n    // Improved approach: work systematically level by level\n    void systematic_approach() {\n        // For each position, try to get the minimum valid value there\n        for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 5; level++) {\n            for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 5; pos++) {\n                // Ensure this position has value <= both children\n                int& current = grid[level][pos];\n                int& left_child = grid[level+1][pos];\n                int& right_child = grid[level+1][pos+1];\n                \n                // Keep swapping down while violation exists\n                while ((current > left_child || current > right_child) && operations.size() < MAX_OPS - 1) {\n                    if (current > left_child && (current > right_child ? left_child <= right_child : true)) {\n                        swap_balls(level, pos, level+1, pos);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else if (current > right_child) {\n                        swap_balls(level, pos, level+1, pos+1);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Local optimization: fix immediate violations\n    void local_optimization() {\n        bool improved = true;\n        int iterations = 0;\n        const int MAX_ITERATIONS = 50;\n        \n        while (improved && iterations < MAX_ITERATIONS && operations.size() < MAX_OPS - 10) {\n            improved = false;\n            iterations++;\n            \n            // Scan through all positions and fix violations\n            for (int i = 0; i < N - 1 && operations.size() < MAX_OPS - 2; i++) {\n                for (int j = 0; j <= i && operations.size() < MAX_OPS - 2; j++) {\n                    int current = grid[i][j];\n                    int left_child = grid[i+1][j];\n                    int right_child = grid[i+1][j+1];\n                    \n                    // Fix violations\n                    if (current > left_child || current > right_child) {\n                        // Swap with smaller child\n                        if (left_child <= right_child) {\n                            swap_balls(i, j, i+1, j);\n                        } else {\n                            swap_balls(i, j, i+1, j+1);\n                        }\n                        improved = true;\n                        if (operations.size() >= MAX_OPS - 2) break;\n                    }\n                }\n                if (operations.size() >= MAX_OPS - 2) break;\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    Pyramid pyramid;\n    pyramid.read_input();\n    \n    // Try multiple strategies\n    pyramid.systematic_approach();\n    pyramid.local_optimization();\n    pyramid.bubble_sort_approach();\n    pyramid.local_optimization();\n    \n    pyramid.output();\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int D = 9;\nconst int ENTRANCE_ROW = 0;\nconst int ENTRANCE_COL = 4;\n\nint N;\nbool is_obstacle[D][D];\nbool has_container[D][D];\nint container_number[D][D];\nvector<pair<int, int>> obstacles;\n\n// Directions: up, down, left, right\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\n\n// Check if coordinates are valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\n// Check if a cell is the entrance\nbool is_entrance(int x, int y) {\n    return x == ENTRANCE_ROW && y == ENTRANCE_COL;\n}\n\n// BFS to find all reachable empty cells from entrance\nvector<vector<bool>> get_reachable() {\n    vector<vector<bool>> reachable(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    reachable[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !has_container[nx][ny] && !reachable[nx][ny]) {\n                reachable[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\n// BFS to find all reachable cells with containers from entrance\nvector<pair<int, int>> get_reachable_containers() {\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    vector<pair<int, int>> result;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    visited[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        // If this cell has a container, add it to result\n        if (has_container[x][y]) {\n            result.push_back({x, y});\n        }\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Calculate Manhattan distance from entrance\nint manhattan_distance(int x, int y) {\n    return abs(x - ENTRANCE_ROW) + abs(y - ENTRANCE_COL);\n}\n\n// Find best position to place a container\npair<int, int> find_best_position(int container_num, int total_containers) {\n    auto reachable = get_reachable();\n    \n    pair<int, int> best_pos = {-1, -1};\n    double best_score = -1e18;\n    \n    // Try all positions\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            // Skip if it's entrance, obstacle, or already has container\n            if (is_entrance(i, j) || is_obstacle[i][j] || has_container[i][j]) {\n                continue;\n            }\n            \n            // Skip if not reachable\n            if (!reachable[i][j]) {\n                continue;\n            }\n            \n            // Calculate score based on multiple factors\n            double distance_score = -manhattan_distance(i, j) * 0.1;\n            double position_score = 0;\n            \n            // Prefer positions that are less likely to block others\n            // Count how many cells would become unreachable if we place container here\n            has_container[i][j] = true;\n            auto new_reachable = get_reachable();\n            has_container[i][j] = false;\n            \n            int blocked_count = 0;\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (!is_entrance(x, y) && !is_obstacle[x][y] && !has_container[x][y]) {\n                        if (reachable[x][y] && !new_reachable[x][y]) {\n                            blocked_count++;\n                        }\n                    }\n                }\n            }\n            \n            double blocking_penalty = -blocked_count * 0.5;\n            \n            // Prefer corners and edges for higher numbers\n            double edge_bonus = 0;\n            if (i == 0 || i == D-1 || j == 0 || j == D-1) {\n                edge_bonus = 0.2;\n            }\n            \n            // For later containers, prefer positions further from entrance\n            double adaptive_distance = (double)container_num / total_containers;\n            double adaptive_score = -(manhattan_distance(i, j) - 4 * adaptive_distance) * 0.1;\n            \n            double total_score = distance_score + blocking_penalty + edge_bonus + adaptive_score;\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_pos = {i, j};\n            }\n        }\n    }\n    \n    return best_pos;\n}\n\nint main() {\n    // Read input\n    cin >> D >> N;\n    \n    // Initialize arrays\n    memset(is_obstacle, false, sizeof(is_obstacle));\n    memset(has_container, false, sizeof(has_container));\n    \n    // Read obstacles\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        obstacles.push_back({r, c});\n    }\n    \n    int total_containers = D * D - 1 - N;\n    vector<pair<int, int>> placement_order(total_containers);\n    \n    // Process each container as it arrives\n    for (int d = 0; d < total_containers; d++) {\n        int container_num;\n        cin >> container_num;\n        \n        // Find best position\n        auto pos = find_best_position(container_num, total_containers);\n        \n        // Place container\n        has_container[pos.first][pos.second] = true;\n        container_number[pos.first][pos.second] = container_num;\n        placement_order[d] = pos;\n        \n        // Output position\n        cout << pos.first << \" \" << pos.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieve containers in optimal order\n    vector<pair<int, int>> retrieval_order;\n    vector<bool> transported(total_containers, false);\n    \n    // Greedy approach: always pick the smallest accessible container number\n    while (retrieval_order.size() < total_containers) {\n        auto reachable_containers = get_reachable_containers();\n        \n        // Find the container with minimum number among reachable ones\n        int min_num = INT_MAX;\n        pair<int, int> best_container = {-1, -1};\n        \n        for (auto& pos : reachable_containers) {\n            int num = container_number[pos.first][pos.second];\n            if (num < min_num) {\n                min_num = num;\n                best_container = pos;\n            }\n        }\n        \n        // Remove this container and add to retrieval order\n        has_container[best_container.first][best_container.second] = false;\n        retrieval_order.push_back(best_container);\n    }\n    \n    // Output retrieval order\n    for (auto& pos : retrieval_order) {\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n = 50, m = 100;\nint input_grid[N][N];\nint output_grid[N][N];\n\n// Adjacency information\nvector<set<int>> adj_list(M + 1);\nvector<vector<bool>> is_adj(M + 1, vector<bool>(M + 1, false));\n\n// Position information for each color\nvector<vector<pair<int, int>>> color_positions(M + 1);\n\n// Find connected components and adjacencies\nvoid analyze_input() {\n    // Collect positions for each color\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            color_positions[color].push_back({i, j});\n        }\n    }\n    \n    // Find adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            // Check 4 directions\n            int dx[] = {-1, 1, 0, 0};\n            int dy[] = {0, 0, -1, 1};\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int neighbor_color = input_grid[ni][nj];\n                    if (color != neighbor_color) {\n                        is_adj[color][neighbor_color] = true;\n                        is_adj[neighbor_color][color] = true;\n                        adj_list[color].insert(neighbor_color);\n                        adj_list[neighbor_color].insert(color);\n                    }\n                } else {\n                    // Boundary - adjacent to outside (color 0)\n                    is_adj[color][0] = true;\n                    is_adj[0][color] = true;\n                    adj_list[color].insert(0);\n                    adj_list[0].insert(color);\n                }\n            }\n        }\n    }\n}\n\n// Simple greedy approach: place colors in a compact way\nvoid generate_output() {\n    // Initialize output grid with 0s\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output_grid[i][j] = 0;\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from center\n    int center_x = N / 2;\n    int center_y = N / 2;\n    \n    // Place color 0 (outside) everywhere first\n    // Then we'll overwrite with other colors\n    \n    vector<bool> placed(M + 1, false);\n    placed[0] = true;\n    \n    // Place colors in order, trying to make them adjacent as required\n    queue<int> to_place;\n    set<int> remaining;\n    \n    for (int i = 1; i <= m; i++) {\n        remaining.insert(i);\n    }\n    \n    // Start with color 1 at center\n    output_grid[center_x][center_y] = 1;\n    placed[1] = true;\n    remaining.erase(1);\n    to_place.push(1);\n    \n    // BFS-like placement to maintain adjacencies\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    while (!to_place.empty() && !remaining.empty()) {\n        int current_color = to_place.front();\n        to_place.pop();\n        \n        // Find adjacent positions that are still 0\n        vector<pair<int, int>> adjacent_empty;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (output_grid[i][j] == current_color) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dx[k];\n                        int nj = j + dy[k];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            if (output_grid[ni][nj] == 0) {\n                                adjacent_empty.push_back({ni, nj});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Place adjacent colors\n        for (int adj_color : adj_list[current_color]) {\n            if (!placed[adj_color] && !remaining.empty() && find(remaining.begin(), remaining.end(), adj_color) != remaining.end()) {\n                if (!adjacent_empty.empty()) {\n                    auto pos = adjacent_empty.back();\n                    adjacent_empty.pop_back();\n                    output_grid[pos.first][pos.second] = adj_color;\n                    placed[adj_color] = true;\n                    remaining.erase(adj_color);\n                    to_place.push(adj_color);\n                }\n            }\n        }\n    }\n    \n    // Place any remaining colors\n    for (int color : remaining) {\n        // Find any empty spot\n        bool placed_color = false;\n        for (int i = 0; i < N && !placed_color; i++) {\n            for (int j = 0; j < N && !placed_color; j++) {\n                if (output_grid[i][j] == 0) {\n                    output_grid[i][j] = color;\n                    placed_color = true;\n                }\n            }\n        }\n    }\n    \n    // Expand each color to make connected regions\n    for (int color = 1; color <= m; color++) {\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_grid[i][j] == color) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.empty()) continue;\n        \n        // Use BFS to expand this color to make it more connected\n        queue<pair<int, int>> q;\n        set<pair<int, int>> visited;\n        \n        for (auto pos : positions) {\n            q.push(pos);\n            visited.insert(pos);\n        }\n        \n        int expansions = min(3, 20 - (int)positions.size()); // Limit expansion\n        int expanded = 0;\n        \n        while (!q.empty() && expanded < expansions) {\n            auto current = q.front();\n            q.pop();\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = current.first + dx[k];\n                int nj = current.second + dy[k];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (output_grid[ni][nj] == 0 && visited.find({ni, nj}) == visited.end()) {\n                        output_grid[ni][nj] = color;\n                        visited.insert({ni, nj});\n                        q.push({ni, nj});\n                        expanded++;\n                        if (expanded >= expansions) break;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input_grid[i][j];\n        }\n    }\n    \n    // Analyze the input to understand adjacencies\n    analyze_input();\n    \n    // Generate optimized output\n    generate_output();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << output_grid[i][j];\n            if (j < N - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 105;\nconst int INF = 1e9;\n\nint N, D, Q;\nvector<vector<int>> win_count, total_count;\nvector<double> weight_estimates;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to query the balance\nstring query(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 result;\n    cin >> result;\n    return result;\n}\n\n// Estimate weights using Bradley-Terry model approximation\nvoid estimate_weights() {\n    // Initialize comparison matrices\n    win_count.assign(N, vector<int>(N, 0));\n    total_count.assign(N, vector<int>(N, 0));\n    \n    // First, do pairwise comparisons for all items (if possible)\n    vector<pair<int, int>> all_pairs;\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            all_pairs.push_back({i, j});\n        }\n    }\n    \n    // Shuffle to randomize\n    shuffle(all_pairs.begin(), all_pairs.end(), rng);\n    \n    int queries_used = 0;\n    \n    // Phase 1: Pairwise comparisons\n    int pairwise_limit = min(Q / 2, (int)all_pairs.size());\n    for (int i = 0; i < pairwise_limit && queries_used < Q; i++) {\n        int a = all_pairs[i].first;\n        int b = all_pairs[i].second;\n        \n        vector<int> left = {a};\n        vector<int> right = {b};\n        string result = query(left, right);\n        queries_used++;\n        \n        total_count[a][b]++;\n        total_count[b][a]++;\n        \n        if (result == \">\") {\n            win_count[a][b]++;\n        } else if (result == \"<\") {\n            win_count[b][a]++;\n        }\n        // For '=' we can count as 0.5 each way\n    }\n    \n    // Phase 2: Group comparisons to refine estimates\n    while (queries_used < Q) {\n        // Compare random subsets\n        int subset_size = min(5, N / 2);\n        if (subset_size < 1) subset_size = 1;\n        \n        vector<int> left_items, right_items;\n        vector<bool> used(N, false);\n        \n        // Select random items for left side\n        int left_count = min(subset_size, N / 2);\n        for (int i = 0; i < left_count && left_items.size() < left_count; i++) {\n            int idx = rng() % N;\n            if (!used[idx]) {\n                left_items.push_back(idx);\n                used[idx] = true;\n            }\n        }\n        \n        // Select random items for right side\n        int right_count = min(subset_size, N - (int)left_items.size());\n        for (int i = 0; i < right_count && right_items.size() < right_count; i++) {\n            int idx = rng() % N;\n            if (!used[idx]) {\n                right_items.push_back(idx);\n                used[idx] = true;\n            }\n        }\n        \n        if (left_items.empty() || right_items.empty()) {\n            // Fallback to single item comparison\n            int a = rng() % N;\n            int b = rng() % N;\n            if (a == b) continue;\n            \n            vector<int> left = {a};\n            vector<int> right = {b};\n            string result = query(left, right);\n            queries_used++;\n            \n            total_count[a][b]++;\n            total_count[b][a]++;\n            \n            if (result == \">\") {\n                win_count[a][b]++;\n            } else if (result == \"<\") {\n                win_count[b][a]++;\n            }\n        } else {\n            string result = query(left_items, right_items);\n            queries_used++;\n            \n            // Update pairwise statistics based on group results\n            // This is a simplification - in practice we'd want to be more sophisticated\n            for (int a : left_items) {\n                for (int b : right_items) {\n                    total_count[a][b]++;\n                    total_count[b][a]++;\n                    \n                    if (result == \">\") {\n                        win_count[a][b]++;\n                    } else if (result == \"<\") {\n                        win_count[b][a]++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Estimate weights using win/loss ratios\n    weight_estimates.assign(N, 1.0);\n    \n    // Simple iterative approach: items that win more against others are heavier\n    for (int iter = 0; iter < 20; iter++) {\n        vector<double> new_weights(N, 0.0);\n        vector<double> normalizers(N, 0.0);\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i == j) continue;\n                if (total_count[i][j] > 0) {\n                    double win_rate = (double)win_count[i][j] / total_count[i][j];\n                    new_weights[i] += win_rate * weight_estimates[j];\n                    normalizers[i] += weight_estimates[j];\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            if (normalizers[i] > 0) {\n                weight_estimates[i] = max(0.1, new_weights[i] / normalizers[i]);\n            }\n        }\n        \n        // Normalize\n        double sum = 0;\n        for (int i = 0; i < N; i++) sum += weight_estimates[i];\n        if (sum > 0) {\n            for (int i = 0; i < N; i++) weight_estimates[i] = weight_estimates[i] * N / sum;\n        }\n    }\n}\n\n// Karmarkar-Karp differencing algorithm for balanced partitioning\nvector<int> karmarkar_karp_partition() {\n    vector<int> assignment(N, 0);\n    \n    // Create list of (weight, item_id) pairs\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.push_back({weight_estimates[i], i});\n    }\n    \n    // Sort by weight descending\n    sort(items.begin(), items.end());\n    reverse(items.begin(), items.end());\n    \n    // Use priority queue to implement Karmarkar-Karp\n    priority_queue<pair<double, vector<int>>> pq;\n    \n    // Initialize: each item in its own group\n    for (int i = 0; i < N; i++) {\n        vector<int> group = {items[i].second};\n        pq.push({items[i].first, group});\n    }\n    \n    // Combine the two heaviest groups until we have D groups\n    while (pq.size() > D) {\n        auto heaviest = pq.top(); pq.pop();\n        auto second_heaviest = pq.top(); pq.pop();\n        \n        // Merge groups (subtract because we're combining)\n        double new_weight = heaviest.first - second_heaviest.first;\n        vector<int> new_group = heaviest.second;\n        new_group.insert(new_group.end(), second_heaviest.second.begin(), second_heaviest.second.end());\n        \n        pq.push({new_weight, new_group});\n    }\n    \n    // Assign remaining groups\n    vector<vector<int>> final_groups;\n    while (!pq.empty()) {\n        final_groups.push_back(pq.top().second);\n        pq.pop();\n    }\n    \n    // Assign group numbers\n    for (int g = 0; g < min(D, (int)final_groups.size()); g++) {\n        for (int item : final_groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    // Handle any remaining items (shouldn't happen with KK)\n    for (int i = 0; i < N; i++) {\n        if (assignment[i] >= D) {\n            assignment[i] = D - 1;\n        }\n    }\n    \n    return assignment;\n}\n\n// Improved greedy with local search\nvector<int> improved_greedy_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Create list of items with their estimated weights\n    vector<pair<double, int>> items_with_weights;\n    for (int i = 0; i < N; i++) {\n        items_with_weights.push_back({weight_estimates[i], i});\n    }\n    \n    // Sort by weight (descending) to place heavier items first\n    sort(items_with_weights.rbegin(), items_with_weights.rend());\n    \n    // Initial assignment using multi-way partitioning\n    for (auto& item : items_with_weights) {\n        double weight = item.first;\n        int item_id = item.second;\n        \n        // Find group with minimum current sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    // Local search improvement\n    bool improved = true;\n    int iterations = 0;\n    const int MAX_ITERATIONS = 10000;\n    \n    while (improved && iterations < MAX_ITERATIONS) {\n        improved = false;\n        iterations++;\n        \n        // Try moving each item to a different group\n        for (int i = 0; i < N; i++) {\n            int current_group = assignment[i];\n            double item_weight = weight_estimates[i];\n            \n            // Try moving to each other group\n            for (int new_group = 0; new_group < D; new_group++) {\n                if (new_group == current_group) continue;\n                \n                // Calculate current variance contribution\n                double old_mean = 0;\n                for (int g = 0; g < D; g++) old_mean += group_sums[g];\n                old_mean /= D;\n                \n                double old_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    old_variance += (group_sums[g] - old_mean) * (group_sums[g] - old_mean);\n                }\n                old_variance /= D;\n                \n                // Simulate move\n                group_sums[current_group] -= item_weight;\n                group_sums[new_group] += item_weight;\n                \n                // Calculate new variance\n                double new_mean = 0;\n                for (int g = 0; g < D; g++) new_mean += group_sums[g];\n                new_mean /= D;\n                \n                double new_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    new_variance += (group_sums[g] - new_mean) * (group_sums[g] - new_mean);\n                }\n                new_variance /= D;\n                \n                // If improvement, keep the move\n                if (new_variance < old_variance - 1e-9) {  // Small epsilon for numerical stability\n                    assignment[i] = new_group;\n                    improved = true;\n                    break;\n                } else {\n                    // Revert move\n                    group_sums[current_group] += item_weight;\n                    group_sums[new_group] -= item_weight;\n                }\n            }\n            \n            if (improved) break;\n        }\n    }\n    \n    return assignment;\n}\n\n// Simple greedy as fallback\nvector<int> simple_greedy_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Pair items and assign pairs to balance groups\n    vector<pair<double, int>> sorted_items;\n    for (int i = 0; i < N; i++) {\n        sorted_items.push_back({weight_estimates[i], i});\n    }\n    \n    sort(sorted_items.begin(), sorted_items.end());\n    \n    // Assign items in pairs (largest with smallest) to balance groups\n    for (int i = 0; i < N; i++) {\n        int item_id = sorted_items[i].second;\n        double weight = sorted_items[i].first;\n        \n        // Find group with minimum sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Estimate weights using balance comparisons\n    estimate_weights();\n    \n    // Try different partitioning strategies and pick the best\n    vector<int> result1 = improved_greedy_partition();\n    vector<int> result2 = karmarkar_karp_partition();\n    vector<int> result3 = simple_greedy_partition();\n    \n    // Calculate variance for each result and pick the best\n    auto calculate_variance = [&](const vector<int>& assignment) -> double {\n        vector<double> group_sums(D, 0.0);\n        for (int i = 0; i < N; i++) {\n            group_sums[assignment[i]] += weight_estimates[i];\n        }\n        \n        double mean = 0;\n        for (int g = 0; g < D; g++) mean += group_sums[g];\n        mean /= D;\n        \n        double variance = 0;\n        for (int g = 0; g < D; g++) {\n            variance += (group_sums[g] - mean) * (group_sums[g] - mean);\n        }\n        variance /= D;\n        \n        return variance;\n    };\n    \n    double var1 = calculate_variance(result1);\n    double var2 = calculate_variance(result2);\n    double var3 = calculate_variance(result3);\n    \n    vector<int> best_result = result1;\n    double best_var = var1;\n    \n    if (var2 < best_var) {\n        best_result = result2;\n        best_var = var2;\n    }\n    \n    if (var3 < best_var) {\n        best_result = result3;\n        best_var = var3;\n    }\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        cout << best_result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 200;\nconst int M = 10;\nconst int STACK_SIZE = N / M;\n\nstruct State {\n    vector<deque<int>> stacks;\n    vector<pair<int, int>> box_positions; // {stack_idx, position_in_stack}\n    vector<bool> removed;\n    int total_energy = 0;\n    vector<pair<int, int>> operations;\n    \n    State() : stacks(M), box_positions(N + 1), removed(N + 1, false) {}\n    \n    void initialize() {\n        for (int i = 0; i < M; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                int box = stacks[i][j];\n                box_positions[box] = {i, j};\n            }\n        }\n    }\n    \n    bool is_top(int box) {\n        auto [stack_idx, pos] = box_positions[box];\n        return pos == (int)stacks[stack_idx].size() - 1;\n    }\n    \n    int stack_height(int stack_idx) {\n        return stacks[stack_idx].size();\n    }\n    \n    pair<int, int> find_box_position(int box) {\n        return box_positions[box];\n    }\n};\n\nclass Solver {\nprivate:\n    State state;\n    \npublic:\n    Solver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Move target box to top if not already there\n            while (!state.is_top(target)) {\n                auto [stack_idx, pos] = state.find_box_position(target);\n                int boxes_above = state.stack_height(stack_idx) - pos - 1;\n                \n                // Find best destination stack\n                int best_dest = -1;\n                int min_cost = INT_MAX;\n                \n                for (int dest = 0; dest < M; dest++) {\n                    if (dest == stack_idx) continue;\n                    \n                    // Cost is number of boxes moved + 1\n                    int cost = boxes_above + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_dest = dest;\n                    }\n                }\n                \n                if (best_dest == -1) {\n                    // Fallback: pick any different stack\n                    best_dest = (stack_idx + 1) % M;\n                }\n                \n                // Execute move\n                execute_move(target, best_dest);\n            }\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\n// Improved solver with better heuristics\nclass ImprovedSolver {\nprivate:\n    State state;\n    \npublic:\n    ImprovedSolver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Bring target to top with optimized strategy\n            bring_to_top(target);\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void bring_to_top(int target) {\n        while (!state.is_top(target)) {\n            auto [source_stack, pos] = state.find_box_position(target);\n            int boxes_above = state.stack_height(source_stack) - pos - 1;\n            \n            // Smart destination selection\n            int best_dest = find_best_destination(source_stack, boxes_above);\n            \n            // Execute move\n            execute_move(target, best_dest);\n        }\n    }\n    \n    int find_best_destination(int source_stack, int boxes_above) {\n        // Prefer stacks with fewer boxes to minimize future conflicts\n        int best_dest = -1;\n        int min_height = INT_MAX;\n        \n        for (int dest = 0; dest < M; dest++) {\n            if (dest == source_stack) continue;\n            \n            int height = state.stack_height(dest);\n            if (height < min_height) {\n                min_height = height;\n                best_dest = dest;\n            }\n        }\n        \n        // If all stacks are full, pick one that's not the source\n        if (best_dest == -1) {\n            best_dest = (source_stack + 1) % M;\n        }\n        \n        return best_dest;\n    }\n    \n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    ImprovedSolver solver(stacks);\n    vector<pair<int, int>> operations = solver.solve();\n    \n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\nbool visited[MAXN][MAXN];\n\n// Directions: Right, Down, Left, Up\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\n// Check if we can move from (i,j) to direction dir\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check for walls\n    if (dir == 0 || dir == 2) { // Horizontal move\n        return v[i][min(j, nj)] == '0';\n    } else { // Vertical move\n        return h[min(i, ni)][j] == '0';\n    }\n}\n\n// DFS with priority to high dirtiness squares\nvoid dfs_priority(int i, int j, string& path) {\n    visited[i][j] = true;\n    \n    // Create list of valid unvisited neighbors\n    vector<pair<int, int>> neighbors;\n    for (int dir = 0; dir < 4; dir++) {\n        if (!can_move(i, j, dir)) continue;\n        \n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj]) {\n            neighbors.push_back({d[ni][nj], dir});\n        }\n    }\n    \n    // Sort by dirtiness (descending)\n    sort(neighbors.begin(), neighbors.end(), greater<pair<int, int>>());\n    \n    for (auto& neighbor : neighbors) {\n        int dir = neighbor.second;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        path += dir_char[dir];\n        dfs_priority(ni, nj, path);\n        path += dir_char[(dir + 2) % 4]; // Return move\n    }\n}\n\n// Create a more sophisticated path by doing multiple DFS passes\nvoid create_path(string& path) {\n    // First, do a basic DFS to ensure all squares are visited\n    memset(visited, false, sizeof(visited));\n    dfs_priority(0, 0, path);\n    \n    // If we have space, add more visits to high-value squares\n    if (path.length() < 80000) {\n        // Add a second pass, but be more selective\n        // We could implement a more complex strategy here\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    // Read dirtiness values\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    string path = \"\";\n    create_path(path);\n    \n    // Make sure path isn't too long\n    if (path.length() > 100000) {\n        path = path.substr(0, 100000);\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\nint n, m;\nint start_i, start_j;\nchar grid[N][N];\nvector<string> targets;\nvector<pair<int,int>> char_positions[26];\n\n// Preprocessing to map characters to positions\nvoid preprocess() {\n    for (int i = 0; i < 26; i++) {\n        char_positions[i].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// Find best position for a character considering future characters\npair<int, int> find_best_position(const string& s, int start_idx, int cur_i, int cur_j) {\n    char c = s[start_idx];\n    int best_cost = 1e9;\n    pair<int, int> best_pos = {0, 0};\n    \n    // Look ahead a few characters to make better decisions\n    int lookahead = min(3, (int)s.length() - start_idx - 1);\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int cost = abs(pos.first - cur_i) + abs(pos.second - cur_j) + 1;\n        \n        // If we have characters ahead, consider their positions too\n        if (lookahead > 0) {\n            char next_c = s[start_idx + 1];\n            auto next_pos = find_best_position(s, start_idx + 1, pos.first, pos.second);\n            cost += abs(next_pos.first - pos.first) + abs(next_pos.second - pos.second) + 1;\n        }\n        \n        if (cost < best_cost) {\n            best_cost = cost;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Simple greedy approach for finding position\npair<int, int> find_closest(char c, int cur_i, int cur_j) {\n    int best_dist = 1e9;\n    pair<int, int> best_pos = {cur_i, cur_j}; // Default to current position\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int dist = abs(pos.first - cur_i) + abs(pos.second - cur_j);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Calculate overlap between two strings\nint calculate_overlap(const string& a, const string& b) {\n    int max_overlap = 0;\n    for (int i = 1; i <= min(a.length(), b.length()); i++) {\n        if (a.substr(a.length() - i) == b.substr(0, i)) {\n            max_overlap = i;\n        }\n    }\n    return max_overlap;\n}\n\n// Greedy shortest superstring construction\nstring construct_superstring() {\n    if (targets.empty()) return \"\";\n    \n    vector<string> strings = targets;\n    random_shuffle(strings.begin(), strings.end());\n    \n    // Try to merge strings with maximum overlap\n    while (strings.size() > 1) {\n        int max_overlap = -1;\n        int best_i = -1, best_j = -1;\n        string best_merged;\n        \n        int limit = min(50, (int)strings.size());\n        \n        // Check pairs for maximum overlap\n        for (int i = 0; i < limit; i++) {\n            for (int j = i + 1; j < limit; j++) {\n                // Try a + b\n                int overlap1 = calculate_overlap(strings[i], strings[j]);\n                string merged1 = strings[i] + strings[j].substr(overlap1);\n                \n                // Try b + a\n                int overlap2 = calculate_overlap(strings[j], strings[i]);\n                string merged2 = strings[j] + strings[i].substr(overlap2);\n                \n                if (overlap1 > max_overlap) {\n                    max_overlap = overlap1;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged1;\n                }\n                \n                if (overlap2 > max_overlap) {\n                    max_overlap = overlap2;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged2;\n                }\n            }\n        }\n        \n        if (best_i == -1) {\n            // No good overlap found, just concatenate first two\n            best_merged = strings[0] + strings[1];\n            best_i = 0;\n            best_j = 1;\n        }\n        \n        // Remove the two strings and add the merged one\n        if (best_i > best_j) swap(best_i, best_j);\n        strings.erase(strings.begin() + best_j);\n        strings.erase(strings.begin() + best_i);\n        strings.push_back(best_merged);\n    }\n    \n    return strings[0];\n}\n\n// Generate optimized path\nvector<pair<int, int>> generate_optimized_path(const string& s) {\n    vector<pair<int, int>> path;\n    int cur_i = start_i, cur_j = start_j;\n    \n    for (int i = 0; i < (int)s.length(); i++) {\n        auto pos = find_closest(s[i], cur_i, cur_j);\n        path.push_back(pos);\n        cur_i = pos.first;\n        cur_j = pos.second;\n    }\n    \n    return path;\n}\n\n// Count how many targets are contained\nint count_targets(const string& s) {\n    int count = 0;\n    for (const string& target : targets) {\n        if (s.find(target) != string::npos) {\n            count++;\n        }\n    }\n    return count;\n}\n\n// Try to ensure all targets are included\nstring ensure_all_targets(const string& s) {\n    string result = s;\n    vector<bool> covered(m, false);\n    \n    // Check which targets are already covered\n    for (int i = 0; i < m; i++) {\n        if (result.find(targets[i]) != string::npos) {\n            covered[i] = true;\n        }\n    }\n    \n    // Add missing targets\n    for (int i = 0; i < m; i++) {\n        if (!covered[i]) {\n            result += targets[i];\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 >> start_i >> start_j;\n    \n    for (int i = 0; i < n; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < n; j++) {\n            grid[i][j] = line[j];\n        }\n    }\n    \n    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i];\n    }\n    \n    preprocess();\n    \n    // Try multiple approaches and pick the best\n    string best_result;\n    int best_score = -1;\n    \n    // Approach 1: Greedy superstring\n    string superstring = construct_superstring();\n    superstring = ensure_all_targets(superstring);\n    \n    // Approach 2: Simple concatenation of some targets\n    string simple_concat;\n    for (int i = 0; i < min(50, m); i++) {\n        simple_concat += targets[i];\n    }\n    \n    // Choose the better approach based on coverage\n    int coverage1 = count_targets(superstring);\n    int coverage2 = count_targets(simple_concat);\n    \n    string final_string = (coverage1 >= coverage2) ? superstring : simple_concat;\n    \n    // Make sure we have all targets\n    final_string = ensure_all_targets(final_string);\n    \n    // If still too long, trim but keep as many targets as possible\n    if (final_string.length() > 2000) {\n        string trimmed;\n        int target_count = 0;\n        for (int i = 0; i < m && trimmed.length() < 1500; i++) {\n            if (trimmed.find(targets[i]) == string::npos) {\n                trimmed += targets[i];\n                target_count++;\n            }\n        }\n        final_string = trimmed;\n    }\n    \n    // Generate the path\n    auto path = generate_optimized_path(final_string);\n    \n    // Limit to maximum operations\n    if (path.size() > MAX_OPS) {\n        path.resize(MAX_OPS);\n    }\n    \n    // Output the path\n    for (const auto& pos : path) {\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\n#include <boost/random.hpp>\n#include <boost/random/normal_distribution.hpp>\n\nusing namespace std;\n\n// Random number generator\nboost::random::mt19937 gen;\n\nconst int MAX_N = 20;\nconst int MAX_M = 20;\n\nint N, M;\ndouble epsilon;\nvector<vector<pair<int,int>>> oil_fields;\nvector<vector<double>> prob; // Probability that each square has oil\nvector<vector<bool>> known;  // Whether we know for sure\nvector<vector<int>> actual_values; // For tracking actual values (if needed)\nint total_operations = 0;\nconst int MAX_OPERATIONS = 2 * MAX_N * MAX_N;\n\n// Normal distribution for divination errors\nboost::random::normal_distribution<> normal_dist(0.0, 1.0);\n\nvoid initialize() {\n    prob.assign(N, vector<double>(N, 0.0));\n    known.assign(N, vector<bool>(N, false));\n    actual_values.assign(N, vector<int>(N, 0));\n    \n    // Initialize with uniform probability based on field sizes\n    int total_area = 0;\n    for (const auto& field : oil_fields) {\n        total_area += field.size();\n    }\n    \n    double base_prob = min(1.0, (double)total_area / (N * N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            prob[i][j] = base_prob;\n        }\n    }\n}\n\n// Query single square\nint query_single(int i, int j) {\n    if (total_operations >= MAX_OPERATIONS) return -1;\n    \n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    total_operations++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\n// Query multiple squares\nint query_multiple(const vector<pair<int,int>>& squares) {\n    if (total_operations >= MAX_OPERATIONS) return -1;\n    if (squares.size() < 2) return -1;\n    \n    cout << \"q \" << squares.size();\n    for (const auto& sq : squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << endl;\n    cout.flush();\n    total_operations++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\n// Make a guess\nbool make_guess() {\n    vector<pair<int,int>> guess_squares;\n    \n    // Include all squares we've definitely seen have oil\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (known[i][j] && actual_values[i][j] > 0) {\n                guess_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    // Add high probability squares\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!known[i][j] && prob[i][j] > 0.3) {\n                bool already_added = false;\n                for (const auto& sq : guess_squares) {\n                    if (sq.first == i && sq.second == j) {\n                        already_added = true;\n                        break;\n                    }\n                }\n                if (!already_added) {\n                    guess_squares.push_back({i, j});\n                }\n            }\n        }\n    }\n    \n    if (guess_squares.empty()) {\n        // Fallback: guess all squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                guess_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    cout << \"a \" << guess_squares.size();\n    for (const auto& sq : guess_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << endl;\n    cout.flush();\n    total_operations++;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\n// Update probabilities based on divination result\nvoid update_probabilities(const vector<pair<int,int>>& squares, int observed_sum) {\n    // Simple heuristic: distribute the observed sum proportionally to current probabilities\n    double current_total_prob = 0;\n    for (const auto& sq : squares) {\n        current_total_prob += prob[sq.first][sq.second];\n    }\n    \n    if (current_total_prob > 0) {\n        double ratio = (double)observed_sum / max(1.0, current_total_prob);\n        ratio = max(0.0, min(2.0, ratio)); // Bound the ratio\n        \n        for (const auto& sq : squares) {\n            prob[sq.first][sq.second] *= ratio;\n            prob[sq.first][sq.second] = max(0.0, min(1.0, prob[sq.first][sq.second]));\n        }\n    }\n}\n\n// Find best divination group\nvector<pair<int,int>> find_best_divination_group(int group_size) {\n    vector<pair<int,int>> best_group;\n    double best_score = -1e9;\n    \n    // Try random groups\n    for (int attempt = 0; attempt < 100; attempt++) {\n        set<pair<int,int>> group_set;\n        vector<pair<int,int>> group;\n        \n        // Start with a random square\n        int start_i = gen() % N;\n        int start_j = gen() % N;\n        group_set.insert({start_i, start_j});\n        group.push_back({start_i, start_j});\n        \n        // Expand to nearby squares to keep it connected\n        for (int i = 1; i < group_size; i++) {\n            vector<pair<int,int>> candidates;\n            for (const auto& sq : group) {\n                for (int di = -1; di <= 1; di++) {\n                    for (int dj = -1; dj <= 1; dj++) {\n                        if (abs(di) + abs(dj) == 1) { // Adjacent\n                            int ni = sq.first + di;\n                            int nj = sq.second + dj;\n                            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                                if (group_set.find({ni, nj}) == group_set.end()) {\n                                    candidates.push_back({ni, nj});\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (!candidates.empty()) {\n                int idx = gen() % candidates.size();\n                group_set.insert(candidates[idx]);\n                group.push_back(candidates[idx]);\n            } else {\n                // If no adjacent candidates, pick any random available square\n                bool found = false;\n                for (int tries = 0; tries < 50 && !found; tries++) {\n                    int ri = gen() % N;\n                    int rj = gen() % N;\n                    if (group_set.find({ri, rj}) == group_set.end()) {\n                        group_set.insert({ri, rj});\n                        group.push_back({ri, rj});\n                        found = true;\n                    }\n                }\n                if (!found) break;\n            }\n        }\n        \n        if ((int)group.size() == group_size) {\n            // Score based on uncertainty (high entropy regions)\n            double score = 0;\n            for (const auto& sq : group) {\n                double p = prob[sq.first][sq.second];\n                // Higher score for mid-probability squares (most uncertain)\n                score += 0.5 - abs(p - 0.5);\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_group = group;\n            }\n        }\n    }\n    \n    return best_group;\n}\n\n// Strategic exploration\nvoid explore() {\n    // Phase 1: Coarse exploration with larger groups\n    for (int group_size = min(9, N*N/4); group_size >= 4 && total_operations < MAX_OPERATIONS * 0.3; group_size--) {\n        int queries_this_size = min(5, MAX_OPERATIONS / 10);\n        for (int q = 0; q < queries_this_size && total_operations < MAX_OPERATIONS * 0.3; q++) {\n            vector<pair<int,int>> group = find_best_divination_group(group_size);\n            if (!group.empty()) {\n                int result = query_multiple(group);\n                if (result >= 0) {\n                    update_probabilities(group, result);\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Medium exploration\n    for (int q = 0; q < 20 && total_operations < MAX_OPERATIONS * 0.6; q++) {\n        vector<pair<int,int>> group = find_best_divination_group(4);\n        if (!group.empty()) {\n            int result = query_multiple(group);\n            if (result >= 0) {\n                update_probabilities(group, result);\n            }\n        }\n    }\n    \n    // Phase 3: Targeted drilling of high probability squares\n    vector<pair<double, pair<int,int>>> candidates;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (!known[i][j]) {\n                candidates.push_back({-prob[i][j], {i, j}}); // Negative for sorting\n            }\n        }\n    }\n    sort(candidates.begin(), candidates.end());\n    \n    int drill_count = min(30, (int)(MAX_OPERATIONS * 0.3));\n    for (int i = 0; i < min(drill_count, (int)candidates.size()) && total_operations < MAX_OPERATIONS - 5; i++) {\n        int ci = candidates[i].second.first;\n        int cj = candidates[i].second.second;\n        \n        int result = query_single(ci, cj);\n        if (result >= 0) {\n            actual_values[ci][cj] = result;\n            known[ci][cj] = true;\n            prob[ci][cj] = (result > 0) ? 1.0 : 0.0;\n        }\n    }\n}\n\nint main() {\n    gen.seed(time(nullptr));\n    \n    // Read input\n    cin >> N >> M >> epsilon;\n    oil_fields.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        int d;\n        cin >> d;\n        oil_fields[i].resize(d);\n        for (int j = 0; j < d; j++) {\n            cin >> oil_fields[i][j].first >> oil_fields[i][j].second;\n        }\n    }\n    \n    initialize();\n    \n    // Explore strategically\n    explore();\n    \n    // Make final guess\n    bool success = make_guess();\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int W = 1000;\nconst int COST_AREA_SHORTAGE = 100;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int _i0, int _j0, int _i1, int _j1) : i0(_i0), j0(_j0), i1(_i1), j1(_j1) {}\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// Function to calculate partition changes between two days\nint calculatePartitionCost(const vector<Rectangle>& prev_day, const vector<Rectangle>& curr_day) {\n    // For simplicity, we'll approximate this\n    // In a full implementation, we'd track actual partition states\n    int cost = 0;\n    // This is a simplified approximation - in practice we'd need to track\n    // all horizontal and vertical partition segments\n    return cost;\n}\n\n// Simple strip packing algorithm\nvector<Rectangle> packRectangles(const vector<int>& areas, int strip_height = 20) {\n    vector<Rectangle> result;\n    int current_row = 0;\n    int current_col = 0;\n    \n    for (int area : areas) {\n        // Try to make rectangle as square as possible\n        int height = max(1, min(strip_height, (int)sqrt(area)));\n        while (area % height != 0) {\n            height--;\n            if (height <= 0) {\n                height = 1;\n                break;\n            }\n        }\n        int width = area / height;\n        \n        // Adjust if dimensions are too large\n        if (height > strip_height) {\n            height = strip_height;\n            width = (area + height - 1) / height; // ceil division\n        }\n        \n        // Place rectangle\n        if (current_col + width > W) {\n            current_row += strip_height;\n            current_col = 0;\n        }\n        \n        if (current_row + height <= W && current_col + width <= W) {\n            result.emplace_back(current_row, current_col, current_row + height, current_col + width);\n            current_col += width;\n        } else {\n            // Fallback: place in remaining space\n            int avail_width = W - current_col;\n            int avail_height = W - current_row;\n            if (avail_width > 0 && avail_height > 0) {\n                // Adjust to fit available space\n                height = min(height, avail_height);\n                width = min(width, avail_width);\n                result.emplace_back(current_row, current_col, current_row + height, current_col + width);\n                current_col += width;\n            } else {\n                // Last resort: small rectangle\n                result.emplace_back(0, 0, min(10, W), min(10, W));\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Improved packing that tries to satisfy area requirements\nvector<Rectangle> improvedPack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    vector<int> actual_areas(required_areas.size());\n    \n    int row_height = W / max(1, (int)sqrt(required_areas.size()));\n    row_height = max(10, min(100, row_height));\n    \n    int current_row = 0;\n    int col = 0;\n    \n    for (int k = 0; k < (int)required_areas.size(); k++) {\n        int required = required_areas[k];\n        \n        // Try to make a reasonably shaped rectangle\n        int height = max(1, (int)sqrt(required));\n        int width = (required + height - 1) / height; // ceil division\n        \n        // Adjust to make it fit better\n        while (height * width < required) {\n            if (height < width) height++;\n            else width++;\n        }\n        \n        // Make sure it fits in the grid\n        if (col + width > W) {\n            current_row += row_height;\n            col = 0;\n            // Adjust row height if needed\n            if (current_row + height > W) {\n                height = max(1, W - current_row);\n            }\n        }\n        \n        if (current_row + height > W) {\n            current_row = W - height;\n            if (current_row < 0) current_row = 0;\n        }\n        \n        if (col + width > W) {\n            col = W - width;\n            if (col < 0) col = 0;\n        }\n        \n        // Final adjustment to ensure minimum size\n        if (width <= 0) width = 1;\n        if (height <= 0) height = 1;\n        \n        result.emplace_back(current_row, col, current_row + height, col + width);\n        actual_areas[k] = height * width;\n        col += width;\n    }\n    \n    // Post-process to better satisfy area requirements\n    for (int k = 0; k < (int)result.size(); k++) {\n        int required = required_areas[k];\n        auto& rect = result[k];\n        int current_area = rect.area();\n        \n        // If we're significantly undershooting, try to expand\n        if (current_area < required) {\n            int deficit = required - current_area;\n            // Try to expand width first\n            if (rect.j1 < W) {\n                int expand_width = min(deficit / max(1, rect.i1 - rect.i0), W - rect.j1);\n                rect.j1 += expand_width;\n            }\n            // If still not enough, try to expand height\n            if (rect.area() < required && rect.i1 < W) {\n                int remaining_deficit = required - rect.area();\n                int expand_height = min(remaining_deficit / max(1, rect.j1 - rect.j0), W - rect.i1);\n                rect.i1 += expand_height;\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Strategy: Try to maintain similar layouts across days to minimize partition changes\nvector<vector<Rectangle>> solve(const vector<vector<int>>& all_areas) {\n    int D = all_areas.size();\n    vector<vector<Rectangle>> result(D);\n    \n    // For day 0, use improved packing\n    result[0] = improvedPack(all_areas[0]);\n    \n    // For subsequent days, try to maintain similar structure\n    for (int d = 1; d < D; d++) {\n        result[d] = improvedPack(all_areas[d]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    \n    vector<vector<int>> all_areas(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> all_areas[d][k];\n        }\n    }\n    \n    // Solve\n    auto solution = solve(all_areas);\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << solution[d][k].i0 << \" \" << solution[d][k].j0 << \" \" \n                 << solution[d][k].i1 << \" \" << solution[d][k].j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint N = 9, M = 20, K = 81;\nlong long a[9][9];\nlong long s[20][3][3];\n\nstruct Operation {\n    int stamp, row, col;\n};\n\n// Calculate the gain in sum of remainders from applying a stamp at position (r,c)\nlong long calculate_gain(long long board[9][9], int stamp, int r, int c) {\n    long long original_sum = 0, new_sum = 0;\n    \n    // Calculate sum of remainders for affected cells before and after\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = r + i, col = c + j;\n            long long original_remainder = board[row][col] % MOD;\n            long long new_value = board[row][col] + s[stamp][i][j];\n            long long new_remainder = new_value % MOD;\n            original_sum += original_remainder;\n            new_sum += new_remainder;\n        }\n    }\n    \n    return new_sum - original_sum;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> K;\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 (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n    \n    // Keep track of actual values (not modded yet)\n    long long board[9][9];\n    for (int i = 0; i < 9; i++) {\n        for (int j = 0; j < 9; j++) {\n            board[i][j] = a[i][j];\n        }\n    }\n    \n    vector<Operation> operations;\n    \n    // Greedy approach: iteratively select best operation\n    for (int op_count = 0; op_count < K; op_count++) {\n        long long best_gain = -1;\n        int best_stamp = -1, best_row = -1, best_col = -1;\n        \n        // Try all possible stamp placements\n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int r = 0; r <= 6; r++) {\n                for (int c = 0; c <= 6; c++) {\n                    long long gain = calculate_gain(board, stamp, r, c);\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_stamp = stamp;\n                        best_row = r;\n                        best_col = c;\n                    }\n                }\n            }\n        }\n        \n        // If no positive gain, stop early\n        if (best_gain <= 0) {\n            break;\n        }\n        \n        // Apply the best operation\n        operations.push_back({best_stamp, best_row, best_col});\n        \n        // Update board values\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_row + i][best_col + j] += s[best_stamp][i][j];\n            }\n        }\n    }\n    \n    // Output result\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << op.stamp << \" \" << op.row << \" \" << op.col << \"\\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 container_to_row[N*N];\nvector<vector<int>> A(N, vector<int>(N));\nvector<string> result(N);\n\nvoid precompute() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            container_to_row[i * N + j] = i;\n        }\n    }\n}\n\n// Simple but effective strategy\nvoid solve() {\n    precompute();\n    \n    // Read input\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Greedy strategy: each crane processes its row\n    // Crane 0 (large) can help with complex movements\n    \n    for (int turn = 0; turn < 500; turn++) {\n        for (int crane = 0; crane < N; crane++) {\n            // Simple strategy: move right, pick up containers, move to right edge, drop off\n            if (turn * 2 < crane * 10) {\n                // Initial waiting period\n                result[crane] += '.';\n            } else if (turn < 100) {\n                // Movement pattern\n                int phase = (turn - crane * 5) % 20;\n                if (phase < 4) {\n                    result[crane] += 'R';\n                } else if (phase == 4) {\n                    result[crane] += 'P'; // Pick up\n                } else if (phase < 9) {\n                    result[crane] += 'R';\n                } else if (phase == 9) {\n                    result[crane] += 'Q'; // Drop off\n                } else if (phase < 14) {\n                    result[crane] += 'L';\n                } else {\n                    result[crane] += '.';\n                }\n            } else {\n                result[crane] += '.';\n            }\n        }\n    }\n    \n    // Ensure minimum length\n    int max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, (int)result[i].length());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (result[i].length() < max_len) {\n            result[i] += '.';\n        }\n        if (result[i].empty()) result[i] = \".\";\n        cout << result[i] << \"\\n\";\n    }\n}\n\nint main() {\n    solve();\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int MOVE_COST_BASE = 100;\n\n// Manhattan distance\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Get moves to go from (x1,y1) to (x2,y2)\nvector<string> get_path(int x1, int y1, int x2, int y2) {\n    vector<string> moves;\n    while (x1 < x2) {\n        moves.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        moves.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        moves.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        moves.push_back(\"L\");\n        y1--;\n    }\n    return moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<int>> grid(n, vector<int>(n));\n    vector<tuple<int, int, int>> sources, sinks; // x, y, amount\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n            if (grid[i][j] > 0) {\n                sources.push_back({i, j, grid[i][j]});\n            } else if (grid[i][j] < 0) {\n                sinks.push_back({i, j, -grid[i][j]});\n            }\n        }\n    }\n    \n    vector<string> result;\n    int curr_x = 0, curr_y = 0;\n    \n    // Create supply and demand lists\n    vector<pair<int, int>> supply_positions, demand_positions;\n    vector<int> supply_amounts, demand_amounts;\n    \n    for (int i = 0; i < sources.size(); i++) {\n        auto [x, y, amount] = sources[i];\n        supply_positions.push_back({x, y});\n        supply_amounts.push_back(amount);\n    }\n    \n    for (int i = 0; i < sinks.size(); i++) {\n        auto [x, y, amount] = sinks[i];\n        demand_positions.push_back({x, y});\n        demand_amounts.push_back(amount);\n    }\n    \n    // Simple greedy approach: match supplies with demands\n    vector<int> supply_left = supply_amounts;\n    vector<int> demand_left = demand_amounts;\n    \n    // For each supply point, distribute to nearby demand points\n    for (int i = 0; i < supply_positions.size(); i++) {\n        if (supply_left[i] <= 0) continue;\n        \n        int sx = supply_positions[i].first;\n        int sy = supply_positions[i].second;\n        int supply_avail = supply_left[i];\n        \n        // Create list of demands with distances\n        vector<pair<int, int>> demand_with_dist; // {distance, index}\n        for (int j = 0; j < demand_positions.size(); j++) {\n            if (demand_left[j] > 0) {\n                int dx = demand_positions[j].first;\n                int dy = demand_positions[j].second;\n                int dist = manhattan(sx, sy, dx, dy);\n                demand_with_dist.push_back({dist, j});\n            }\n        }\n        \n        // Sort by distance\n        sort(demand_with_dist.begin(), demand_with_dist.end());\n        \n        // Distribute supply to nearest demands\n        for (auto& [dist, j] : demand_with_dist) {\n            if (supply_avail <= 0) break;\n            if (demand_left[j] <= 0) continue;\n            \n            int transfer = min(supply_avail, demand_left[j]);\n            \n            // Move to supply location\n            if (curr_x != sx || curr_y != sy) {\n                auto moves = get_path(curr_x, curr_y, sx, sy);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = sx;\n                curr_y = sy;\n            }\n            \n            // Load\n            result.push_back(\"+\" + to_string(transfer));\n            \n            // Move to demand location\n            int dx = demand_positions[j].first;\n            int dy = demand_positions[j].second;\n            if (curr_x != dx || curr_y != dy) {\n                auto moves = get_path(curr_x, curr_y, dx, dy);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = dx;\n                curr_y = dy;\n            }\n            \n            // Unload\n            result.push_back(\"-\" + to_string(transfer));\n            \n            supply_avail -= transfer;\n            demand_left[j] -= transfer;\n        }\n        \n        supply_left[i] = supply_avail;\n    }\n    \n    // Output results\n    for (const string& s : result) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int SEED_COUNT = 2 * N * (N - 1); // 72\n\n// Structure to hold seed information\nstruct Seed {\n    int id;\n    vector<int> values;\n    int total_value;\n    \n    Seed() : id(0), values(M, 0), total_value(0) {}\n    \n    Seed(int _id, const vector<int>& _values) : id(_id), values(_values) {\n        total_value = accumulate(values.begin(), values.end(), 0);\n    }\n};\n\n// Calculate distance between two seeds (for clustering similar seeds)\nint seedDistance(const Seed& a, const Seed& b) {\n    int dist = 0;\n    for (int i = 0; i < M; i++) {\n        dist += abs(a.values[i] - b.values[i]);\n    }\n    return dist;\n}\n\n// Greedy placement strategy\nvector<vector<int>> placeSeedsGreedy(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Take top N*N seeds\n    vector<Seed> top_seeds(seeds.begin(), seeds.begin() + N * N);\n    \n    // Simple placement: put highest value seeds in center area\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    // Sort positions by distance from center (place better seeds more centrally)\n    pair<int, int> center = {N/2, N/2};\n    sort(positions.begin(), positions.end(), [&center](const pair<int, int>& a, const pair<int, int>& b) {\n        int dist_a = abs(a.first - center.first) + abs(a.second - center.second);\n        int dist_b = abs(b.first - center.first) + abs(b.second - center.second);\n        return dist_a < dist_b;\n    });\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = top_seeds[i].id;\n    }\n    \n    return grid;\n}\n\n// Alternative placement: try to group similar high-value seeds\nvector<vector<int>> placeSeedsClustered(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Take top N*N seeds\n    vector<Seed> top_seeds(seeds.begin(), seeds.begin() + N * N);\n    \n    // Try to place similar seeds adjacent to each other\n    vector<bool> placed(N * N, false);\n    int placed_count = 0;\n    \n    // Start with the best seed in the center\n    grid[N/2][N/2] = top_seeds[0].id;\n    placed[0] = true;\n    placed_count++;\n    \n    // For remaining positions, try to place seeds similar to neighbors\n    vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    \n    while (placed_count < N * N) {\n        bool placed_something = false;\n        \n        // Look for an empty cell adjacent to a filled cell\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == -1) { // Empty cell\n                    // Check if it's adjacent to a filled cell\n                    for (auto& dir : directions) {\n                        int ni = i + dir.first;\n                        int nj = j + dir.second;\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N && grid[ni][nj] != -1) {\n                            // Found adjacent filled cell, find best seed to place here\n                            int best_seed_idx = -1;\n                            int best_similarity = -1;\n                            \n                            for (int s = 0; s < N * N; s++) {\n                                if (!placed[s]) {\n                                    int similarity = -seedDistance(top_seeds[s], \n                                        seeds[grid[ni][nj]]); // Negative because we want min distance\n                                    if (similarity > best_similarity) {\n                                        best_similarity = similarity;\n                                        best_seed_idx = s;\n                                    }\n                                }\n                            }\n                            \n                            if (best_seed_idx != -1) {\n                                grid[i][j] = top_seeds[best_seed_idx].id;\n                                placed[best_seed_idx] = true;\n                                placed_count++;\n                                placed_something = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (placed_something) break;\n                }\n            }\n            if (placed_something) break;\n        }\n        \n        // If we couldn't place anything, just fill sequentially\n        if (!placed_something) {\n            for (int i = 0; i < N * N; i++) {\n                if (!placed[i]) {\n                    // Find first empty spot\n                    for (int r = 0; r < N; r++) {\n                        for (int c = 0; c < N; c++) {\n                            if (grid[r][c] == -1) {\n                                grid[r][c] = top_seeds[i].id;\n                                placed[i] = true;\n                                placed_count++;\n                                break;\n                            }\n                        }\n                        if (placed[i]) break;\n                    }\n                }\n            }\n        }\n    }\n    \n    return grid;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N_input, M_input, T;\n    cin >> N_input >> M_input >> T;\n    \n    vector<Seed> seeds(SEED_COUNT);\n    \n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; i++) {\n        vector<int> values(M);\n        for (int j = 0; j < M; j++) {\n            cin >> values[j];\n        }\n        seeds[i] = Seed(i, values);\n    }\n    \n    // Process each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Place seeds on grid\n        vector<vector<int>> grid = placeSeedsGreedy(seeds);\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            vector<int> values(M);\n            for (int j = 0; j < M; j++) {\n                cin >> values[j];\n            }\n            seeds[i] = Seed(i, values);\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 30;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'R', 'D', 'L', 'U'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Edge {\n    int parent, length;\n    Edge() : parent(0), length(0) {}\n    Edge(int p, int l) : parent(p), length(l) {}\n};\n\nclass Solution {\npublic:\n    int N, M, V;\n    vector<vector<int>> source, target;\n    \n    Solution(int n, int m, int v) : N(n), M(m), V(v) {\n        source.assign(N, vector<int>(N, 0));\n        target.assign(N, vector<int>(N, 0));\n    }\n    \n    void read_input() {\n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                source[i][j] = line[j] - '0';\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    void design_arm() {\n        // Create a star-like tree with root at center\n        int num_edges = min(V - 1, 8);\n        \n        cout << num_edges + 1 << endl; // Number of vertices\n        \n        // Create edges from root (0) to fingertips\n        for (int i = 1; i <= num_edges; i++) {\n            cout << 0 << \" \" << 1 << endl; // parent, length\n        }\n        \n        // Initial root position\n        cout << N/2 << \" \" << N/2 << endl;\n    }\n    \n    int manhattan_distance(int x1, int y1, int x2, int y2) {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    vector<pair<int, int>> get_positions_to_visit() {\n        vector<pair<int, int>> positions;\n        \n        // Collect source positions (where takoyaki are)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        return positions;\n    }\n    \n    void solve() {\n        read_input();\n        design_arm();\n        \n        // Simple greedy approach\n        vector<pair<int, int>> sources, targets;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1 && target[i][j] == 0) {\n                    sources.push_back({i, j});\n                }\n                if (target[i][j] == 1 && source[i][j] == 0) {\n                    targets.push_back({i, j});\n                }\n            }\n        }\n        \n        // For demonstration, just do random moves\n        int root_x = N/2, root_y = N/2;\n        vector<bool> held(min(V, 9), false);\n        \n        for (int turn = 0; turn < 2000; turn++) {\n            string command(2 * min(V, 9), '.');\n            \n            // Move root randomly but stay in bounds\n            int dir = rand() % 5;\n            if (dir < 4) {\n                int nx = root_x + dx[dir];\n                int ny = root_y + dy[dir];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    root_x = nx;\n                    root_y = ny;\n                    command[0] = dir_char[dir];\n                }\n            }\n            \n            // Check if we can pick up or drop takoyaki\n            for (int finger = 1; finger < min(V, 9); finger++) {\n                int fx = root_x;\n                int fy = root_y + finger; // Simple positioning\n                \n                if (fx >= 0 && fx < N && fy >= 0 && fy < N) {\n                    // Try to pick up\n                    if (!held[finger] && source[fx][fy] == 1 && target[fx][fy] == 0) {\n                        source[fx][fy] = 0;\n                        held[finger] = true;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                    // Try to drop\n                    else if (held[finger] && source[fx][fy] == 0 && target[fx][fy] == 1) {\n                        source[fx][fy] = 1;\n                        held[finger] = false;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(time(nullptr));\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    Solution solution(N, M, V);\n    solution.solve();\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 5000;\nconst int MAX_COORD = 100000;\nconst int MAX_VERTICES = 1000;\nconst long long MAX_PERIMETER = 400000LL;\n\nstruct Point {\n    int x, y;\n    bool is_mackerel;\n    \n    Point() : x(0), y(0), is_mackerel(false) {}\n    Point(int _x, int _y, bool _is_mackerel) : x(_x), y(_y), is_mackerel(_is_mackerel) {}\n};\n\nstruct Rectangle {\n    int x1, y1, x2, y2;\n    \n    Rectangle() : x1(0), y1(0), x2(0), y2(0) {}\n    Rectangle(int _x1, int _y1, int _x2, int _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {}\n    \n    long long perimeter() const {\n        return 2LL * (abs(x2 - x1) + abs(y2 - y1));\n    }\n    \n    bool isValid() const {\n        return x1 >= 0 && x2 <= MAX_COORD && y1 >= 0 && y2 <= MAX_COORD && \n               x1 <= x2 && y1 <= y2;\n    }\n};\n\nvector<Point> points;\nvector<Point> mackerels, sardines;\n\n// 2D grid for faster counting\nconst int GRID_SIZE = 1000;\nvector<vector<pair<int, int>>> grid_mackerel(GRID_SIZE + 1, vector<pair<int, int>>(GRID_SIZE + 1, {0, 0}));\nvector<vector<pair<int, int>>> grid_sardine(GRID_SIZE + 1, vector<pair<int, int>>(GRID_SIZE + 1, {0, 0}));\n\nint grid_x[MAX_N * 2], grid_y[MAX_N * 2];\n\nvoid buildGrid() {\n    for (int i = 0; i <= GRID_SIZE; i++) {\n        for (int j = 0; j <= GRID_SIZE; j++) {\n            grid_mackerel[i][j] = {0, 0};\n            grid_sardine[i][j] = {0, 0};\n        }\n    }\n    \n    for (const auto& p : points) {\n        int gx = min(GRID_SIZE, p.x * GRID_SIZE / MAX_COORD);\n        int gy = min(GRID_SIZE, p.y * GRID_SIZE / MAX_COORD);\n        \n        if (p.is_mackerel) {\n            grid_mackerel[gx][gy].first++;\n            grid_mackerel[gx][gy].second += p.x;\n        } else {\n            grid_sardine[gx][gy].first++;\n            grid_sardine[gx][gy].second += p.x;\n        }\n    }\n}\n\n// Count points in rectangle using grid approximation\npair<int, int> countPointsInRectApprox(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    int gx1 = max(0, min(GRID_SIZE, rect.x1 * GRID_SIZE / MAX_COORD));\n    int gy1 = max(0, min(GRID_SIZE, rect.y1 * GRID_SIZE / MAX_COORD));\n    int gx2 = max(0, min(GRID_SIZE, rect.x2 * GRID_SIZE / MAX_COORD));\n    int gy2 = max(0, min(GRID_SIZE, rect.y2 * GRID_SIZE / MAX_COORD));\n    \n    for (int gx = gx1; gx <= gx2; gx++) {\n        for (int gy = gy1; gy <= gy2; gy++) {\n            mackerel_count += grid_mackerel[gx][gy].first;\n            sardine_count += grid_sardine[gx][gy].first;\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\n// Exact count for final evaluation\npair<int, int> countPointsInRectExact(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    for (const auto& p : points) {\n        if (p.x >= rect.x1 && p.x <= rect.x2 && p.y >= rect.y1 && p.y <= rect.y2) {\n            if (p.is_mackerel) {\n                mackerel_count++;\n            } else {\n                sardine_count++;\n            }\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\nint calculateScore(const Rectangle& rect) {\n    if (!rect.isValid()) return 0;\n    \n    auto [m, s] = countPointsInRectExact(rect);\n    return max(0, m - s + 1);\n}\n\n// Try to find good rectangles using local search\nRectangle findBestRectangle() {\n    Rectangle best_rect;\n    int best_score = 0;\n    \n    // Try different sizes and positions\n    vector<int> sizes = {5000, 10000, 15000, 20000, 25000, 30000};\n    \n    for (int size : sizes) {\n        // Sample points to try as centers\n        for (int i = 0; i < min(100, (int)mackerels.size()); i += max(1, (int)mackerels.size() / 100)) {\n            int cx = mackerels[i].x;\n            int cy = mackerels[i].y;\n            \n            // Try different rectangles around this center\n            for (int dx = -size/2; dx <= size/2; dx += size/4) {\n                for (int dy = -size/2; dy <= size/2; dy += size/4) {\n                    int x1 = max(0, cx + dx - size/2);\n                    int y1 = max(0, cy + dy - size/2);\n                    int x2 = min(MAX_COORD, cx + dx + size/2);\n                    int y2 = min(MAX_COORD, cy + dy + size/2);\n                    \n                    if (x2 > x1 && y2 > y1) {\n                        Rectangle rect(x1, y1, x2, y2);\n                        int score = calculateScore(rect);\n                        if (score > best_score) {\n                            best_score = score;\n                            best_rect = rect;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\n// Greedy approach: try to expand/shrink rectangle to improve score\nRectangle optimizeRectangle(Rectangle rect) {\n    Rectangle best_rect = rect;\n    int best_score = calculateScore(rect);\n    \n    // Try expanding/shrinking each side\n    for (int step = 1000; step >= 100; step /= 2) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            \n            // Try expanding left\n            if (rect.x1 - step >= 0) {\n                Rectangle new_rect(rect.x1 - step, rect.y1, rect.x2, rect.y2);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding right\n            if (rect.x2 + step <= MAX_COORD) {\n                Rectangle new_rect(rect.x1, rect.y1, rect.x2 + step, rect.y2);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding bottom\n            if (rect.y1 - step >= 0) {\n                Rectangle new_rect(rect.x1, rect.y1 - step, rect.x2, rect.y2);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding top\n            if (rect.y2 + step <= MAX_COORD) {\n                Rectangle new_rect(rect.x1, rect.y1, rect.x2, rect.y2 + step);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\nvector<pair<int, int>> rectangleToPolygon(const Rectangle& rect) {\n    vector<pair<int, int>> polygon;\n    polygon.push_back({rect.x1, rect.y1});\n    polygon.push_back({rect.x2, rect.y1});\n    polygon.push_back({rect.x2, rect.y2});\n    polygon.push_back({rect.x1, rect.y2});\n    return polygon;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    points.reserve(2 * N);\n    mackerels.reserve(N);\n    sardines.reserve(N);\n    \n    // Read mackerels\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, true);\n        points.push_back(p);\n        mackerels.push_back(p);\n    }\n    \n    // Read sardines\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, false);\n        points.push_back(p);\n        sardines.push_back(p);\n    }\n    \n    // Build grid for faster approximation\n    buildGrid();\n    \n    // Find best rectangle\n    Rectangle best_rect = findBestRectangle();\n    \n    // Optimize it\n    if (best_rect.isValid()) {\n        best_rect = optimizeRectangle(best_rect);\n    }\n    \n    // If no good rectangle found, fallback to bounding box of mackerels\n    if (calculateScore(best_rect) == 0) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        int pad = 500;\n        best_rect = Rectangle(\n            max(0, min_x - pad),\n            max(0, min_y - pad),\n            min(MAX_COORD, max_x + pad),\n            min(MAX_COORD, max_y + pad)\n        );\n    }\n    \n    // Convert to polygon\n    auto polygon = rectangleToPolygon(best_rect);\n    \n    // Output result\n    cout << polygon.size() << \"\\n\";\n    for (const auto& vertex : polygon) {\n        cout << vertex.first << \" \" << vertex.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\n// Random number generator\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Utility functions\ninline double random_double() {\n    return uniform_real_distribution<double>(0, 1)(rng);\n}\n\ninline int random_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rectangle {\n    int w, h;\n    int idx;\n    \n    Rectangle() : w(0), h(0), idx(0) {}\n    Rectangle(int _w, int _h, int _idx) : w(_w), h(_h), idx(_idx) {}\n    \n    long long area() const { return 1LL * w * h; }\n    int perimeter() const { return w + h; }\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n    \n    Placement(int _p, int _r, char _d, int _b) : p(_p), r(_r), d(_d), b(_b) {}\n};\n\nclass Packer {\nprivate:\n    int N, T, sigma;\n    vector<Rectangle> rectangles;\n    vector<Rectangle> true_rectangles; // For estimation\n    \npublic:\n    Packer() {\n        cin >> N >> T >> sigma;\n        rectangles.resize(N);\n        true_rectangles.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            int w, h;\n            cin >> w >> h;\n            rectangles[i] = Rectangle(w, h, i);\n            true_rectangles[i] = Rectangle(w, h, i);\n        }\n    }\n    \n    // Simple skyline-based packing algorithm\n    vector<Placement> skyLinePacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Start with first rectangle at origin\n        int first_idx = selected_indices[0];\n        placements.emplace_back(first_idx, 0, 'U', -1);\n        \n        // For remaining rectangles, try to place them optimally\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            \n            // Randomly decide rotation\n            int rotate = random_int(0, 1);\n            \n            // Randomly decide direction and base\n            char dir = (random_int(0, 1) == 0) ? 'U' : 'L';\n            int base = random_int(-1, i - 1);\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Corner-based packing\n    vector<Placement> cornerPacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle\n        int first_idx = selected_indices[0];\n        placements.emplace_back(first_idx, random_int(0, 1), 'U', -1);\n        \n        // Try to fill corners\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            \n            // Prefer corner filling\n            char dir = (random_double() < 0.7) ? 'U' : 'L';\n            int base = random_int(-1, min(i - 1, 3)); // Prefer recent placements for corners\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Greedy approach: select largest rectangles first\n    vector<int> selectLargeRectangles(int max_count) {\n        vector<pair<long long, int>> areas;\n        for (int i = 0; i < N; i++) {\n            areas.emplace_back(rectangles[i].area(), i);\n        }\n        \n        sort(areas.rbegin(), areas.rend());\n        \n        vector<int> selected;\n        int count = min(max_count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(areas[i].second);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n    \n    // Select middle-sized rectangles\n    vector<int> selectMiddleRectangles(int max_count) {\n        vector<pair<int, int>> perimeters;\n        for (int i = 0; i < N; i++) {\n            perimeters.emplace_back(rectangles[i].perimeter(), i);\n        }\n        \n        sort(perimeters.begin(), perimeters.end());\n        \n        vector<int> selected;\n        int start = N / 4;\n        int end = min(start + max_count, N);\n        \n        for (int i = start; i < end; i++) {\n            selected.push_back(perimeters[i].second);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n    \n    // Random selection\n    vector<int> selectRandom(int count) {\n        vector<int> indices(N);\n        iota(indices.begin(), indices.end(), 0);\n        \n        shuffle(indices.begin(), indices.end(), rng);\n        \n        vector<int> selected;\n        count = min(count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(indices[i]);\n        }\n        \n        sort(selected.begin(), selected.end());\n        return selected;\n    }\n    \n    void run() {\n        vector<vector<Placement>> strategies;\n        \n        for (int t = 0; t < T; t++) {\n            vector<Placement> best_placement;\n            \n            // Strategy 1: All rectangles, skyline packing\n            if (t < T/3) {\n                vector<int> all_indices(N);\n                iota(all_indices.begin(), all_indices.end(), 0);\n                best_placement = skyLinePacking(all_indices);\n            }\n            // Strategy 2: Large rectangles only\n            else if (t < 2*T/3) {\n                int count = max(N/2, 10);\n                vector<int> large = selectLargeRectangles(count);\n                best_placement = cornerPacking(large);\n            }\n            // Strategy 3: Random selection\n            else {\n                int count = max(N/2, 15);\n                vector<int> random_sel = selectRandom(count);\n                best_placement = skyLinePacking(random_sel);\n            }\n            \n            // Output placement\n            cout << best_placement.size() << \"\\n\";\n            for (const auto& p : best_placement) {\n                cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n            }\n            cout.flush();\n            \n            // Read measurement result\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n            \n            // Update our estimates based on feedback (simple approach)\n            // In a more sophisticated solution, we'd maintain probabilistic models\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.run();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int MAXH = 10;\n\nint N, M, H;\nvector<int> beauty;\nvector<vector<int>> adj;\nvector<pair<int, int>> coords;\nvector<int> parent;\n\n// Calculate attractiveness of a tree configuration\nlong long calculate_tree_attractiveness(int root, const vector<int>& tree_parents) {\n    // BFS to calculate levels\n    vector<int> level(N, -1);\n    queue<int> q;\n    q.push(root);\n    level[root] = 0;\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (tree_parents[v] == u && level[v] == -1 && level[u] < H) {\n                level[v] = level[u] + 1;\n                q.push(v);\n            }\n        }\n    }\n    \n    long long attractiveness = 0;\n    for (int i = 0; i < N; i++) {\n        if (level[i] != -1) {\n            attractiveness += (long long)(level[i] + 1) * beauty[i];\n        }\n    }\n    return attractiveness;\n}\n\n// Build a single tree starting from root\npair<vector<int>, long long> build_best_tree(int root, const vector<bool>& available) {\n    vector<int> tree_parents(N, -2); // -2 = not in this tree, -1 = root, >=0 = parent\n    tree_parents[root] = -1;\n    \n    vector<vector<int>> levels(H + 1);\n    levels[0].push_back(root);\n    \n    // Build tree level by level\n    for (int level = 0; level < H; level++) {\n        // Collect all available neighbors of current level\n        vector<pair<long long, pair<int, int>>> candidates; // {potential_score, {vertex, parent}}\n        \n        for (int u : levels[level]) {\n            for (int v : adj[u]) {\n                if (available[v] && tree_parents[v] == -2) {\n                    // Estimate potential of adding this vertex\n                    long long potential = (long long)(level + 2) * beauty[v]; // level+1+1 (0-indexed)\n                    candidates.push_back({potential, {v, u}});\n                }\n            }\n        }\n        \n        // Sort by potential (descending)\n        sort(candidates.begin(), candidates.end(), greater<pair<long long, pair<int, int>>>());\n        \n        // Add best candidates (limit to prevent overly wide trees)\n        int added = 0;\n        for (const auto& candidate : candidates) {\n            if (added >= 20) break; // Limit per level\n            int vertex = candidate.second.first;\n            int parent_vertex = candidate.second.second;\n            \n            if (tree_parents[vertex] == -2) { // Still available\n                tree_parents[vertex] = parent_vertex;\n                levels[level + 1].push_back(vertex);\n                added++;\n            }\n        }\n        \n        if (levels[level + 1].empty()) break;\n    }\n    \n    long long attractiveness = 0;\n    for (int level = 0; level <= H; level++) {\n        for (int v : levels[level]) {\n            attractiveness += (long long)(level + 1) * beauty[v];\n        }\n    }\n    \n    return {tree_parents, attractiveness};\n}\n\nvoid solve_improved() {\n    parent.assign(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Create list of vertices sorted by beauty (descending)\n    vector<pair<int, int>> vertices_by_beauty;\n    for (int i = 0; i < N; i++) {\n        vertices_by_beauty.push_back({beauty[i], i});\n    }\n    sort(vertices_by_beauty.begin(), vertices_by_beauty.end(), greater<pair<int, int>>());\n    \n    // Build trees greedily\n    for (const auto& [b, root] : vertices_by_beauty) {\n        if (assigned[root]) continue;\n        \n        // Build best tree starting from this root\n        auto [tree_parents, attractiveness] = build_best_tree(root, assigned);\n        \n        // Assign this tree\n        for (int i = 0; i < N; i++) {\n            if (tree_parents[i] != -2) {\n                parent[i] = tree_parents[i];\n                assigned[i] = true;\n            }\n        }\n    }\n}\n\n// Even more refined approach with better tree construction\nvoid solve_refined() {\n    parent.assign(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Priority queue for unassigned vertices (by beauty)\n    priority_queue<pair<int, int>> pq;\n    for (int i = 0; i < N; i++) {\n        pq.push({beauty[i], i});\n    }\n    \n    while (!pq.empty()) {\n        // Get highest beauty unassigned vertex\n        int root = -1;\n        while (!pq.empty()) {\n            auto [b, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        // Mark as assigned and make root\n        assigned[root] = true;\n        parent[root] = -1;\n        \n        // Build tree using BFS with smart vertex selection\n        vector<set<int>> levels(H + 1);\n        levels[0].insert(root);\n        \n        for (int level = 0; level < H; level++) {\n            // Collect all unassigned neighbors with their \"value density\"\n            vector<tuple<double, int, int>> candidates; // {value_density, vertex, parent}\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Value density: beauty / (level + 2) - this prioritizes vertices \n                        // that contribute more per level of depth\n                        double density = (double)beauty[v] / (level + 2);\n                        candidates.push_back({density, v, u});\n                    }\n                }\n            }\n            \n            // Sort by density (descending)\n            sort(candidates.begin(), candidates.end(), greater<tuple<double, int, int>>());\n            \n            // Add top candidates to next level\n            int added = 0;\n            for (const auto& [density, vertex, parent_vertex] : candidates) {\n                if (added >= 25) break; // Limit tree width\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    parent[vertex] = parent_vertex;\n                    levels[level + 1].insert(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> H;\n    \n    beauty.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> beauty[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    solve_refined();\n    \n    for (int i = 0; i < N; i++) {\n        cout << parent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nstruct OniInfo {\n    int row, col;\n    char direction;\n    int moves;\n};\n\n// Check if column j has any Fukunokami above row i\nbool hasFukuAbove(const vector<vector<char>>& board, int i, int j) {\n    for (int r = 0; r < i; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if column j has any Fukunokami below row i\nbool hasFukuBelow(const vector<vector<char>>& board, int i, int j) {\n    for (int r = i + 1; r < N; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the left of column j\nbool hasFukuLeft(const vector<vector<char>>& board, int i, int j) {\n    for (int c = 0; c < j; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the right of column j\nbool hasFukuRight(const vector<vector<char>>& board, int i, int j) {\n    for (int c = j + 1; c < N; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Find best direction to remove Oni at (i,j)\nOniInfo findBestDirection(const vector<vector<char>>& board, int i, int j) {\n    OniInfo best = {i, j, 'U', N}; // default with high cost\n    \n    // Check up\n    if (!hasFukuAbove(board, i, j)) {\n        if (i < best.moves) {\n            best.direction = 'U';\n            best.moves = i;\n        }\n    }\n    \n    // Check down\n    if (!hasFukuBelow(board, i, j)) {\n        int moves = N - 1 - i;\n        if (moves < best.moves) {\n            best.direction = 'D';\n            best.moves = moves;\n        }\n    }\n    \n    // Check left\n    if (!hasFukuLeft(board, i, j)) {\n        if (j < best.moves) {\n            best.direction = 'L';\n            best.moves = j;\n        }\n    }\n    \n    // Check right\n    if (!hasFukuRight(board, i, j)) {\n        int moves = N - 1 - j;\n        if (moves < best.moves) {\n            best.direction = 'R';\n            best.moves = moves;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<char>> board(N, vector<char>(N));\n    vector<pair<int, int>> oniPositions;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            board[i][j] = line[j];\n            if (line[j] == 'x') {\n                oniPositions.push_back({i, j});\n            }\n        }\n    }\n    \n    vector<OniInfo> oniInfos;\n    \n    // Find best direction for each Oni\n    for (auto& pos : oniPositions) {\n        int i = pos.first, j = pos.second;\n        OniInfo info = findBestDirection(board, i, j);\n        oniInfos.push_back(info);\n    }\n    \n    // Group Oni by row/column to optimize batching\n    map<pair<char, int>, vector<OniInfo>> groupedMoves;\n    \n    for (const auto& oni : oniInfos) {\n        if (oni.direction == 'U' || oni.direction == 'D') {\n            groupedMoves[{oni.direction, oni.col}].push_back(oni);\n        } else {\n            groupedMoves[{oni.direction, oni.row}].push_back(oni);\n        }\n    }\n    \n    vector<pair<char, int>> moves;\n    \n    // Process groups to batch operations\n    for (auto& [key, group] : groupedMoves) {\n        char dir = key.first;\n        int idx = key.second;\n        \n        // Sort by moves needed within the group\n        sort(group.begin(), group.end(), [](const OniInfo& a, const OniInfo& b) {\n            return a.moves < b.moves;\n        });\n        \n        // For columns, we want to shift all the way then back\n        if (dir == 'U') {\n            // Find maximum moves needed in this column\n            int maxMoves = 0;\n            for (const auto& oni : group) {\n                maxMoves = max(maxMoves, oni.moves);\n            }\n            // Shift up maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'U', idx});\n            }\n            // Shift back down maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'D', idx});\n            }\n        } else if (dir == 'D') {\n            // Find maximum moves needed in this column\n            int maxMoves = 0;\n            for (const auto& oni : group) {\n                maxMoves = max(maxMoves, oni.moves);\n            }\n            // Shift down maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'D', idx});\n            }\n            // Shift back up maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'U', idx});\n            }\n        } else if (dir == 'L') {\n            // Find maximum moves needed in this row\n            int maxMoves = 0;\n            for (const auto& oni : group) {\n                maxMoves = max(maxMoves, oni.moves);\n            }\n            // Shift left maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'L', idx});\n            }\n            // Shift back right maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'R', idx});\n            }\n        } else if (dir == 'R') {\n            // Find maximum moves needed in this row\n            int maxMoves = 0;\n            for (const auto& oni : group) {\n                maxMoves = max(maxMoves, oni.moves);\n            }\n            // Shift right maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'R', idx});\n            }\n            // Shift back left maxMoves times\n            for (int k = 0; k < maxMoves; k++) {\n                moves.push_back({'L', idx});\n            }\n        }\n    }\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\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 target[N];\nint a[N], b[N];\nint actual[N];\n\n// Simulate the cleaning process to compute actual counts\nvoid simulate() {\n    fill(actual, actual + N, 0);\n    \n    int current = 0;\n    vector<int> count(N, 0);\n    \n    for (int week = 0; week < L; week++) {\n        actual[current]++;\n        count[current]++;\n        \n        if (count[current] % 2 == 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n    }\n}\n\n// Calculate error\nint calculate_error() {\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(actual[i] - target[i]);\n    }\n    return error;\n}\n\n// Initialize a and b arrays\nvoid initialize() {\n    // Create a rough approximation using greedy approach\n    vector<pair<int, int>> employees;\n    for (int i = 0; i < N; i++) {\n        employees.push_back({target[i], i});\n    }\n    \n    // Sort by target frequency (descending)\n    sort(employees.rbegin(), employees.rend());\n    \n    // Assign transitions to try to balance load\n    for (int i = 0; i < N; i++) {\n        int idx = employees[i].second;\n        // Point to employees with lower targets to distribute load\n        int next_idx1 = employees[(i + 1) % N].second;\n        int next_idx2 = employees[(i + 2) % N].second;\n        \n        a[idx] = next_idx1;\n        b[idx] = next_idx2;\n    }\n}\n\n// Improve the solution using local search\nvoid optimize() {\n    // Try swapping transitions to reduce error\n    for (int iter = 0; iter < 1000; iter++) {\n        simulate();\n        int current_error = calculate_error();\n        \n        // Try random swaps\n        int emp = rand() % N;\n        int choice = rand() % 2;\n        int old_val = (choice == 0) ? a[emp] : b[emp];\n        int new_val = rand() % N;\n        \n        if (choice == 0) {\n            a[emp] = new_val;\n        } else {\n            b[emp] = new_val;\n        }\n        \n        simulate();\n        int new_error = calculate_error();\n        \n        // Accept improvement or revert with some probability\n        if (new_error <= current_error) {\n            // Keep the change\n        } else {\n            // Revert with probability based on temperature\n            if (rand() % 100 < 10) {\n                // Keep it anyway sometimes\n            } else {\n                if (choice == 0) {\n                    a[emp] = old_val;\n                } else {\n                    b[emp] = old_val;\n                }\n            }\n        }\n    }\n}\n\n// Better initialization based on target distribution\nvoid smart_initialize() {\n    // For each employee, set a and b to point to employees \n    // that help balance the distribution\n    \n    // Simple approach: point to employees in a round-robin fashion\n    // but weighted by inverse of their targets\n    \n    vector<int> indices(N);\n    for (int i = 0; i < N; i++) {\n        indices[i] = i;\n    }\n    \n    // Sort indices by target (ascending - those needing more should be pointed to)\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return target[i] < target[j];\n    });\n    \n    for (int i = 0; i < N; i++) {\n        // Point to employees that need more assignments\n        a[i] = indices[(i + 1) % N];\n        b[i] = indices[(i + 2) % N];\n    }\n}\n\n// Even smarter approach: try to create cycles that match target distribution\nvoid cycle_based_initialize() {\n    // Create a more sophisticated assignment\n    \n    // Make sure everyone points somewhere\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    \n    // But adjust based on targets\n    // Employees with high targets should be pointed to more often\n    vector<pair<int, int>> target_pairs;\n    for (int i = 0; i < N; i++) {\n        target_pairs.push_back({target[i], i});\n    }\n    \n    sort(target_pairs.begin(), target_pairs.end());\n    \n    // Redistribute edges to favor high-target employees\n    for (int i = 0; i < N; i++) {\n        int from = target_pairs[i].second;\n        int to_high = target_pairs[(i + N/2) % N].second;\n        int to_medium = target_pairs[(i + N/4) % N].second;\n        \n        // With some probability, point to high-target employees\n        if (rand() % 3 == 0) {\n            a[from] = to_high;\n        }\n        if (rand() % 3 == 0) {\n            b[from] = to_medium;\n        }\n    }\n}\n\nint main() {\n    srand(time(nullptr));\n    \n    int dummy_L;\n    cin >> dummy_L >> dummy_L;\n    for (int i = 0; i < N; i++) {\n        cin >> target[i];\n    }\n    \n    // Initialize with a reasonable strategy\n    cycle_based_initialize();\n    \n    // Do some local optimization\n    for (int iter = 0; iter < 500; iter++) {\n        simulate();\n        int current_error = calculate_error();\n        \n        // Pick a random employee and modify their transitions\n        int emp = rand() % N;\n        int which = rand() % 2;\n        int old_val = (which == 0) ? a[emp] : b[emp];\n        int new_val = rand() % N;\n        \n        if (which == 0) {\n            a[emp] = new_val;\n        } else {\n            b[emp] = new_val;\n        }\n        \n        simulate();\n        int new_error = calculate_error();\n        \n        // If worse, only accept with small probability\n        if (new_error > current_error && rand() % 100 > 5) {\n            // Revert\n            if (which == 0) {\n                a[emp] = old_val;\n            } else {\n                b[emp] = old_val;\n            }\n        }\n    }\n    \n    // Output result\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\nconst int N = 800;\nconst int MAX_Q = 400;\nconst int MAX_L = 15;\n\nint n, m, q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<pair<int, int>> centers;\nvector<vector<int>> groups;\nint queries_used = 0;\n\n// Query function with proper count tracking\nvector<pair<int, int>> query(const vector<int>& cities) {\n    if (queries_used >= q) {\n        return {}; // Don't make more queries than allowed\n    }\n    \n    if (cities.size() < 2 || cities.size() > L) {\n        return {};\n    }\n    \n    cout << \"? \" << cities.size();\n    for (int city : cities) {\n        cout << \" \" << city;\n    }\n    cout << endl;\n    cout.flush();\n    \n    queries_used++;\n    \n    vector<pair<int, int>> result;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        if (u > v) swap(u, v);\n        result.push_back({u, v});\n    }\n    \n    return result;\n}\n\n// Calculate distance between two rectangles using their centers\nlong long calc_center_distance_sq(int i, int j) {\n    long long cx1 = (lx[i] + rx[i]) / 2LL;\n    long long cy1 = (ly[i] + ry[i]) / 2LL;\n    long long cx2 = (lx[j] + rx[j]) / 2LL;\n    long long cy2 = (ly[j] + ry[j]) / 2LL;\n    return (cx1 - cx2) * (cx1 - cx2) + (cy1 - cy2) * (cy1 - cy2);\n}\n\n// Initial clustering based on centers using a greedy approach\nvoid initial_clustering() {\n    // Calculate centers\n    centers.clear();\n    for (int i = 0; i < n; i++) {\n        int cx = (lx[i] + rx[i]) / 2;\n        int cy = (ly[i] + ry[i]) / 2;\n        centers.push_back({cx, cy});\n    }\n    \n    // Create list of all cities\n    vector<int> cities(n);\n    iota(cities.begin(), cities.end(), 0);\n    \n    // Sort cities by x-coordinate primarily, y-coordinate secondarily\n    sort(cities.begin(), cities.end(), [&](int a, int b) {\n        if (centers[a].first != centers[b].first) {\n            return centers[a].first < centers[b].first;\n        }\n        return centers[a].second < centers[b].second;\n    });\n    \n    // Assign to groups sequentially\n    groups.clear();\n    groups.resize(m);\n    int idx = 0;\n    for (int i = 0; i < m; i++) {\n        groups[i].clear();\n        for (int j = 0; j < G[i]; j++) {\n            if (idx < n) {\n                groups[i].push_back(cities[idx]);\n                idx++;\n            }\n        }\n    }\n}\n\n// Use queries efficiently to learn about connections\nvoid learn_connections() {\n    // First, query small groups entirely if possible\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= 1) continue;\n        \n        // If group size is small enough, query the whole group\n        if (G[i] <= L) {\n            query(groups[i]);\n            if (queries_used >= q) return;\n        }\n    }\n    \n    // For larger groups, do sliding window queries\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= L) continue; // Already handled above\n        \n        // Do sliding window queries of size L\n        for (int start = 0; start < G[i] - 1 && queries_used < q; start += L - 1) {\n            int end = min(start + L, G[i]);\n            vector<int> subset;\n            for (int j = start; j < end; j++) {\n                subset.push_back(groups[i][j]);\n            }\n            \n            if (subset.size() >= 2) {\n                query(subset);\n            }\n            \n            if (queries_used >= q) break;\n        }\n        \n        if (queries_used >= q) break;\n    }\n}\n\n// Build MST for each group\nvector<vector<pair<int, int>>> build_final_msts() {\n    vector<vector<pair<int, int>>> result(m);\n    \n    for (int i = 0; i < m; i++) {\n        if (G[i] <= 1) continue;\n        \n        // For small groups, we can query directly if we have queries left\n        if (G[i] <= L && queries_used < q) {\n            vector<pair<int, int>> edges = query(groups[i]);\n            result[i] = edges;\n            continue;\n        }\n        \n        // For larger groups or when out of queries, build approximate MST\n        // Simple path: connect consecutive cities\n        for (int j = 0; j < G[i] - 1; j++) {\n            result[i].push_back({groups[i][j], groups[i][j+1]});\n        }\n    }\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++) {\n        cin >> G[i];\n    }\n    \n    lx.resize(n);\n    rx.resize(n);\n    ly.resize(n);\n    ry.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Perform initial clustering\n    initial_clustering();\n    \n    // Learn connections through queries\n    learn_connections();\n    \n    // Build MSTs for final answer\n    vector<vector<pair<int, int>>> msts = build_final_msts();\n    \n    // Output final answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            cout << groups[i][j];\n            if (j < (int)groups[i].size() - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n        \n        for (const auto& edge : msts[i]) {\n            cout << edge.first << \" \" << edge.second << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int _x, int _y) : x(_x), y(_y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass SkatingSolver {\nprivate:\n    int grid[N][N]; // 0 = empty, 1 = block\n    Point pos;\n    vector<Point> targets;\n    vector<string> actions;\n    \npublic:\n    SkatingSolver() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        int n, m;\n        cin >> n >> m;\n        int x, y;\n        cin >> x >> y;\n        pos = Point(x, y);\n        \n        targets.resize(m);\n        for (int i = 0; i < m; i++) {\n            cin >> targets[i].x >> targets[i].y;\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void add_action(char action, char direction) {\n        actions.push_back(string(1, action) + \" \" + string(1, direction));\n    }\n    \n    // Move one step in given direction\n    bool move(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (!is_valid(nx, ny) || grid[nx][ny] == 1) {\n            return false;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('M', dir_chars[dir]);\n        return true;\n    }\n    \n    // Slide until hitting a block or boundary\n    void slide(int dir) {\n        int nx = pos.x, ny = pos.y;\n        \n        while (true) {\n            int tx = nx + dx[dir];\n            int ty = ny + dy[dir];\n            \n            if (!is_valid(tx, ty) || grid[tx][ty] == 1) {\n                break;\n            }\n            \n            nx = tx;\n            ny = ty;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('S', dir_chars[dir]);\n    }\n    \n    // Place or remove block\n    void alter(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            grid[nx][ny] = 1 - grid[nx][ny];\n        }\n        \n        add_action('A', dir_chars[dir]);\n    }\n    \n    // Find direction from point a to point b\n    int get_direction(Point a, Point b) {\n        if (a.x > b.x) return 0; // U\n        if (a.x < b.x) return 1; // D\n        if (a.y > b.y) return 2; // L\n        if (a.y < b.y) return 3; // R\n        return -1; // Same position\n    }\n    \n    // Manhattan distance\n    int manhattan_distance(Point a, Point b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Simple path finding using moves only\n    void move_to_target(Point target) {\n        // Use greedy approach - move in the direction that reduces distance\n        for (int step = 0; step < 1000 && !(pos == target); step++) {\n            int best_dir = -1;\n            int min_dist = manhattan_distance(pos, target);\n            \n            // Try all directions\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = pos.x + dx[dir];\n                int ny = pos.y + dy[dir];\n                \n                if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                    int dist = abs(nx - target.x) + abs(ny - target.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_dir = dir;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                move(best_dir);\n            } else {\n                // If stuck, try any valid move\n                bool moved = false;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (move(dir)) {\n                        moved = true;\n                        break;\n                    }\n                }\n                if (!moved) break;\n            }\n        }\n    }\n    \n    // Enhanced strategy using slides when possible\n    void smart_move_to_target(Point target) {\n        if (pos == target) return;\n        \n        // If in same row or column, consider sliding\n        if (pos.x == target.x || pos.y == target.y) {\n            int dir = get_direction(pos, target);\n            if (dir != -1) {\n                // Check if we can slide directly\n                bool can_slide_directly = true;\n                Point temp_pos = pos;\n                \n                while (!(temp_pos == target)) {\n                    int nx = temp_pos.x + dx[dir];\n                    int ny = temp_pos.y + dy[dir];\n                    \n                    if (!is_valid(nx, ny)) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    if (grid[nx][ny] == 1) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    temp_pos.x = nx;\n                    temp_pos.y = ny;\n                }\n                \n                if (can_slide_directly) {\n                    slide(dir);\n                    return;\n                }\n            }\n        }\n        \n        // Otherwise use regular move-to-target\n        move_to_target(target);\n    }\n    \n    void solve() {\n        // Visit each target in order\n        for (int i = 1; i < (int)targets.size(); i++) {\n            // If target has a block, remove it first\n            if (grid[targets[i].x][targets[i].y] == 1) {\n                // Find adjacent empty spot to remove block\n                for (int dir = 0; dir < 4; dir++) {\n                    int nx = targets[i].x + dx[dir];\n                    int ny = targets[i].y + dy[dir];\n                    \n                    if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                        // Move to adjacent position and remove block\n                        Point adj_pos(nx, ny);\n                        \n                        // Move to adjacent position\n                        move_to_target(adj_pos);\n                        \n                        // Remove block (opposite direction)\n                        int opposite_dir = (dir == 0) ? 1 : (dir == 1) ? 0 : (dir == 2) ? 3 : 2;\n                        alter(opposite_dir);\n                        break;\n                    }\n                }\n            }\n            \n            // Move to target\n            smart_move_to_target(targets[i]);\n        }\n    }\n    \n    void print_solution() {\n        for (const string& action : actions) {\n            cout << action << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    SkatingSolver solver;\n    solver.read_input();\n    solver.solve();\n    solver.print_solution();\n    \n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int id, x, y, r;\n};\n\nstruct Rectangle {\n    int a, b, c, d; // (a,b) to (c,d) where a<c and b<d\n};\n\nconst int SIZE = 10000;\nvector<Rectangle> rectangles;\nvector<Company> companies;\n\n// Check if two rectangles overlap (touching edges is OK, overlapping area is not)\nbool overlap(int a1, int b1, int c1, int d1, int a2, int b2, int c2, int d2) {\n    // Rectangles overlap if their intersection has positive area\n    // This happens when both x and y projections have positive overlap\n    return !(c1 <= a2 || c2 <= a1 || d1 <= b2 || d2 <= b1);\n}\n\n// Check if rectangle overlaps with existing rectangles\nbool has_overlap(int a, int b, int c, int d) {\n    for (const auto& rect : rectangles) {\n        if (rect.a != -1) {\n            if (overlap(a, b, c, d, rect.a, rect.b, rect.c, rect.d)) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Find reasonable factors of area\nvector<pair<int, int>> get_factors(int area) {\n    vector<pair<int, int>> factors;\n    \n    // Limit the search to reasonable factors\n    int limit = min(200, (int)sqrt(area) + 50);\n    \n    for (int w = 1; w <= min(limit, area); w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            if (h <= SIZE) {\n                factors.push_back({w, h});\n                if (w != h && w <= SIZE && h <= limit) {\n                    factors.push_back({h, w});\n                }\n            }\n        }\n    }\n    \n    // Remove duplicates and limit size\n    sort(factors.begin(), factors.end());\n    factors.erase(unique(factors.begin(), factors.end()), factors.end());\n    \n    // Keep only top candidates\n    if (factors.size() > 30) {\n        factors.resize(30);\n    }\n    \n    return factors;\n}\n\n// Try to place rectangle for company\nbool place_company(const Company& comp) {\n    int target_x = comp.x;\n    int target_y = comp.y;\n    int area = comp.r;\n    \n    auto factors = get_factors(area);\n    \n    // Try to place with exact area first\n    for (auto& factor : factors) {\n        int w = factor.first;\n        int h = factor.second;\n        \n        // Try to center around the target point\n        int center_a = target_x - w/2;\n        int center_b = target_y - h/2;\n        \n        // Try a small window around the center\n        for (int dx = -min(30, w/2); dx <= min(30, w/2); dx++) {\n            for (int dy = -min(30, h/2); dy <= min(30, h/2); dy++) {\n                int a = center_a + dx;\n                int b = center_b + dy;\n                int c = a + w;\n                int d = b + h;\n                \n                // Ensure valid bounds\n                if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE && a < c && b < d) {\n                    // Check if target point (with 0.5 offset) is inside\n                    // Point (x+0.5, y+0.5) is inside [a,c) x [b,d) if a <= x < c and b <= y < d\n                    if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                        if (!has_overlap(a, b, c, d)) {\n                            rectangles[comp.id] = {a, b, c, d};\n                            return true;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Try approximate areas\n    vector<int> test_areas;\n    for (int delta = 1; delta <= min(30, area/100); delta++) {\n        if (area + delta <= SIZE * SIZE) test_areas.push_back(area + delta);\n        if (area - delta > 0) test_areas.push_back(area - delta);\n    }\n    \n    for (int test_area : test_areas) {\n        auto test_factors = get_factors(test_area);\n        for (auto& factor : test_factors) {\n            int w = factor.first;\n            int h = factor.second;\n            \n            int center_a = target_x - w/2;\n            int center_b = target_y - h/2;\n            \n            for (int dx = -min(20, w/2); dx <= min(20, w/2); dx++) {\n                for (int dy = -min(20, h/2); dy <= min(20, h/2); dy++) {\n                    int a = center_a + dx;\n                    int b = center_b + dy;\n                    int c = a + w;\n                    int d = b + h;\n                    \n                    if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE && a < c && b < d) {\n                        if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                            if (!has_overlap(a, b, c, d)) {\n                                rectangles[comp.id] = {a, b, c, d};\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Last resort: simple placement near target\n    for (int w = 1; w <= min(50, area); w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            if (h <= SIZE) {\n                // Try to place near the target point\n                int start_a = max(0, min(target_x, SIZE - w));\n                int start_b = max(0, min(target_y, SIZE - h));\n                \n                for (int a = max(0, start_a - 10); a <= min(SIZE - w, start_a + 10); a++) {\n                    for (int b = max(0, start_b - 10); b <= min(SIZE - h, start_b + 10); b++) {\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                            if (!has_overlap(a, b, c, d)) {\n                                rectangles[comp.id] = {a, b, c, d};\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Absolute fallback: place smallest possible valid rectangle\n    for (int a = max(0, target_x - 20); a <= min(SIZE - 1, target_x + 20); a++) {\n        for (int b = max(0, target_y - 20); b <= min(SIZE - 1, target_y + 20); b++) {\n            int c = a + 1;\n            int d = b + 1;\n            \n            if (c <= SIZE && d <= SIZE) {\n                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                    if (!has_overlap(a, b, c, d)) {\n                        rectangles[comp.id] = {a, b, c, d};\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Final fallback: any valid position\n    for (int a = 0; a < SIZE; a += 50) {\n        for (int b = 0; b < SIZE; b += 50) {\n            int c = a + 1;\n            int d = b + 1;\n            \n            if (c <= SIZE && d <= SIZE) {\n                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                    if (!has_overlap(a, b, c, d)) {\n                        rectangles[comp.id] = {a, b, c, d};\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // If all else fails, place somewhere (even if it might not contain the point optimally)\n    rectangles[comp.id] = {0, 0, 1, 1};\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    companies.resize(n);\n    rectangles.assign(n, {-1, -1, -1, -1});\n    \n    vector<pair<int, int>> areas_indices;\n    \n    for (int i = 0; i < n; i++) {\n        companies[i].id = i;\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        areas_indices.push_back({companies[i].r, i});\n    }\n    \n    // Sort by area descending to place larger rectangles first\n    sort(areas_indices.rbegin(), areas_indices.rend());\n    \n    // Place each company\n    for (const auto& area_idx : areas_indices) {\n        int idx = area_idx.second;\n        place_company(companies[idx]);\n    }\n    \n    // Output results\n    for (const auto& rect : rectangles) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SIZE = 50;\nint si, sj;\nint tile_id[SIZE][SIZE];\nint points[SIZE][SIZE];\nvector<pair<int,int>> tile_cells[2500];\nbool tile_visited[2500];\n\n// Directions: U, D, L, R\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nvoid preprocess_tiles() {\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            int tid = tile_id[i][j];\n            tile_cells[tid].push_back({i, j});\n        }\n    }\n}\n\nbool is_valid_position(int x, int y) {\n    return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n}\n\nstring solve() {\n    // Reset visited status\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int x = si, y = sj;\n    int current_tile = tile_id[x][y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    // Simple greedy approach\n    for (int step = 0; step < 2500; step++) {\n        // Find best valid move\n        int best_value = -1;\n        int best_dir = -1;\n        int best_nx = -1, best_ny = -1;\n        int best_next_tile = -1;\n        \n        // Try all 4 directions from current position\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (is_valid_position(nx, ny)) {\n                int next_tile = tile_id[nx][ny];\n                if (!tile_visited[next_tile]) {\n                    // Calculate value of this tile\n                    int tile_value = 0;\n                    for (auto& cell : tile_cells[next_tile]) {\n                        tile_value += points[cell.first][cell.second];\n                    }\n                    \n                    if (tile_value > best_value) {\n                        best_value = tile_value;\n                        best_dir = d;\n                        best_nx = nx;\n                        best_ny = ny;\n                        best_next_tile = next_tile;\n                    }\n                }\n            }\n        }\n        \n        // If no valid move, stop\n        if (best_dir == -1) {\n            break;\n        }\n        \n        // Make the move\n        path += dir_char[best_dir];\n        x = best_nx;\n        y = best_ny;\n        tile_visited[best_next_tile] = true;\n        current_tile = best_next_tile;\n    }\n    \n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> tile_id[i][j];\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess_tiles();\n    \n    string result = solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int QUERY_COUNT = 1000;\n\n// Edge weight estimates with confidence\nvector<vector<double>> h_edges; // horizontal edges (i,j) to (i,j+1)\nvector<vector<double>> v_edges; // vertical edges (i,j) to (i+1,j)\nvector<vector<double>> h_confidence; // confidence in h_edge estimates\nvector<vector<double>> v_confidence; // confidence in v_edge estimates\n\n// Count of times each edge has been used\nvector<vector<int>> h_usage_count;\nvector<vector<int>> v_usage_count;\n\n// Initialize edge weights\nvoid initialize_weights() {\n    // Better initial estimate based on problem parameters\n    h_edges.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 5000.0));\n    v_edges.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 5000.0));\n    \n    // Initialize confidence (lower means less certain)\n    h_confidence.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 1.0));\n    v_confidence.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 1.0));\n    \n    // Usage counts\n    h_usage_count.assign(GRID_SIZE, vector<int>(GRID_SIZE - 1, 0));\n    v_usage_count.assign(GRID_SIZE - 1, vector<int>(GRID_SIZE, 0));\n}\n\n// Calculate path length using current estimates\ndouble calculate_estimated_length(const vector<pair<int,int>>& path) {\n    double length = 0.0;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) {\n            length += h_edges[r1][c1];\n        } else if (r1 == r2 && c2 == c1 - 1) {\n            length += h_edges[r1][c2];\n        } else if (c1 == c2 && r2 == r1 + 1) {\n            length += v_edges[r1][c1];\n        } else if (c1 == c2 && r2 == r1 - 1) {\n            length += v_edges[r2][c1];\n        }\n    }\n    return length;\n}\n\n// Get actual length from the last query\nint get_actual_length() {\n    int actual_length;\n    cin >> actual_length;\n    return actual_length;\n}\n\n// Find shortest path using A* with current estimates and some exploration\nvector<pair<int,int>> find_shortest_path(int start_r, int start_c, int end_r, int end_c, int query_num) {\n    // For very short distances, just use Manhattan path\n    int manhattan_dist = abs(start_r - end_r) + abs(start_c - end_c);\n    if (manhattan_dist <= 10 && query_num > 100) {\n        vector<pair<int,int>> path;\n        path.push_back({start_r, start_c});\n        int r = start_r, c = start_c;\n        \n        // Move vertically first\n        while (r < end_r) {\n            r++;\n            path.push_back({r, c});\n        }\n        while (r > end_r) {\n            r--;\n            path.push_back({r, c});\n        }\n        \n        // Then horizontally\n        while (c < end_c) {\n            c++;\n            path.push_back({r, c});\n        }\n        while (c > end_c) {\n            c--;\n            path.push_back({r, c});\n        }\n        return path;\n    }\n    \n    // Priority queue: {f_score, g_score, row, col}\n    priority_queue<tuple<double, double, int, int>, vector<tuple<double, double, int, int>>, greater<>> pq;\n    \n    // Distance and parent tracking\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int,int>>> parent(GRID_SIZE, vector<pair<int,int>>(GRID_SIZE, {-1, -1}));\n    \n    auto heuristic = [&](int r, int c) {\n        return abs(r - end_r) + abs(c - end_c); // Manhattan distance\n    };\n    \n    dist[start_r][start_c] = 0;\n    pq.push({heuristic(start_r, start_c), 0.0, start_r, start_c});\n    \n    vector<pair<int,int>> directions = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // U, D, L, R\n    \n    while (!pq.empty()) {\n        auto [f_score, g_score, r, c] = pq.top();\n        pq.pop();\n        \n        if (g_score > dist[r][c]) continue;\n        \n        if (r == end_r && c == end_c) break;\n        \n        // Explore neighbors\n        for (int dir = 0; dir < 4; dir++) {\n            int dr = directions[dir].first;\n            int dc = directions[dir].second;\n            int nr = r + dr;\n            int nc = c + dc;\n            \n            // Check bounds\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            \n            double edge_cost = 0;\n            if (dr == 0 && dc == 1) { // Right\n                edge_cost = h_edges[r][c];\n            } else if (dr == 0 && dc == -1) { // Left\n                edge_cost = h_edges[r][nc];\n            } else if (dr == 1 && dc == 0) { // Down\n                edge_cost = v_edges[r][c];\n            } else if (dr == -1 && dc == 0) { // Up\n                edge_cost = v_edges[nr][c];\n            }\n            \n            // Add exploration bonus for less confident edges (early queries)\n            if (query_num < 200) {\n                double exploration_bonus = 0;\n                if (dr == 0 && dc == 1) { // Right\n                    exploration_bonus = (1.0 / (h_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 0 && dc == -1) { // Left\n                    exploration_bonus = (1.0 / (h_confidence[r][nc] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 1 && dc == 0) { // Down\n                    exploration_bonus = (1.0 / (v_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == -1 && dc == 0) { // Up\n                    exploration_bonus = (1.0 / (v_confidence[nr][c] + 1e-6)) * (200 - query_num) * 0.1;\n                }\n                edge_cost += exploration_bonus;\n            }\n            \n            double new_g_score = g_score + edge_cost;\n            if (new_g_score < dist[nr][nc]) {\n                dist[nr][nc] = new_g_score;\n                parent[nr][nc] = {r, c};\n                double f_score = new_g_score + heuristic(nr, nc);\n                pq.push({f_score, new_g_score, nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int r = end_r, c = end_c;\n    while (r != -1 && c != -1) {\n        path.push_back({r, c});\n        auto p = parent[r][c];\n        r = p.first;\n        c = p.second;\n    }\n    reverse(path.begin(), path.end());\n    \n    return path;\n}\n\n// Convert path to direction string\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r2 == r1 - 1) result += 'U';\n        else if (r2 == r1 + 1) result += 'D';\n        else if (c2 == c1 - 1) result += 'L';\n        else if (c2 == c1 + 1) result += 'R';\n    }\n    return result;\n}\n\n// Update edge weights based on actual path performance with confidence tracking\nvoid update_weights(const vector<pair<int,int>>& path, int actual_length, int query_num) {\n    if (path.size() < 2) return;\n    \n    double estimated_length = calculate_estimated_length(path);\n    double error = actual_length - estimated_length;\n    \n    // Adaptive learning rate based on query number and path length\n    double base_learning_rate = 0.3;\n    double learning_rate = base_learning_rate * exp(-0.001 * query_num);\n    \n    // Update each edge in the path\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) { // Right\n            h_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c1] += learning_rate * edge_error;\n            h_edges[r1][c1] = max(100.0, min(10000.0, h_edges[r1][c1]));\n            // Update confidence - more usage means higher confidence\n            h_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (r1 == r2 && c2 == c1 - 1) { // Left\n            h_usage_count[r1][c2]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c2] += learning_rate * edge_error;\n            h_edges[r1][c2] = max(100.0, min(10000.0, h_edges[r1][c2]));\n            h_confidence[r1][c2] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 + 1) { // Down\n            v_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r1][c1] += learning_rate * edge_error;\n            v_edges[r1][c1] = max(100.0, min(10000.0, v_edges[r1][c1]));\n            v_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 - 1) { // Up\n            v_usage_count[r2][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r2][c1] += learning_rate * edge_error;\n            v_edges[r2][c1] = max(100.0, min(10000.0, v_edges[r2][c1]));\n            v_confidence[r2][c1] += learning_rate * 10.0;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_weights();\n    \n    for (int query = 0; query < QUERY_COUNT; query++) {\n        int start_r, start_c, end_r, end_c;\n        cin >> start_r >> start_c >> end_r >> end_c;\n        \n        vector<pair<int,int>> path = find_shortest_path(start_r, start_c, end_r, end_c, query);\n        \n        string path_str = path_to_string(path);\n        cout << path_str << endl;\n        cout.flush();\n        \n        // Get actual length and update weights\n        int actual_length = get_actual_length();\n        update_weights(path, actual_length, query);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst string ALPHABET = \"ABCDEFGH\";\n\nstruct StringInfo {\n    string s;\n    int id;\n    bool placed = false;\n    int row = -1, col = -1;\n    bool horizontal = true;\n};\n\nvector<string> matrix(N, string(N, '.'));\nvector<StringInfo> strings;\nint M;\n\n// Check if string can be placed at position (r,c) in given direction\nbool canPlace(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        \n        if (matrix[nr][nc] != '.' && matrix[nr][nc] != s[i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place string at position (r,c) in given direction\nvoid placeString(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        matrix[nr][nc] = s[i];\n    }\n}\n\n// Count how many strings are currently matched\nint countMatches() {\n    int count = 0;\n    for (const auto& str_info : strings) {\n        const string& s = str_info.s;\n        bool found = false;\n        \n        // Check horizontal placements\n        for (int r = 0; r < N && !found; r++) {\n            for (int c = 0; c < N && !found; c++) {\n                bool match = true;\n                for (int i = 0; i < (int)s.length(); i++) {\n                    int nc = (c + i) % N;\n                    if (matrix[r][nc] != s[i]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) {\n                    found = true;\n                }\n            }\n        }\n        \n        // Check vertical placements\n        if (!found) {\n            for (int c = 0; c < N && !found; c++) {\n                for (int r = 0; r < N && !found; r++) {\n                    bool match = true;\n                    for (int i = 0; i < (int)s.length(); i++) {\n                        int nr = (r + i) % N;\n                        if (matrix[nr][c] != s[i]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                    }\n                }\n            }\n        }\n        \n        if (found) count++;\n    }\n    return count;\n}\n\n// Try to place as many strings as possible\nvoid greedyPlacement() {\n    // Sort strings by length (longer first might be better)\n    vector<pair<int, int>> str_lengths;\n    for (int i = 0; i < M; i++) {\n        str_lengths.push_back({(int)strings[i].s.length(), i});\n    }\n    sort(str_lengths.rbegin(), str_lengths.rend());\n    \n    for (const auto& p : str_lengths) {\n        int idx = p.second;\n        const string& s = strings[idx].s;\n        \n        // Try to place this string\n        bool placed = false;\n        \n        // Try horizontal placements first\n        for (int r = 0; r < N && !placed; r++) {\n            for (int c = 0; c < N && !placed; c++) {\n                if (canPlace(s, r, c, true)) {\n                    placeString(s, r, c, true);\n                    strings[idx].placed = true;\n                    strings[idx].row = r;\n                    strings[idx].col = c;\n                    strings[idx].horizontal = true;\n                    placed = true;\n                }\n            }\n        }\n        \n        // Try vertical placements if horizontal didn't work\n        if (!placed) {\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    if (canPlace(s, r, c, false)) {\n                        placeString(s, r, c, false);\n                        strings[idx].placed = true;\n                        strings[idx].row = r;\n                        strings[idx].col = c;\n                        strings[idx].horizontal = false;\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Improve by trying to fill empty spots with valid characters only\nvoid fillEmptySpots() {\n    // For each empty cell, try to determine the best character\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matrix[r][c] == '.') {\n                // Count which characters would help match more strings\n                map<char, int> char_score;\n                \n                // Initialize all characters with a baseline\n                for (char ch : ALPHABET) {\n                    char_score[ch] = 0;\n                }\n                \n                // Test each character\n                for (char ch : ALPHABET) {\n                    char original = matrix[r][c];\n                    matrix[r][c] = ch;\n                    int new_matches = countMatches();\n                    matrix[r][c] = original; // Restore\n                    char_score[ch] = new_matches;\n                }\n                \n                // Choose character that maximizes matches, fallback to 'A' if all same\n                char best_char = 'A'; // Default to 'A' instead of '.'\n                int best_score = -1;\n                for (const auto& p : char_score) {\n                    if (p.second > best_score) {\n                        best_score = p.second;\n                        best_char = p.first;\n                    }\n                }\n                \n                matrix[r][c] = best_char;\n            }\n        }\n    }\n}\n\n// Simple randomized approach\nvoid randomImprovement() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    int current_matches = countMatches();\n    \n    // Try random changes with valid characters only\n    for (int iter = 0; iter < 1000; iter++) {\n        // Pick a random cell\n        int r = gen() % N;\n        int c = gen() % N;\n        char original = matrix[r][c];\n        \n        // Try a random valid character\n        char new_char = ALPHABET[gen() % ALPHABET.length()];\n        matrix[r][c] = new_char;\n        \n        int new_matches = countMatches();\n        if (new_matches < current_matches) {\n            matrix[r][c] = original; // Revert\n        } else {\n            current_matches = new_matches;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // N is fixed at 20, so we don't read it\n    cin >> M;\n    strings.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> strings[i].s;\n        strings[i].id = i;\n    }\n    \n    // Initialize matrix\n    for (int i = 0; i < N; i++) {\n        matrix[i] = string(N, '.');\n    }\n    \n    // Greedy placement\n    greedyPlacement();\n    \n    // Try to improve - but avoid filling with control characters\n    fillEmptySpots();\n    \n    // Final improvement\n    randomImprovement();\n    \n    // Ensure all characters are valid before output\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (matrix[i][j] != '.' && ALPHABET.find(matrix[i][j]) == string::npos) {\n                matrix[i][j] = 'A'; // Fallback to 'A' if somehow invalid\n            }\n        }\n    }\n    \n    // Output result\n    for (const string& row : matrix) {\n        cout << row << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 70;\nint N, si, sj;\nchar grid[MAX_N][MAX_N];\nbool is_road[MAX_N][MAX_N];\nint cost[MAX_N][MAX_N];\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Calculate visible squares from a given position\nset<pair<int,int>> get_visible_squares(int x, int y) {\n    set<pair<int,int>> visible;\n    \n    // Horizontal visibility (same row)\n    // Left direction\n    for (int j = y; j >= 0; j--) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    // Right direction\n    for (int j = y; j < N; j++) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    \n    // Vertical visibility (same column)\n    // Up direction\n    for (int i = x; i >= 0; i--) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    // Down direction\n    for (int i = x; i < N; i++) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    \n    return visible;\n}\n\n// Check if position is valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && is_road[x][y];\n}\n\n// BFS to find shortest path between two points\nvector<char> bfs_path(int start_x, int start_y, int end_x, int end_y) {\n    if (start_x == end_x && start_y == end_y) return {};\n    \n    queue<pair<int,int>> q;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    \n    q.push({start_x, start_y});\n    visited[start_x][start_y] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            \n            if (is_valid(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = {x, y};\n                q.push({nx, ny});\n                \n                if (nx == end_x && ny == end_y) {\n                    // Reconstruct path\n                    vector<char> path;\n                    int cx = end_x, cy = end_y;\n                    \n                    while (parent[cx][cy].first != -1) {\n                        auto [px, py] = parent[cx][cy];\n                        // Determine direction from parent to current\n                        if (cx == px - 1 && cy == py) path.push_back('U');\n                        else if (cx == px + 1 && cy == py) path.push_back('D');\n                        else if (cx == px && cy == py - 1) path.push_back('L');\n                        else if (cx == px && cy == py + 1) path.push_back('R');\n                        \n                        cx = px;\n                        cy = py;\n                    }\n                    \n                    reverse(path.begin(), path.end());\n                    return path;\n                }\n            }\n        }\n    }\n    \n    return {}; // No path found\n}\n\n// Get all road positions\nvector<pair<int,int>> get_all_roads() {\n    vector<pair<int,int>> roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) {\n                roads.push_back({i, j});\n            }\n        }\n    }\n    return roads;\n}\n\n// Count total roads\nint count_total_roads() {\n    int cnt = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) cnt++;\n        }\n    }\n    return cnt;\n}\n\n// Generate path using greedy coverage approach\nvector<char> generate_greedy_coverage_path() {\n    vector<char> path;\n    int current_x = si, current_y = sj;\n    \n    // Get all roads\n    auto all_roads = get_all_roads();\n    if (all_roads.empty()) return path;\n    \n    // Track covered roads\n    set<pair<int,int>> covered;\n    auto initial_visible = get_visible_squares(current_x, current_y);\n    covered.insert(initial_visible.begin(), initial_visible.end());\n    \n    // Limit iterations to prevent overly long paths\n    int max_iterations = min(300, (int)(N * N * 0.8));\n    \n    for (int iter = 0; iter < max_iterations && path.size() < 2800; iter++) {\n        // Find the position that maximizes new coverage\n        pair<int,int> best_pos = {-1, -1};\n        int best_new_coverage = -1;\n        vector<char> best_segment;\n        \n        // Sample some road positions to evaluate\n        int sample_size = min(50, (int)all_roads.size());\n        vector<pair<int,int>> candidates;\n        \n        // Include some random candidates and some strategic ones\n        for (int i = 0; i < sample_size && i < (int)all_roads.size(); i++) {\n            candidates.push_back(all_roads[(iter * 17 + i * 23) % all_roads.size()]);\n        }\n        \n        // Also include some positions that are likely to provide good coverage\n        for (int i = 0; i < N && (int)candidates.size() < sample_size + 20; i += max(1, N/10)) {\n            for (int j = 0; j < N && (int)candidates.size() < sample_size + 20; j += max(1, N/10)) {\n                if (is_road[i][j]) {\n                    candidates.push_back({i, j});\n                }\n            }\n        }\n        \n        for (const auto& pos : candidates) {\n            int target_x = pos.first;\n            int target_y = pos.second;\n            \n            // Skip if already at this position\n            if (target_x == current_x && target_y == current_y) continue;\n            \n            // Get path to this position\n            auto segment = bfs_path(current_x, current_y, target_x, target_y);\n            if (segment.empty()) continue;\n            \n            // Calculate new coverage from this position\n            auto visible = get_visible_squares(target_x, target_y);\n            int new_coverage = 0;\n            for (const auto& p : visible) {\n                if (covered.find(p) == covered.end()) {\n                    new_coverage++;\n                }\n            }\n            \n            // Prefer positions with good new coverage, but also consider path length\n            double score = (double)new_coverage / (segment.size() + 1);\n            if (new_coverage > best_new_coverage || \n                (new_coverage == best_new_coverage && (int)segment.size() < (int)best_segment.size())) {\n                best_new_coverage = new_coverage;\n                best_pos = {target_x, target_y};\n                best_segment = segment;\n            }\n        }\n        \n        // If no good position found, try a simple exploration\n        if (best_pos.first == -1) {\n            // Try moving in each direction\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = current_x + dx[dir];\n                int ny = current_y + dy[dir];\n                if (is_valid(nx, ny)) {\n                    best_segment = {dir_char[dir]};\n                    best_pos = {nx, ny};\n                    break;\n                }\n            }\n            if (best_pos.first == -1) break; // No valid moves\n        }\n        \n        // Add this segment to path\n        path.insert(path.end(), best_segment.begin(), best_segment.end());\n        current_x = best_pos.first;\n        current_y = best_pos.second;\n        \n        // Update coverage\n        auto new_visible = get_visible_squares(current_x, current_y);\n        covered.insert(new_visible.begin(), new_visible.end());\n        \n        // If we have good coverage, consider returning to start\n        if (covered.size() >= 0.95 * all_roads.size() && path.size() > 2000) {\n            break;\n        }\n    }\n    \n    // Return to start\n    if (current_x != si || current_y != sj) {\n        auto return_segment = bfs_path(current_x, current_y, si, sj);\n        path.insert(path.end(), return_segment.begin(), return_segment.end());\n    }\n    \n    return path;\n}\n\n// Optimize path by removing redundant segments\nvector<char> optimize_path(const vector<char>& original_path) {\n    if (original_path.empty()) return original_path;\n    \n    // Simulate path to verify it's valid\n    int x = si, y = sj;\n    bool valid = true;\n    \n    for (char c : original_path) {\n        int dir = -1;\n        for (int i = 0; i < 4; i++) {\n            if (dir_char[i] == c) {\n                dir = i;\n                break;\n            }\n        }\n        \n        if (dir != -1) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            if (is_valid(nx, ny)) {\n                x = nx;\n                y = ny;\n            } else {\n                valid = false;\n                break;\n            }\n        }\n    }\n    \n    // If invalid or doesn't return to start, fix it\n    if (!valid || x != si || y != sj) {\n        // Rebuild path with proper return\n        vector<char> fixed_path;\n        x = si; y = sj;\n        \n        int limit = min((int)original_path.size(), 2800);\n        for (int i = 0; i < limit; i++) {\n            char c = original_path[i];\n            int dir = -1;\n            for (int j = 0; j < 4; j++) {\n                if (dir_char[j] == c) {\n                    dir = j;\n                    break;\n                }\n            }\n            \n            if (dir != -1) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                if (is_valid(nx, ny)) {\n                    fixed_path.push_back(c);\n                    x = nx;\n                    y = ny;\n                }\n            }\n        }\n        \n        // Return to start\n        if (x != si || y != sj) {\n            auto return_segment = bfs_path(x, y, si, sj);\n            fixed_path.insert(fixed_path.end(), return_segment.begin(), return_segment.end());\n        }\n        \n        return fixed_path;\n    }\n    \n    return original_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j];\n            if (line[j] == '#') {\n                is_road[i][j] = false;\n            } else {\n                is_road[i][j] = true;\n                cost[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    // Generate path using greedy coverage approach\n    vector<char> path = generate_greedy_coverage_path();\n    \n    // Optimize path\n    path = optimize_path(path);\n    \n    // Final length check\n    if (path.size() > 2999) {\n        path.resize(2999);\n        path = optimize_path(path);\n    }\n    \n    // Output result\n    for (char c : path) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int MAX_N = 1000;\nconst int MAX_M = 20;\nconst int MAX_K = 20;\nconst int MAX_DAYS = 2000;\n\n// Global variables\nint N, M, K, R;\nvector<vector<int>> task_skills;  // [task][skill] = required level\nvector<vector<int>> member_skills; // [member][skill] = estimated level\nvector<vector<int>> task_times;    // [task][member] = observed time\nvector<vector<int>> dependencies;  // [task] = list of prerequisite tasks\nvector<vector<int>> reverse_dependencies; // [task] = list of dependent tasks\nvector<int> task_status;           // -1:not started, 0:in progress, 1:completed\nvector<int> member_status;         // -1:free, task_id:working on task\nvector<int> task_completion_day;   // when each task was completed\nvector<set<int>> completed_tasks_by_member; // track what each member completed\n\n// For skill estimation\nvector<int> task_start_day;\nvector<vector<pair<int,int>>> member_task_history; // {task_id, completion_time}\n\n// Topological sorting helper\nvector<int> in_degree;\nqueue<int> ready_tasks;\n\nvoid read_input() {\n    cin >> N >> M >> K >> R;\n    \n    task_skills.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_skills[i][j];\n        }\n    }\n    \n    dependencies.resize(N);\n    reverse_dependencies.resize(N);\n    in_degree.assign(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--; // Convert to 0-indexed\n        dependencies[v].push_back(u);\n        reverse_dependencies[u].push_back(v);\n        in_degree[v]++;\n    }\n}\n\n// Initialize data structures\nvoid initialize() {\n    task_status.assign(N, -1);\n    member_status.assign(M, -1);\n    task_completion_day.assign(N, -1);\n    task_start_day.assign(N, -1);\n    completed_tasks_by_member.resize(M);\n    member_task_history.resize(M);\n    \n    // Initialize skill estimates with reasonable defaults\n    member_skills.resize(M, vector<int>(K, 10)); // Start with moderate skills\n    task_times.resize(N, vector<int>(M, 1));     // Default time estimate\n    \n    // Find initially ready tasks (no dependencies)\n    for (int i = 0; i < N; i++) {\n        if (in_degree[i] == 0) {\n            ready_tasks.push(i);\n        }\n    }\n}\n\n// Estimate member skills based on history\nvoid update_skill_estimates() {\n    // Simple approach: for each member, look at tasks they completed quickly\n    for (int member = 0; member < M; member++) {\n        if (member_task_history[member].size() == 0) continue;\n        \n        // Look at recent successful completions (time = 1 day usually means skill >= difficulty)\n        map<int, vector<int>> skill_samples; // skill_index -> list of observed levels\n        \n        for (auto& [task_id, completion_time] : member_task_history[member]) {\n            if (completion_time <= 2) { // Completed quickly\n                for (int k = 0; k < K; k++) {\n                    // If completed quickly, member's skill is likely >= task requirement\n                    skill_samples[k].push_back(task_skills[task_id][k]);\n                }\n            }\n        }\n        \n        // Update skill estimates\n        for (int k = 0; k < K; k++) {\n            if (!skill_samples[k].empty()) {\n                // Take maximum observed requirement they handled well\n                sort(skill_samples[k].begin(), skill_samples[k].end());\n                member_skills[member][k] = max(member_skills[member][k], \n                                             skill_samples[k].back());\n            }\n        }\n    }\n}\n\n// Calculate estimated time for a member to complete a task\nint estimate_time(int task_id, int member_id) {\n    int w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0, task_skills[task_id][k] - member_skills[member_id][k]);\n    }\n    \n    if (w == 0) return 1;\n    else return max(1, w); // Simplified - ignoring randomness for planning\n}\n\n// Get best available member for a task\nint get_best_member(int task_id) {\n    int best_member = 0;\n    int min_time = estimate_time(task_id, 0);\n    \n    for (int member = 1; member < M; member++) {\n        int time = estimate_time(task_id, member);\n        if (time < min_time) {\n            min_time = time;\n            best_member = member;\n        }\n    }\n    \n    return best_member;\n}\n\n// Update ready tasks based on completed tasks\nvoid update_ready_tasks(int completed_task) {\n    for (int dependent : reverse_dependencies[completed_task]) {\n        in_degree[dependent]--;\n        if (in_degree[dependent] == 0) {\n            ready_tasks.push(dependent);\n        }\n    }\n}\n\n// Main assignment logic\nvector<pair<int, int>> assign_tasks(int current_day) {\n    vector<pair<int, int>> assignments;\n    \n    // Find free members\n    vector<int> free_members;\n    for (int member = 0; member < M; member++) {\n        if (member_status[member] == -1) {\n            free_members.push_back(member);\n        }\n    }\n    \n    if (free_members.empty() || ready_tasks.empty()) {\n        return assignments;\n    }\n    \n    // Create list of ready tasks with priorities\n    vector<pair<int, int>> task_priority; // {priority, task_id}\n    queue<int> temp_queue = ready_tasks; // Copy to avoid modifying original\n    \n    while (!temp_queue.empty()) {\n        int task_id = temp_queue.front();\n        temp_queue.pop();\n        \n        // Priority: tasks with more dependents first, then lower ID\n        int priority = -reverse_dependencies[task_id].size() * 1000 - task_id;\n        task_priority.push_back({priority, task_id});\n    }\n    \n    sort(task_priority.begin(), task_priority.end());\n    \n    // Assign tasks to free members\n    int task_count = min((int)free_members.size(), (int)task_priority.size());\n    \n    for (int i = 0; i < task_count; i++) {\n        int member_id = free_members[i];\n        int task_id = task_priority[i].second;\n        \n        // Remove this task from ready queue (we'll re-add if not assigned)\n        // Actually, let's handle this more carefully in the main loop\n        \n        assignments.push_back({member_id, task_id});\n        task_status[task_id] = 0; // Mark as in progress\n        member_status[member_id] = task_id;\n        task_start_day[task_id] = current_day;\n    }\n    \n    return assignments;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    read_input();\n    initialize();\n    \n    int day = 0;\n    \n    while (day < MAX_DAYS) {\n        day++;\n        \n        // Process completed tasks from previous day\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) {\n            break; // Done\n        }\n        \n        vector<int> completed_members(n_completed);\n        for (int i = 0; i < n_completed; i++) {\n            cin >> completed_members[i];\n            completed_members[i]--; // Convert to 0-indexed\n        }\n        \n        // Update based on completed tasks\n        for (int member_idx : completed_members) {\n            int task_id = member_status[member_idx];\n            if (task_id != -1) {\n                task_status[task_id] = 1;\n                task_completion_day[task_id] = day;\n                member_status[member_idx] = -1;\n                completed_tasks_by_member[member_idx].insert(task_id);\n                \n                // Record completion for skill estimation\n                int duration = day - task_start_day[task_id];\n                member_task_history[member_idx].push_back({task_id, duration});\n                \n                // Update ready tasks\n                update_ready_tasks(task_id);\n            }\n        }\n        \n        // Update skill estimates periodically\n        if (day % 10 == 0) {\n            update_skill_estimates();\n        }\n        \n        // Make new assignments\n        vector<pair<int, int>> assignments = assign_tasks(day);\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& [member, task] : assignments) {\n            cout << \" \" << (member + 1) << \" \" << (task + 1);\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst int NUM_ORDERS = 1000;\nconst int SELECT_COUNT = 50;\n\nstruct Order {\n    int id, a, b, c, d;\n};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan_distance(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nint manhattan_distance(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Simple greedy route construction\nvector<Point> build_route(const vector<Order>& selected_orders) {\n    vector<Point> route;\n    route.emplace_back(DEPOT_X, DEPOT_Y);\n    \n    // Create list of all points with their type and order id\n    vector<pair<Point, pair<int, bool>>> all_points; // point, {order_id, is_pickup}\n    \n    for (const auto& order : selected_orders) {\n        all_points.emplace_back(Point(order.a, order.b), make_pair(order.id, true));   // pickup\n        all_points.emplace_back(Point(order.c, order.d), make_pair(order.id, false));  // delivery\n    }\n    \n    vector<bool> picked_up(NUM_ORDERS + 1, false);\n    \n    // Greedy construction: at each step, pick the nearest valid point\n    while (!all_points.empty()) {\n        Point current = route.back();\n        int best_idx = -1;\n        int best_dist = 1e9;\n        \n        // Find the best next point to visit\n        for (size_t i = 0; i < all_points.size(); i++) {\n            const Point& point = all_points[i].first;\n            int order_id = all_points[i].second.first;\n            bool is_pickup = all_points[i].second.second;\n            \n            if (is_pickup) {\n                // Always valid to pick up\n                int dist = manhattan_distance(current, point);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_idx = i;\n                }\n            } else {\n                // Can only deliver if picked up\n                if (picked_up[order_id]) {\n                    int dist = manhattan_distance(current, point);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        // If no valid delivery found, pick the closest pickup\n        if (best_idx == -1) {\n            for (size_t i = 0; i < all_points.size(); i++) {\n                const Point& point = all_points[i].first;\n                bool is_pickup = all_points[i].second.second;\n                if (is_pickup) {\n                    int dist = manhattan_distance(current, point);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        // If still no point found, take the first one\n        if (best_idx == -1) {\n            best_idx = 0;\n        }\n        \n        // Add the selected point to route\n        const Point& selected_point = all_points[best_idx].first;\n        int order_id = all_points[best_idx].second.first;\n        bool is_pickup = all_points[best_idx].second.second;\n        \n        route.push_back(selected_point);\n        \n        if (is_pickup) {\n            picked_up[order_id] = true;\n        }\n        \n        // Remove the selected point\n        all_points.erase(all_points.begin() + best_idx);\n    }\n    \n    // Return to depot\n    route.emplace_back(DEPOT_X, DEPOT_Y);\n    \n    return route;\n}\n\n// Select orders based on efficiency\nvector<Order> select_orders(vector<Order>& orders) {\n    // Calculate efficiency score: direct distance + average distance to depot\n    vector<pair<int, int>> scores; // {score, order_id}\n    \n    for (int i = 0; i < NUM_ORDERS; i++) {\n        int direct_dist = manhattan_distance(orders[i].a, orders[i].b, orders[i].c, orders[i].d);\n        int pickup_dist = manhattan_distance(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b);\n        int delivery_dist = manhattan_distance(DEPOT_X, DEPOT_Y, orders[i].c, orders[i].d);\n        int score = direct_dist + (pickup_dist + delivery_dist) / 2;\n        scores.emplace_back(score, i);\n    }\n    \n    // Sort by score (lower is better)\n    sort(scores.begin(), scores.end());\n    \n    // Select best orders\n    vector<Order> selected_orders;\n    for (int i = 0; i < SELECT_COUNT; i++) {\n        selected_orders.push_back(orders[scores[i].second]);\n    }\n    \n    return selected_orders;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<Order> orders(NUM_ORDERS);\n    \n    // Read input\n    for (int i = 0; i < NUM_ORDERS; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i + 1;\n    }\n    \n    // Select orders\n    vector<Order> selected_orders = select_orders(orders);\n    \n    // Build route\n    vector<Point> route = build_route(selected_orders);\n    \n    // Output selected orders\n    cout << SELECT_COUNT;\n    for (const auto& order : selected_orders) {\n        cout << \" \" << order.id;\n    }\n    cout << \"\\n\";\n    \n    // Output route\n    cout << route.size();\n    for (const auto& point : route) {\n        cout << \" \" << point.x << \" \" << point.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u, v;\n    int d; // euclidean distance (rounded)\n    int l; // actual length (revealed online)\n    double ratio; // l/d ratio\n};\n\nvector<pair<int, int>> coords(N);\nvector<Edge> edges(M);\nvector<int> parent(N);\nint component_count = N;\n\nvoid init_union_find() {\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n}\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nbool unite(int x, int y) {\n    x = find(x);\n    y = find(y);\n    if (x == y) return false;\n    parent[x] = y;\n    component_count--;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read coordinates\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        \n        // Calculate euclidean distance\n        long long dx = coords[edges[i].u].first - coords[edges[i].v].first;\n        long long dy = coords[edges[i].u].second - coords[edges[i].v].second;\n        edges[i].d = (int)round(sqrt(dx * dx + dy * dy));\n    }\n    \n    init_union_find();\n    \n    // Process each edge as it comes\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        edges[i].l = l;\n        edges[i].ratio = (double)l / edges[i].d;\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        // Check if this edge connects two different components\n        bool would_connect = (find(u) != find(v));\n        \n        bool accept = false;\n        \n        // Always accept edges that connect different components until we have a spanning tree\n        if (would_connect && component_count > 1) {\n            accept = true;\n        }\n        // For remaining edges, be selective based on cost efficiency\n        else if (component_count == 1) {\n            // Even after connectivity, accept very cheap edges that could improve the tree\n            // Only accept if significantly better than average\n            if (edges[i].ratio <= 1.3) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            unite(u, v);\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nconst int INF = 100000000;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Point pos;\n    int type;\n    Pet() : pos(0, 0), type(0) {}\n    Pet(Point p, int t) : pos(p), type(t) {}\n};\n\nstruct Human {\n    Point pos;\n    Human() : pos(0, 0) {}\n    Human(Point p) : pos(p) {}\n};\n\n// Directions: up, down, left, right\nconst vector<Point> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"UDLR\";\nconst string BLOCK_CHARS = \"udlr\";\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nvector<vector<int>> grid; // 0 = passable, 1 = blocked\nvector<vector<int>> pet_count; // count of pets in each cell\n\n// Check if position is valid\nbool valid(int x, int y) {\n    return x >= 1 && x <= H && y >= 1 && y <= W;\n}\n\nbool valid_point(Point p) {\n    return valid(p.x, p.y);\n}\n\n// Get adjacent points\nvector<Point> get_adjacent(Point p) {\n    vector<Point> adj;\n    for (auto& d : DIRS) {\n        Point np = {p.x + d.x, p.y + d.y};\n        if (valid_point(np)) {\n            adj.push_back(np);\n        }\n    }\n    return adj;\n}\n\n// BFS to calculate reachable area size from a point\nint calculate_area_size(Point start) {\n    if (!valid_point(start) || grid[start.x][start.y] == 1) return 0;\n    \n    vector<vector<bool>> visited(H + 1, vector<bool>(W + 1, false));\n    queue<Point> q;\n    q.push(start);\n    visited[start.x][start.y] = true;\n    int size = 0;\n    \n    while (!q.empty()) {\n        Point cur = q.front(); q.pop();\n        size++;\n        \n        for (auto& d : DIRS) {\n            Point next = {cur.x + d.x, cur.y + d.y};\n            if (valid_point(next) && !visited[next.x][next.y] && grid[next.x][next.y] == 0) {\n                visited[next.x][next.y] = true;\n                q.push(next);\n            }\n        }\n    }\n    \n    return size;\n}\n\n// Count pets in reachable area from a point\nint count_pets_in_area(Point start) {\n    if (!valid_point(start) || grid[start.x][start.y] == 1) return 0;\n    \n    vector<vector<bool>> visited(H + 1, vector<bool>(W + 1, false));\n    queue<Point> q;\n    q.push(start);\n    visited[start.x][start.y] = true;\n    int pet_count_area = 0;\n    \n    while (!q.empty()) {\n        Point cur = q.front(); q.pop();\n        pet_count_area += pet_count[cur.x][cur.y];\n        \n        for (auto& d : DIRS) {\n            Point next = {cur.x + d.x, cur.y + d.y};\n            if (valid_point(next) && !visited[next.x][next.y] && grid[next.x][next.y] == 0) {\n                visited[next.x][next.y] = true;\n                q.push(next);\n            }\n        }\n    }\n    \n    return pet_count_area;\n}\n\n// Simple heuristic: if we can block a square that limits pet movement, do it\nstring decide_actions(int turn) {\n    string actions(M, '.');\n    \n    // Update pet count grid\n    pet_count.assign(H + 1, vector<int>(W + 1, 0));\n    for (const auto& pet : pets) {\n        if (valid_point(pet.pos)) {\n            pet_count[pet.pos.x][pet.pos.y]++;\n        }\n    }\n    \n    // Early turns: just observe and move away from pets\n    if (turn < 50) {\n        for (int i = 0; i < M; i++) {\n            // Move away from nearby pets if possible\n            Point cur = humans[i].pos;\n            bool moved = false;\n            \n            // Check if any pet is adjacent\n            for (auto& pet : pets) {\n                if (abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y) <= 2) {\n                    // Try to move away\n                    for (int d = 0; d < 4; d++) {\n                        Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                        if (valid_point(next) && grid[next.x][next.y] == 0) {\n                            // Check if this move takes us away from pets\n                            int dist_to_pet = abs(pet.pos.x - next.x) + abs(pet.pos.y - next.y);\n                            int cur_dist = abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y);\n                            if (dist_to_pet > cur_dist) {\n                                actions[i] = DIR_CHARS[d];\n                                moved = true;\n                                break;\n                            }\n                        }\n                    }\n                    if (moved) break;\n                }\n            }\n            \n            // If we didn't move, try to block strategically\n            if (!moved && turn > 20) {\n                for (int d = 0; d < 4; d++) {\n                    Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                        // Don't block if pet is adjacent to the square we want to block\n                        bool pet_adjacent = false;\n                        for (auto& pet : pets) {\n                            if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                                pet_adjacent = true;\n                                break;\n                            }\n                        }\n                        if (!pet_adjacent) {\n                            actions[i] = BLOCK_CHARS[d];\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    // Mid game: start creating barriers\n    else if (turn < 200) {\n        for (int i = 0; i < M; i++) {\n            Point cur = humans[i].pos;\n            \n            // Try to block to create isolated areas\n            // Prefer blocking squares that separate areas with fewer pets\n            vector<pair<int, int>> candidates; // {score, direction}\n            \n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                    // Don't block if pet is adjacent\n                    bool pet_adjacent = false;\n                    for (auto& pet : pets) {\n                        if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                            pet_adjacent = true;\n                            break;\n                        }\n                    }\n                    if (!pet_adjacent) {\n                        // Score based on potential to create good areas\n                        grid[block_pos.x][block_pos.y] = 1;\n                        int area_size = calculate_area_size(cur);\n                        int pet_count_area = count_pets_in_area(cur);\n                        grid[block_pos.x][block_pos.y] = 0;\n                        \n                        double score = (double)area_size / (1 + pet_count_area);\n                        candidates.push_back({(int)(score * 1000), d});\n                    }\n                }\n            }\n            \n            if (!candidates.empty()) {\n                sort(candidates.rbegin(), candidates.rend());\n                actions[i] = BLOCK_CHARS[candidates[0].second];\n            } else {\n                // If no good blocking, try to move to better position\n                int best_score = -1;\n                int best_dir = -1;\n                \n                for (int d = 0; d < 4; d++) {\n                    Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                    if (valid_point(next) && grid[next.x][next.y] == 0) {\n                        int area_size = calculate_area_size(next);\n                        int pet_count_area = count_pets_in_area(next);\n                        int score = area_size - pet_count_area * 10;\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_dir = d;\n                        }\n                    }\n                }\n                \n                if (best_dir != -1) {\n                    actions[i] = DIR_CHARS[best_dir];\n                }\n            }\n        }\n    }\n    // Late game: optimize final positions\n    else {\n        for (int i = 0; i < M; i++) {\n            Point cur = humans[i].pos;\n            \n            // Calculate current situation\n            int current_area = calculate_area_size(cur);\n            int current_pets = count_pets_in_area(cur);\n            double current_score = (double)current_area / 900.0 * pow(2.0, -current_pets);\n            \n            // Try all possible actions and pick the best\n            double best_score = current_score;\n            char best_action = '.';\n            \n            // Try blocking\n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0) {\n                    // Don't block if pet is adjacent\n                    bool pet_adjacent = false;\n                    for (auto& pet : pets) {\n                        if (abs(pet.pos.x - block_pos.x) + abs(pet.pos.y - block_pos.y) <= 1) {\n                            pet_adjacent = true;\n                            break;\n                        }\n                    }\n                    if (!pet_adjacent) {\n                        grid[block_pos.x][block_pos.y] = 1;\n                        int new_area = calculate_area_size(cur);\n                        int new_pets = count_pets_in_area(cur);\n                        double new_score = (double)new_area / 900.0 * pow(2.0, -new_pets);\n                        grid[block_pos.x][block_pos.y] = 0;\n                        \n                        if (new_score > best_score) {\n                            best_score = new_score;\n                            best_action = BLOCK_CHARS[d];\n                        }\n                    }\n                }\n            }\n            \n            // Try moving\n            for (int d = 0; d < 4; d++) {\n                Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(next) && grid[next.x][next.y] == 0) {\n                    int new_area = calculate_area_size(next);\n                    int new_pets = count_pets_in_area(next);\n                    double new_score = (double)new_area / 900.0 * pow(2.0, -new_pets);\n                    \n                    if (new_score > best_score) {\n                        best_score = new_score;\n                        best_action = DIR_CHARS[d];\n                    }\n                }\n            }\n            \n            actions[i] = best_action;\n        }\n    }\n    \n    return actions;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Initialize grid\n    grid.assign(H + 1, vector<int>(W + 1, 0));\n    \n    // Read initial positions\n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t;\n        cin >> x >> y >> t;\n        pets[i] = Pet(Point(x, y), t);\n    }\n    \n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        humans[i] = Human(Point(x, y));\n    }\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // Decide actions\n        string actions = decide_actions(turn);\n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        string pet_moves;\n        getline(cin, pet_moves);\n        if (pet_moves.empty()) {\n            getline(cin, pet_moves);\n        }\n        \n        stringstream ss(pet_moves);\n        string move;\n        for (int i = 0; i < N && ss >> move; i++) {\n            // Update pet position based on movement\n            for (char c : move) {\n                switch (c) {\n                    case 'U': pets[i].pos.x--; break;\n                    case 'D': pets[i].pos.x++; break;\n                    case 'L': pets[i].pos.y--; break;\n                    case 'R': pets[i].pos.y++; break;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint si, sj, ti, tj;\ndouble p;\nbool h_wall[N][N-1]; // horizontal walls\nbool v_wall[N-1][N]; // vertical walls\n\n// Direction mappings\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nbool can_move(int x, int y, int dir) {\n    if (dir == 0) { // Up\n        if (x == 0) return false;\n        return !v_wall[x-1][y];\n    } else if (dir == 1) { // Down\n        if (x == N-1) return false;\n        return !v_wall[x][y];\n    } else if (dir == 2) { // Left\n        if (y == 0) return false;\n        return !h_wall[x][y-1];\n    } else { // Right\n        if (y == N-1) return false;\n        return !h_wall[x][y];\n    }\n}\n\n// Create a robust path using a strategy that builds in redundancy\nstring create_robust_path() {\n    string path;\n    \n    // Strategy: Create a path with built-in redundancy\n    // We'll use a \"thick path\" approach where we don't just follow\n    // the shortest route, but create a wider corridor\n    \n    int x = si, y = sj;\n    \n    // Since home is in top-left (0-4, 0-4) and office is in bottom-right (15-19, 15-19)\n    // We generally want to go right and down\n    \n    // Main strategy:\n    // 1. Go right in a robust manner\n    // 2. Go down in a robust manner\n    // 3. Fine-tune to exact position\n    \n    // Phase 1: Move toward target column with redundancy\n    while (y < tj && path.length() < 180) {\n        if (can_move(x, y, 3)) { // Right\n            path += 'R';\n            y++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try down then right\n            if (x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n                moved = true;\n            } else if (x > 0 && can_move(x, y, 0)) {\n                path += 'U';\n                x--;\n                moved = true;\n            }\n            \n            if (moved && y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n            } else if (moved) {\n                // Undo the vertical move if we can't go right\n                if (x > si) {\n                    path += 'U';\n                    x--;\n                } else {\n                    path += 'D';\n                    x++;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Move toward target row with redundancy\n    while (x < ti && path.length() < 195) {\n        if (can_move(x, y, 1)) { // Down\n            path += 'D';\n            x++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try right then down\n            if (y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n                moved = true;\n            } else if (y > 0 && can_move(x, y, 2)) {\n                path += 'L';\n                y--;\n                moved = true;\n            }\n            \n            if (moved && x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n            } else if (moved) {\n                // Undo the horizontal move if we can't go down\n                if (y > sj) {\n                    path += 'L';\n                    y--;\n                } else {\n                    path += 'R';\n                    y++;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Fine adjustment\n    while ((x != ti || y != tj) && path.length() < 200) {\n        if (x < ti && can_move(x, y, 1)) {\n            path += 'D';\n            x++;\n        } else if (x > ti && can_move(x, y, 0)) {\n            path += 'U';\n            x--;\n        } else if (y < tj && can_move(x, y, 3)) {\n            path += 'R';\n            y++;\n        } else if (y > tj && can_move(x, y, 2)) {\n            path += 'L';\n            y--;\n        } else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Alternative approach: Create a path with explicit redundancy\nstring create_redundant_path() {\n    string path;\n    int x = si, y = sj;\n    \n    // Create a path where every few steps, we add a small loop\n    // This provides redundancy - if one move is forgotten, \n    // the loop gives us another chance\n    \n    int steps_since_loop = 0;\n    \n    while ((x != ti || y != tj) && path.length() < 200) {\n        // Determine best direction\n        int best_dir = -1;\n        int best_value = -1000;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(x, y, dir)) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                // Heuristic: prefer moves that get us closer to target\n                int value = -(abs(nx - ti) + abs(ny - tj));\n                \n                // Slight preference for right/down moves to maintain progress\n                if (dir == 1 || dir == 3) value += 1;\n                \n                if (value > best_value) {\n                    best_value = value;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            path += dir_char[best_dir];\n            x += dx[best_dir];\n            y += dy[best_dir];\n            steps_since_loop++;\n            \n            // Every few steps, add a small redundant loop if space allows\n            if (steps_since_loop >= 4 && path.length() < 190) {\n                // Try to add a small 2-step loop\n                int perpendicular_dir1 = (best_dir + 1) % 4;\n                int perpendicular_dir2 = (best_dir + 3) % 4;\n                \n                if (can_move(x, y, perpendicular_dir1) && \n                    can_move(x + dx[perpendicular_dir1], y + dy[perpendicular_dir1], \n                             (perpendicular_dir1 + 2) % 4) &&\n                    path.length() < 198) {\n                    path += dir_char[perpendicular_dir1];\n                    path += dir_char[(perpendicular_dir1 + 2) % 4];\n                    steps_since_loop = 0;\n                } else if (can_move(x, y, perpendicular_dir2) && \n                           can_move(x + dx[perpendicular_dir2], y + dy[perpendicular_dir2], \n                                    (perpendicular_dir2 + 2) % 4) &&\n                           path.length() < 198) {\n                    path += dir_char[perpendicular_dir2];\n                    path += dir_char[(perpendicular_dir2 + 2) % 4];\n                    steps_since_loop = 0;\n                }\n            }\n        } else {\n            break; // No valid moves\n        }\n    }\n    \n    return path;\n}\n\nint main() {\n    // Read input\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N-1; j++) {\n            h_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N-1; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            v_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Generate path - try the redundant approach\n    string result = create_redundant_path();\n    \n    // Fallback to simpler approach if needed\n    if (result.empty() || result.length() > 200) {\n        result = create_robust_path();\n    }\n    \n    // Ensure we don't exceed 200 characters\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction: 0=left, 1=up, 2=right, 3=down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Transition table: to[tile_type][entry_direction] = exit_direction (-1 if invalid)\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // tile 0\n    {3, -1, -1, 0},  // tile 1\n    {-1, -1, 3, 2},  // tile 2\n    {-1, 2, 1, -1},  // tile 3\n    {1, 0, 3, 2},    // tile 4\n    {3, 2, 1, 0},    // tile 5\n    {2, -1, 0, -1},  // tile 6\n    {-1, 3, -1, 1}   // tile 7\n};\n\nconst int N = 30;\nint grid[N][N];\nint rotation[N][N];\n\n// Get actual tile type after rotation\nint get_rotated_tile(int base_tile, int rot) {\n    static const int rotation_map[8][4] = {\n        {0, 1, 2, 3},  // tile 0\n        {1, 2, 3, 0},  // tile 1\n        {2, 3, 0, 1},  // tile 2\n        {3, 0, 1, 2},  // tile 3\n        {4, 5, 4, 5},  // tile 4\n        {5, 4, 5, 4},  // tile 5\n        {6, 7, 6, 7},  // tile 6\n        {7, 6, 7, 6}   // tile 7\n    };\n    return rotation_map[base_tile][rot % 4];\n}\n\n// Check if coordinates are valid\nbool valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\n// Find loop length starting from position (si,sj) entering from direction sd\nint find_loop_length(int si, int sj, int sd, bool visited[N][N][4]) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        if (visited[i][j][d]) return 0;  // Already part of another loop\n        visited[i][j][d] = true;\n        \n        int tile_type = get_rotated_tile(grid[i][j], rotation[i][j]);\n        int d2 = to[tile_type][d];\n        \n        if (d2 == -1) return 0;  // Broken line\n        \n        i += di[d2];\n        j += dj[d2];\n        \n        if (!valid(i, j)) return 0;  // Out of bounds\n        \n        d = (d2 + 2) % 4;  // Reverse direction\n        length++;\n        \n        if (length > 1000) return 0;  // Prevent infinite loops\n        \n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\n// Find all loops and return their lengths\nvector<int> find_all_loops() {\n    vector<int> loops;\n    bool visited[N][N][4] = {};\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (!visited[i][j][d]) {\n                    int length = find_loop_length(i, j, d, visited);\n                    if (length > 0) {\n                        loops.push_back(length);\n                    }\n                }\n            }\n        }\n    }\n    \n    sort(loops.rbegin(), loops.rend());\n    return loops;\n}\n\n// Calculate score\nlong long calculate_score() {\n    vector<int> loops = find_all_loops();\n    if (loops.size() < 2) return 0;\n    return 1LL * loops[0] * loops[1];\n}\n\n// Fast incremental evaluation - only check loops that might be affected\nlong long fast_evaluate_change(int ci, int cj, int new_rot) {\n    int old_rot = rotation[ci][cj];\n    rotation[ci][cj] = new_rot;\n    \n    long long score = calculate_score();\n    \n    rotation[ci][cj] = old_rot;  // Restore\n    return score;\n}\n\n// Simple greedy improvement with limited iterations\nvoid greedy_improve() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    \n    long long best_score = calculate_score();\n    \n    // Limited iterations for speed\n    for (int iter = 0; iter < 10000; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        int best_rotation = old_rotation;\n        long long best_local_score = 0;\n        \n        // Try all 3 other rotations\n        for (int r = 1; r < 4; r++) {\n            int new_rot = (old_rotation + r) % 4;\n            long long score = fast_evaluate_change(i, j, new_rot);\n            if (score > best_local_score) {\n                best_local_score = score;\n                best_rotation = new_rot;\n            }\n        }\n        \n        if (best_local_score > best_score) {\n            rotation[i][j] = best_rotation;\n            best_score = best_local_score;\n        }\n    }\n}\n\n// Initialize with a simple pattern\nvoid initialize_simple() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            // Simple initialization - try to make some connectivity\n            if (grid[i][j] >= 4 && grid[i][j] <= 5) {\n                rotation[i][j] = 0;  // Double curves as is\n            } else if (grid[i][j] >= 6 && grid[i][j] <= 7) {\n                rotation[i][j] = 0;  // Straights as is\n            } else {\n                rotation[i][j] = 0;  // Curves as is\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Initialize\n    initialize_simple();\n    \n    // Improve using greedy approach\n    greedy_improve();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 10;\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst char inv_dir_chars[4] = {'D', 'U', 'R', 'L'};\n\nint N, T;\nint board[MAX_N][MAX_N];\nint empty_x, empty_y;\n\n// Check if two adjacent tiles are connected\nbool isConnected(int x1, int y1, int x2, int y2) {\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (board[x1][y1] == 0 || board[x2][y2] == 0) return false;\n    \n    // Check if they connect\n    if (x1 == x2 && y1 == y2 - 1) { // Right connection\n        return (board[x1][y1] & 4) && (board[x2][y2] & 1);\n    }\n    if (x1 == x2 && y1 == y2 + 1) { // Left connection\n        return (board[x1][y1] & 1) && (board[x2][y2] & 4);\n    }\n    if (x1 == x2 - 1 && y1 == y2) { // Down connection\n        return (board[x1][y1] & 8) && (board[x2][y2] & 2);\n    }\n    if (x1 == x2 + 1 && y1 == y2) { // Up connection\n        return (board[x1][y1] & 2) && (board[x2][y2] & 8);\n    }\n    return false;\n}\n\n// Find all connected components\nvector<vector<int>> findComponents() {\n    vector<vector<int>> component_id(N, vector<int>(N, -1));\n    int current_component = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || component_id[i][j] != -1) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({i, j});\n            component_id[i][j] = current_component;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                \n                // Check 4 neighbors\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dx[k];\n                    int ny = y + dy[k];\n                    \n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && \n                        component_id[nx][ny] == -1 && board[nx][ny] != 0 && \n                        isConnected(x, y, nx, ny)) {\n                        component_id[nx][ny] = current_component;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            current_component++;\n        }\n    }\n    \n    return component_id;\n}\n\n// Count component sizes\nvector<int> getComponentSizes(const vector<vector<int>>& component_id) {\n    int max_id = -1;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (component_id[i][j] > max_id) max_id = component_id[i][j];\n        }\n    }\n    \n    vector<int> sizes(max_id + 1, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (component_id[i][j] != -1) {\n                sizes[component_id[i][j]]++;\n            }\n        }\n    }\n    \n    return sizes;\n}\n\n// Calculate how many components would be connected by a move\nint calculateConnectionGain(int from_x, int from_y) {\n    // Temporarily move the tile\n    int temp = board[from_x][from_y];\n    board[from_x][from_y] = 0;\n    board[empty_x][empty_y] = temp;\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    \n    // Find components after move\n    auto component_id = findComponents();\n    auto sizes = getComponentSizes(component_id);\n    \n    int max_component_size = 0;\n    if (!sizes.empty()) {\n        max_component_size = *max_element(sizes.begin(), sizes.end());\n    }\n    \n    // Count how many components would be reduced (meaning they got connected)\n    int unique_components = 0;\n    for (int size : sizes) {\n        if (size > 0) unique_components++;\n    }\n    \n    // Restore\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    board[empty_x][empty_y] = 0;\n    board[from_x][from_y] = temp;\n    \n    // Return a score that prioritizes larger components and fewer total components\n    return max_component_size * 1000 - unique_components;\n}\n\n// Try to make a move\nbool makeMove(char move, string& result) {\n    int dir = -1;\n    for (int i = 0; i < 4; i++) {\n        if (dir_chars[i] == move) {\n            dir = i;\n            break;\n        }\n    }\n    \n    int new_x = empty_x + dx[dir];\n    int new_y = empty_y + dy[dir];\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) {\n        return false;\n    }\n    \n    // Perform move\n    board[empty_x][empty_y] = board[new_x][new_y];\n    board[new_x][new_y] = 0;\n    empty_x = new_x;\n    empty_y = new_y;\n    result += move;\n    \n    return true;\n}\n\n// Get current largest tree size\nint getCurrentMaxComponentSize() {\n    auto component_id = findComponents();\n    auto sizes = getComponentSizes(component_id);\n    \n    if (sizes.empty()) return 0;\n    return *max_element(sizes.begin(), sizes.end());\n}\n\n// Check if we can form connections with neighbors of the empty cell\nint getNeighborConnectionPotential() {\n    int potential = 0;\n    for (int k = 0; k < 4; k++) {\n        int nx = empty_x + dx[k];\n        int ny = empty_y + dy[k];\n        if (nx >= 0 && nx < N && ny >= 0 && ny < N && board[nx][ny] != 0) {\n            potential++;\n        }\n    }\n    return potential;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    \n    // Read board\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_x = i;\n                empty_y = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int last_dir = -1;\n    \n    // Enhanced approach with better component analysis\n    for (int step = 0; step < T && (int)result.length() < T; step++) {\n        int best_score = INT_MIN;\n        int best_dir = -1;\n        \n        // Try all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            // Avoid immediate reversals unless necessary\n            if (step > 0 && dir == (last_dir ^ 1)) continue;\n            \n            int from_x = empty_x + dx[dir];\n            int from_y = empty_y + dy[dir];\n            \n            if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n            \n            int score = calculateConnectionGain(from_x, from_y);\n            \n            // Bonus for moves that could connect to multiple neighbors\n            if (step < T * 0.7) { // In early game, prioritize flexibility\n                // Temporarily make move to check neighbor potential\n                int temp = board[from_x][from_y];\n                board[from_x][from_y] = 0;\n                board[empty_x][empty_y] = temp;\n                swap(empty_x, from_x);\n                swap(empty_y, from_y);\n                \n                score += getNeighborConnectionPotential() * 10;\n                \n                // Restore\n                swap(empty_x, from_x);\n                swap(empty_y, from_y);\n                board[empty_x][empty_y] = 0;\n                board[from_x][from_y] = temp;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        // If no good move found, relax constraints\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                \n                if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n                \n                int score = calculateConnectionGain(from_x, from_y);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        // If still no move, pick any valid move\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                if (from_x >= 0 && from_x < N && from_y >= 0 && from_y < N) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            makeMove(dir_chars[best_dir], result);\n            last_dir = best_dir;\n        } else {\n            break;\n        }\n        \n        // Early termination if we have a near-optimal solution\n        int current_max = getCurrentMaxComponentSize();\n        if (current_max >= N * N - 2 && result.length() < T * 0.7) {\n            // Try a few more moves to complete the tree\n            if (result.length() + 10 < T) {\n                continue;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing P = pair<int, int>;\n\nconst int MAX_N = 10000;\nconst int RADIUS = 10000;\nconst int BOUND = 1000000000;\n\nstruct Strawberry {\n    int x, y;\n    int id;\n};\n\nint N, K;\nint a[11]; // a[1] to a[10]\nvector<Strawberry> strawberries;\n\n// Generate line through two points\ntuple<ll, ll, ll, ll> line_through_points(ll x1, ll y1, ll x2, ll y2) {\n    if (x1 == x2 && y1 == y2) {\n        x2 += 1;\n    }\n    return {x1, y1, x2, y2};\n}\n\n// Calculate centroid of strawberries\npair<double, double> calculate_centroid() {\n    if (strawberries.empty()) return {0, 0};\n    \n    double sum_x = 0, sum_y = 0;\n    for (const auto& s : strawberries) {\n        sum_x += s.x;\n        sum_y += s.y;\n    }\n    return {sum_x / N, sum_y / N};\n}\n\n// Strategy: Adaptive approach based on strawberry distribution\nvoid adaptive_strategy(vector<tuple<ll, ll, ll, ll>>& lines) {\n    if (strawberries.empty()) return;\n    \n    // Calculate centroid\n    auto [centroid_x, centroid_y] = calculate_centroid();\n    \n    int used_lines = 0;\n    \n    // Create a mix of different line types\n    \n    // 1. Radial lines from centroid\n    int radial_count = min(20, K/3);\n    for (int i = 0; i < radial_count && used_lines < K; i++) {\n        double angle = 2.0 * M_PI * i / max(1, radial_count);\n        // Perturb angles slightly to avoid degenerate cases\n        double perturbation = (double)(i % 7 - 3) * 0.1;\n        angle += perturbation;\n        \n        ll px = (ll)(centroid_x + 100000 * cos(angle));\n        ll py = (ll)(centroid_y + 100000 * sin(angle));\n        ll qx = (ll)(centroid_x - 100000 * cos(angle));\n        ll qy = (ll)(centroid_y - 100000 * sin(angle));\n        lines.push_back({px, py, qx, qy});\n        used_lines++;\n    }\n    \n    // 2. Grid lines\n    int grid_dim = min(8, (int)sqrt((K - used_lines)/2));\n    if (grid_dim > 0) {\n        // Horizontal lines\n        for (int i = 0; i <= grid_dim && used_lines < K; i++) {\n            double ratio = (double)i / max(1, grid_dim);\n            int y_pos = (int)(centroid_y - RADIUS + 2 * RADIUS * ratio);\n            lines.push_back(line_through_points(-BOUND, y_pos, BOUND, y_pos));\n            used_lines++;\n        }\n        \n        // Vertical lines\n        for (int i = 0; i <= grid_dim && used_lines < K; i++) {\n            double ratio = (double)i / max(1, grid_dim);\n            int x_pos = (int)(centroid_x - RADIUS + 2 * RADIUS * ratio);\n            lines.push_back(line_through_points(x_pos, -BOUND, x_pos, BOUND));\n            used_lines++;\n        }\n    }\n    \n    // 3. Strategic separators between nearby strawberries\n    // Sort strawberries by distance from centroid\n    vector<pair<double, int>> distances;\n    for (int i = 0; i < N; i++) {\n        double dist = sqrt(pow(strawberries[i].x - centroid_x, 2) + pow(strawberries[i].y - centroid_y, 2));\n        distances.push_back({dist, i});\n    }\n    sort(distances.begin(), distances.end());\n    \n    // Create separators for strawberries close to each other\n    for (int i = 0; i < min(20, N-1) && used_lines < K - 5; i++) {\n        int idx1 = distances[i].second;\n        int idx2 = distances[(i+1) % N].second;\n        \n        if (idx1 != idx2) {\n            // Perpendicular bisector\n            int mid_x = (strawberries[idx1].x + strawberries[idx2].x) / 2;\n            int mid_y = (strawberries[idx1].y + strawberries[idx2].y) / 2;\n            int dx = strawberries[idx2].x - strawberries[idx1].x;\n            int dy = strawberries[idx2].y - strawberries[idx1].y;\n            \n            // Add some perturbation to avoid degenerate cases\n            lines.push_back(line_through_points(\n                mid_x - dy + (i%5 - 2), \n                mid_y + dx + (i%7 - 3),\n                mid_x + dy + (i%3 - 1), \n                mid_y - dx + (i%4 - 2)\n            ));\n            used_lines++;\n        }\n    }\n    \n    // 4. Create bounding boxes for high-priority single strawberries\n    // Focus on creating isolated regions for a_1 (single strawberry demand)\n    for (int i = 0; i < min(5, a[1]) && used_lines < K - 2; i++) {\n        if (i < N) {\n            int x = strawberries[i].x;\n            int y = strawberries[i].y;\n            \n            // Small bounding box with slight perturbations\n            lines.push_back(line_through_points(x - 80 + (i%3), y - 80 + (i%4), x + 80 + (i%2), y - 80 + (i%3)));\n            used_lines++;\n            if (used_lines >= K) break;\n            \n            lines.push_back(line_through_points(x - 80 + (i%4), y + 80 + (i%2), x + 80 + (i%3), y + 80 + (i%4)));\n            used_lines++;\n            if (used_lines >= K) break;\n        }\n    }\n    \n    // 5. Fill remaining with diverse lines\n    while (used_lines < K) {\n        // Mix of different line types\n        int strategy = used_lines % 4;\n        \n        switch (strategy) {\n            case 0: {\n                // Random radial\n                double angle = 2.0 * M_PI * used_lines / K;\n                ll px = (ll)(centroid_x + 100000 * cos(angle));\n                ll py = (ll)(centroid_y + 100000 * sin(angle));\n                ll qx = (ll)(centroid_x - 100000 * cos(angle));\n                ll qy = (ll)(centroid_y - 100000 * sin(angle));\n                lines.push_back({px, py, qx, qy});\n                break;\n            }\n            case 1: {\n                // Random grid-like\n                int pos = (rand() % (2 * RADIUS)) - RADIUS + (int)centroid_x;\n                lines.push_back(line_through_points(pos, -BOUND, pos, BOUND));\n                break;\n            }\n            case 2: {\n                // Random grid-like horizontal\n                int pos = (rand() % (2 * RADIUS)) - RADIUS + (int)centroid_y;\n                lines.push_back(line_through_points(-BOUND, pos, BOUND, pos));\n                break;\n            }\n            case 3: {\n                // Random line\n                ll px = rand() % (2 * BOUND) - BOUND;\n                ll py = rand() % (2 * BOUND) - BOUND;\n                ll qx = rand() % (2 * BOUND) - BOUND;\n                ll qy = rand() % (2 * BOUND) - BOUND;\n                if (px == qx && py == qy) qx += (rand() % 7) - 3;\n                if (px == qx && py == qy) qy += (rand() % 5) - 2;\n                lines.push_back({px, py, qx, qy});\n                break;\n            }\n        }\n        used_lines++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Better random seed\n    srand(time(nullptr) ^ (intptr_t)&cout ^ chrono::duration_cast<chrono::nanoseconds>(\n        chrono::high_resolution_clock::now().time_since_epoch()).count());\n    \n    cin >> N >> K;\n    \n    int total_demand = 0;\n    for (int d = 1; d <= 10; d++) {\n        cin >> a[d];\n        total_demand += a[d];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n    }\n    \n    // Use the adaptive strategy\n    vector<tuple<ll, ll, ll, ll>> lines;\n    adaptive_strategy(lines);\n    \n    // Ensure we don't exceed K lines\n    if (lines.size() > K) {\n        lines.resize(K);\n    }\n    \n    // Output result\n    cout << lines.size() << \"\\n\";\n    for (const auto& line : lines) {\n        auto [px, py, qx, qy] = line;\n        cout << px << \" \" << py << \" \" << qx << \" \" << qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int MAX_N = 65;\nbool grid[MAX_N][MAX_N];\nint N, M;\nvector<pair<int, int>> initial_dots;\nvector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n// Store edges of drawn rectangles to prevent overlaps\nset<pair<pair<int, int>, pair<int, int>>> drawn_edges;\n\nauto start_time = high_resolution_clock::now();\nconst double TIME_LIMIT = 4.5;\n\n// Weight calculation\ninline long long weight(int x, int y) {\n    int c = (N - 1) / 2;\n    int dx = x - c;\n    int dy = y - c;\n    return (long long)dx * dx + (long long)dy * dy + 1;\n}\n\nbool time_limit_exceeded() {\n    auto now = high_resolution_clock::now();\n    auto duration = duration_cast<milliseconds>(now - start_time);\n    return duration.count() > TIME_LIMIT * 1000;\n}\n\n// Generate all points on a line segment\nvector<pair<int, int>> get_line_points(int x1, int y1, int x2, int y2) {\n    vector<pair<int, int>> points;\n    \n    if (x1 == x2 && y1 == y2) {\n        points.push_back({x1, y1});\n        return points;\n    }\n    \n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int steps = max(abs(dx), abs(dy));\n    \n    for (int i = 0; i <= steps; i++) {\n        int x = x1 + (dx * i) / steps;\n        int y = y1 + (dy * i) / steps;\n        points.push_back({x, y});\n    }\n    return points;\n}\n\n// Normalize edge to have consistent representation\npair<pair<int, int>, pair<int, int>> normalize_edge(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        return {{x2, y2}, {x1, y1}};\n    }\n    return {{x1, y1}, {x2, y2}};\n}\n\n// Get all edges of a rectangle\nvector<pair<pair<int, int>, pair<int, int>>> get_rectangle_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    vector<pair<pair<int, int>, pair<int, int>>> edges;\n    edges.push_back(normalize_edge(x1, y1, x2, y2));\n    edges.push_back(normalize_edge(x2, y2, x3, y3));\n    edges.push_back(normalize_edge(x3, y3, x4, y4));\n    edges.push_back(normalize_edge(x4, y4, x1, y1));\n    return edges;\n}\n\n// Check if rectangle edges overlap with existing edges\nbool has_edge_overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto edges = get_rectangle_edges(x1, y1, x2, y2, x3, y3, x4, y4);\n    for (const auto& edge : edges) {\n        if (drawn_edges.count(edge)) return true;\n    }\n    return false;\n}\n\n// Add edges of a rectangle to the drawn set\nvoid add_rectangle_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto edges = get_rectangle_edges(x1, y1, x2, y2, x3, y3, x4, y4);\n    for (const auto& edge : edges) {\n        drawn_edges.insert(edge);\n    }\n}\n\n// Check if four points form a valid rectangle (axis-parallel or 45-degree)\nbool is_valid_rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check if diagonals bisect each other (parallelogram property)\n    if (x1 + x3 != x2 + x4 || y1 + y3 != y2 + y4) {\n        return false;\n    }\n    \n    // Check if all sides are valid directions (axis-parallel or 45-degree)\n    vector<pair<int, int>> points = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    for (int i = 0; i < 4; i++) {\n        int j = (i + 1) % 4;\n        int dx = points[j].first - points[i].first;\n        int dy = points[j].second - points[i].second;\n        \n        // Valid moves: horizontal, vertical, or diagonal (|dx| = |dy|)\n        if (dx == 0 && dy == 0) return false; // Same point\n        if (!(dx == 0 || dy == 0 || abs(dx) == abs(dy))) {\n            return false;\n        }\n    }\n    \n    // Check that it's actually a rectangle by verifying diagonals are equal\n    long long diag1_sq = (long long)(x3 - x1) * (x3 - x1) + (long long)(y3 - y1) * (y3 - y1);\n    long long diag2_sq = (long long)(x4 - x2) * (x4 - x2) + (long long)(y4 - y2) * (y4 - y2);\n    \n    if (diag1_sq != diag2_sq) return false;\n    \n    return true;\n}\n\n// Check if there are no dots on the perimeter except the 4 vertices\nbool no_dots_on_perimeter(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    set<pair<int, int>> vertices = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    // Check each side\n    auto side1 = get_line_points(x1, y1, x2, y2);\n    auto side2 = get_line_points(x2, y2, x3, y3);\n    auto side3 = get_line_points(x3, y3, x4, y4);\n    auto side4 = get_line_points(x4, y4, x1, y1);\n    \n    for (const auto& p : side1) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side2) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side3) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side4) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    \n    return true;\n}\n\nvoid solve() {\n    // Initialize with initial dots\n    vector<pair<int, int>> dots;\n    for (int i = 0; i < M; i++) {\n        dots.push_back(initial_dots[i]);\n        grid[initial_dots[i].first][initial_dots[i].second] = true;\n    }\n    \n    // Greedy approach: prioritize high-weight positions\n    while (!time_limit_exceeded()) {\n        bool found = false;\n        \n        // Create candidate positions sorted by weight\n        vector<tuple<long long, int, int>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    candidates.push_back({weight(x, y), x, y});\n                }\n            }\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Limit candidates to avoid timeout\n        int limit = min(50, (int)candidates.size());\n        \n        for (int cand_idx = 0; cand_idx < limit && !found; cand_idx++) {\n            if (time_limit_exceeded()) break;\n            \n            int x1 = get<1>(candidates[cand_idx]);\n            int y1 = get<2>(candidates[cand_idx]);\n            \n            // Try combinations of existing dots\n            int sz = dots.size();\n            for (int i = 0; i < sz && !found; i++) {\n                for (int j = i + 1; j < sz && !found; j++) {\n                    for (int k = j + 1; k < sz && !found; k++) {\n                        if (time_limit_exceeded()) return;\n                        \n                        int x2 = dots[i].first, y2 = dots[i].second;\n                        int x3 = dots[j].first, y3 = dots[j].second;\n                        int x4 = dots[k].first, y4 = dots[k].second;\n                        \n                        // Try all permutations\n                        vector<vector<int>> perms = {\n                            {x2, y2, x3, y3, x4, y4},\n                            {x2, y2, x4, y4, x3, y3},\n                            {x3, y3, x2, y2, x4, y4},\n                            {x3, y3, x4, y4, x2, y2},\n                            {x4, y4, x2, y2, x3, y3},\n                            {x4, y4, x3, y3, x2, y2}\n                        };\n                        \n                        for (const auto& perm : perms) {\n                            if (is_valid_rectangle(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                if (no_dots_on_perimeter(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                    if (!has_edge_overlap(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                        // Valid operation\n                                        operations.push_back(make_tuple(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]));\n                                        grid[x1][y1] = true;\n                                        dots.push_back({x1, y1});\n                                        add_rectangle_edges(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]);\n                                        found = true;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!found) break;\n    }\n}\n\nint main() {\n    start_time = high_resolution_clock::now();\n    \n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    initial_dots.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> initial_dots[i].first >> initial_dots[i].second;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" \n             << get<2>(op) << \" \" << get<3>(op) << \" \"\n             << get<4>(op) << \" \" << get<5>(op) << \" \"\n             << get<6>(op) << \" \" << get<7>(op) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 10;\nconst int TOTAL_CANDIES = 100;\n\n// Directions: F(forward/up), B(backward/down), L(left), R(right)\nconst vector<pair<int, int>> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"FBLR\";\n\nclass CandyBox {\nprivate:\n    vector<vector<int>> grid; // 0 = empty, 1,2,3 = flavors\n\npublic:\n    CandyBox() : grid(GRID_SIZE, vector<int>(GRID_SIZE, 0)) {}\n\n    void place_candy(int pos, int flavor) {\n        int empty_count = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] == 0) {\n                    empty_count++;\n                    if (empty_count == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulate tilting in given direction\n    void tilt(int dir_idx) {\n        auto [di, dj] = DIRS[dir_idx];\n        \n        if (dir_idx == 0) { // Forward (up) - process top to bottom\n            for (int i = 0; i < GRID_SIZE; i++) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 1) { // Backward (down) - process bottom to top\n            for (int i = GRID_SIZE - 1; i >= 0; i--) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 2) { // Left - process left to right\n            for (int j = 0; j < GRID_SIZE; j++) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else { // Right - process right to left\n            for (int j = GRID_SIZE - 1; j >= 0; j--) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        }\n    }\n\nprivate:\n    void move_candy(int i, int j, int di, int dj) {\n        int flavor = grid[i][j];\n        grid[i][j] = 0;\n        \n        int ni = i + di, nj = j + dj;\n        while (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == 0) {\n            i = ni;\n            j = nj;\n            ni += di;\n            nj += dj;\n        }\n        \n        grid[i][j] = flavor;\n    }\n\npublic:\n    // Simple but effective evaluation: sum of squares of component sizes\n    long long evaluate_clustering() {\n        vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n        long long total_score = 0;\n        \n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int component_size = dfs_component(i, j, grid[i][j], visited);\n                    total_score += (long long)component_size * component_size;\n                }\n            }\n        }\n        \n        return total_score;\n    }\n\nprivate:\n    int dfs_component(int i, int j, int flavor, vector<vector<bool>>& visited) {\n        if (i < 0 || i >= GRID_SIZE || j < 0 || j >= GRID_SIZE || \n            visited[i][j] || grid[i][j] != flavor) {\n            return 0;\n        }\n        \n        visited[i][j] = true;\n        int size = 1;\n        \n        // Check 4 adjacent cells\n        for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n            size += dfs_component(i + di, j + dj, flavor, visited);\n        }\n        \n        return size;\n    }\n\npublic:\n    CandyBox copy() const {\n        CandyBox new_box;\n        new_box.grid = grid;\n        return new_box;\n    }\n    \n    // Count how many candies would connect with their neighbors after tilting\n    int count_connections() {\n        int connections = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0) {\n                    int flavor = grid[i][j];\n                    // Check adjacent cells\n                    for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n                        int ni = i + di, nj = j + dj;\n                        if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == flavor) {\n                            connections++;\n                        }\n                    }\n                }\n            }\n        }\n        return connections / 2; // Each connection counted twice\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<int> flavors(TOTAL_CANDIES);\n    for (int i = 0; i < TOTAL_CANDIES; i++) {\n        cin >> flavors[i];\n    }\n    \n    CandyBox box;\n    \n    for (int t = 0; t < TOTAL_CANDIES; t++) {\n        int pos;\n        cin >> pos;\n        \n        // Place the candy\n        box.place_candy(pos, flavors[t]);\n        \n        if (t == TOTAL_CANDIES - 1) {\n            // No need to output direction for last candy\n            break;\n        }\n        \n        // Evaluate each possible tilt direction\n        int best_direction = 0;\n        long long best_score = -1;\n        \n        // Try all directions and pick the best one\n        for (int dir = 0; dir < 4; dir++) {\n            CandyBox temp_box = box.copy();\n            temp_box.tilt(dir);\n            long long score = temp_box.evaluate_clustering();\n            \n            // Small bonus for creating more connections\n            score += temp_box.count_connections();\n            \n            if (score > best_score) {\n                best_score = score;\n                best_direction = dir;\n            }\n        }\n        \n        cout << DIR_CHARS[best_direction] << endl;\n        cout.flush();\n        \n        // Actually perform the tilt\n        box.tilt(best_direction);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n\nusing namespace std;\n\n// Fast I/O optimization\nstatic auto fast_io = []() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n    return 0;\n}();\n\n// Convert adjacency matrix to string representation\nstring graphToString(const vector<vector<int>>& adj, int n) {\n    string result;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            result += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return result;\n}\n\n// Convert string to adjacency matrix\nvector<vector<int>> stringToGraph(const string& s, int n) {\n    vector<vector<int>> adj(n, vector<int>(n, 0));\n    int idx = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[idx] == '1') {\n                adj[i][j] = adj[j][i] = 1;\n            }\n            idx++;\n        }\n    }\n    return adj;\n}\n\n// Count edges\nint countEdges(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            count += adj[i][j];\n        }\n    }\n    return count;\n}\n\n// Generate graphs with more controlled edge distribution\nvector<string> generateGraphs(int M, int N) {\n    vector<string> graphs;\n    \n    for (int k = 0; k < M; ++k) {\n        vector<vector<int>> adj(N, vector<int>(N, 0));\n        \n        // Calculate target edge count with better distribution\n        double ratio = (double)k / (M - 1);  // 0.0 to 1.0\n        int max_edges = N * (N - 1) / 2;\n        int target_edges = (int)(ratio * max_edges);\n        \n        // Ensure at least 0 and at most max_edges\n        target_edges = max(0, min(max_edges, target_edges));\n        \n        // Add edges systematically to achieve target\n        int added = 0;\n        // Fill in a systematic pattern\n        for (int i = 0; i < N && added < target_edges; ++i) {\n            for (int j = i + 1; j < N && added < target_edges; ++j) {\n                // Use a deterministic pattern based on k\n                if (((i + j + k) * 17 + i * j * 3) % 37 < 20) {\n                    adj[i][j] = adj[j][i] = 1;\n                    added++;\n                }\n            }\n        }\n        \n        // If we haven't added enough edges, add them sequentially\n        if (added < target_edges) {\n            for (int i = 0; i < N && added < target_edges; ++i) {\n                for (int j = i + 1; j < N && added < target_edges; ++j) {\n                    if (!adj[i][j]) {\n                        adj[i][j] = adj[j][i] = 1;\n                        added++;\n                    }\n                }\n            }\n        }\n        \n        // If we have too many edges, remove some\n        while (added > target_edges) {\n            for (int i = 0; i < N && added > target_edges; ++i) {\n                for (int j = i + 1; j < N && added > target_edges; ++j) {\n                    if (adj[i][j]) {\n                        adj[i][j] = adj[j][i] = 0;\n                        added--;\n                        break;\n                    }\n                }\n                if (added <= target_edges) break;\n            }\n        }\n        \n        graphs.push_back(graphToString(adj, N));\n    }\n    \n    return graphs;\n}\n\n// Enhanced prediction with multiple strategies\nint predictGraph(const vector<vector<int>>& noisy_adj, int N, int M, double epsilon, \n                 const vector<int>& template_edge_counts) {\n    int edge_count = countEdges(noisy_adj, N);\n    \n    // Primary strategy: nearest edge count\n    int best_match = 0;\n    int min_diff = abs(edge_count - template_edge_counts[0]);\n    \n    for (int i = 1; i < M; ++i) {\n        int diff = abs(edge_count - template_edge_counts[i]);\n        if (diff < min_diff) {\n            min_diff = diff;\n            best_match = i;\n        }\n    }\n    \n    return best_match;\n}\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n    \n    // Improved N selection based on empirical testing\n    int N;\n    if (epsilon > 0.3) {\n        // Very high noise: small graphs\n        N = max(6, min(12, 6 + M/8));\n    } else if (epsilon > 0.2) {\n        // High noise: medium-small graphs\n        N = max(8, min(18, 8 + M/6));\n    } else if (epsilon > 0.1) {\n        // Medium noise: medium graphs\n        N = max(10, min(25, 10 + M/4));\n    } else if (epsilon > 0.05) {\n        // Low-medium noise: larger graphs\n        N = max(12, min(35, 12 + M/3));\n    } else {\n        // Low noise: large graphs for better discrimination\n        N = max(15, min(50, 15 + M/2));\n    }\n    \n    // Ensure bounds\n    N = min(N, 100);\n    N = max(N, 4);\n    \n    // Generate template graphs\n    auto graphs = generateGraphs(M, N);\n    \n    // Precompute template edge counts\n    vector<int> template_edge_counts(M);\n    for (int i = 0; i < M; ++i) {\n        auto adj = stringToGraph(graphs[i], N);\n        template_edge_counts[i] = countEdges(adj, N);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        auto noisy_adj = stringToGraph(h_str, N);\n        \n        // Predict which graph it came from\n        int prediction = predictGraph(noisy_adj, N, M, epsilon, template_edge_counts);\n        \n        cout << prediction << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<vector<pair<int, int>>> adj;\n\n// Simple but effective edge scoring\nvector<pair<double, int>> scoreEdges() {\n    vector<pair<double, int>> scores(M);\n    \n    for (int i = 0; i < M; i++) {\n        const auto& e = edges[i];\n        \n        // Consider multiple factors:\n        // 1. Edge weight (heavier edges less critical)\n        // 2. Vertex degrees (higher degree vertices mean more alternatives)\n        // 3. Graph density around the edge\n        \n        int deg_u = adj[e.u].size();\n        int deg_v = adj[e.v].size();\n        \n        // Calculate neighborhood overlap as a measure of redundancy\n        int common_neighbors = 0;\n        vector<bool> neighbor_u(N, false);\n        for (auto& p : adj[e.u]) {\n            neighbor_u[p.first] = true;\n        }\n        for (auto& p : adj[e.v]) {\n            if (neighbor_u[p.first] && p.first != e.u && p.first != e.v) {\n                common_neighbors++;\n            }\n        }\n        \n        // Score: higher score = repair later (more critical)\n        // Lower weight, lower degrees, fewer common neighbors = more critical\n        double score = (1.0 / e.w) * sqrt(deg_u * deg_v) / (1.0 + common_neighbors);\n        \n        scores[i] = {score, i};\n    }\n    \n    return scores;\n}\n\n// Assign days using the scored edges\nvector<int> assignDays() {\n    vector<int> result(M);\n    \n    // Get edge scores\n    auto scores = scoreEdges();\n    \n    // Sort by score (ascending - lower scores repaired first)\n    sort(scores.begin(), scores.end());\n    \n    // Distribute edges across days\n    vector<vector<int>> day_edges(D);\n    \n    // First pass: try to distribute evenly\n    for (int i = 0; i < M; i++) {\n        int edge_id = scores[i].second;\n        \n        // Find the best day to place this edge\n        int best_day = 0;\n        int min_edges = K + 1;\n        \n        // Prefer days with fewer edges but still under limit\n        for (int day = 0; day < D; day++) {\n            if (day_edges[day].size() < K && day_edges[day].size() < min_edges) {\n                min_edges = day_edges[day].size();\n                best_day = day;\n            }\n        }\n        \n        // If all days are full, put in day with minimum edges\n        if (min_edges == K + 1) {\n            min_edges = M + 1;\n            for (int day = 0; day < D; day++) {\n                if (day_edges[day].size() < min_edges) {\n                    min_edges = day_edges[day].size();\n                    best_day = day;\n                }\n            }\n        }\n        \n        day_edges[best_day].push_back(edge_id);\n        result[edge_id] = best_day + 1;\n    }\n    \n    return result;\n}\n\n// Alternative simple approach based on edge weights only\nvector<int> simpleWeightBasedAssignment() {\n    vector<int> result(M);\n    \n    // Sort edges by weight (heavier first - less critical)\n    vector<pair<int, int>> weights(M);\n    for (int i = 0; i < M; i++) {\n        weights[i] = {edges[i].w, i};\n    }\n    sort(weights.begin(), weights.end(), greater<pair<int, int>>());\n    \n    // Assign to days\n    for (int i = 0; i < M; i++) {\n        int edge_id = weights[i].second;\n        int day = min(i / K, D - 1);\n        result[edge_id] = day + 1;\n    }\n    \n    // Fix constraint violations\n    vector<vector<int>> day_edges(D);\n    for (int i = 0; i < M; i++) {\n        day_edges[result[i] - 1].push_back(i);\n    }\n    \n    // Redistribute if any day has too many edges\n    for (int day = 0; day < D; day++) {\n        while (day_edges[day].size() > K) {\n            int edge_id = day_edges[day].back();\n            day_edges[day].pop_back();\n            \n            // Find day with space\n            bool placed = false;\n            for (int target_day = 0; target_day < D; target_day++) {\n                if (target_day != day && day_edges[target_day].size() < K) {\n                    day_edges[target_day].push_back(edge_id);\n                    result[edge_id] = target_day + 1;\n                    placed = true;\n                    break;\n                }\n            }\n            \n            // If no space, put in last day\n            if (!placed) {\n                if (day != D - 1 && day_edges[D - 1].size() < K) {\n                    day_edges[D - 1].push_back(edge_id);\n                    result[edge_id] = D;\n                }\n                // If still no space, we have to exceed limit (shouldn't happen with valid input)\n            }\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 >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--; // Convert to 0-indexed\n        edges[i] = {u, v, w, i};\n    }\n    \n    // Skip coordinate input\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Build adjacency list\n    adj.assign(N, vector<pair<int, int>>());\n    for (const auto& e : edges) {\n        adj[e.u].push_back({e.v, e.w});\n        adj[e.v].push_back({e.u, e.w});\n    }\n    \n    // Choose assignment strategy\n    vector<int> result;\n    \n    // Use the more sophisticated approach for smaller problems, simple for larger\n    if (M <= 2000 && D <= 20) {\n        result = assignDays();\n    } else {\n        result = simpleWeightBasedAssignment();\n    }\n    \n    // Output result\n    for (int i = 0; i < M; i++) {\n        cout << result[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_D = 14;\nint D;\nchar f[2][MAX_D][MAX_D];\nchar r[2][MAX_D][MAX_D];\n\n// 3D grid for each construction\nint b[2][MAX_D][MAX_D][MAX_D];\n\n// Directions for 6-connectivity\nconst int dx[6] = {1, -1, 0, 0, 0, 0};\nconst int dy[6] = {0, 0, 1, -1, 0, 0};\nconst int dz[6] = {0, 0, 0, 0, 1, -1};\n\nbool isValid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n\n// Simple BFS to find connected component\nvector<tuple<int,int,int>> findComponent(int grid[MAX_D][MAX_D][MAX_D], \n                                        vector<vector<vector<bool>>>& visited,\n                                        int start_x, int start_y, int start_z) {\n    vector<tuple<int,int,int>> component;\n    \n    if (!isValid(start_x, start_y, start_z) || \n        grid[start_x][start_y][start_z] == 0 || \n        visited[start_x][start_y][start_z]) {\n        return component;\n    }\n    \n    queue<tuple<int,int,int>> q;\n    q.push({start_x, start_y, start_z});\n    visited[start_x][start_y][start_z] = true;\n    component.push_back({start_x, start_y, start_z});\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front(); q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            \n            if (isValid(nx, ny, nz) && \n                !visited[nx][ny][nz] && \n                grid[nx][ny][nz] == 1) {\n                visited[nx][ny][nz] = true;\n                q.push({nx, ny, nz});\n                component.push_back({nx, ny, nz});\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read input\n    for (int i = 0; i < 2; i++) {\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int x = 0; x < D; x++) {\n                f[i][z][x] = line[x];\n            }\n        }\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int y = 0; y < D; y++) {\n                r[i][z][y] = line[y];\n            }\n        }\n    }\n    \n    // Initialize grids - place unit cubes where both silhouettes allow\n    int valid_cubes[2][MAX_D][MAX_D][MAX_D] = {0};\n    \n    for (int constr = 0; constr < 2; constr++) {\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[constr][z][x] == '1' && r[constr][z][y] == '1') {\n                        valid_cubes[constr][x][y][z] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Reset output grid\n    memset(b, 0, sizeof(b));\n    \n    // For each construction, find connected components and assign block IDs\n    int block_id_counter = 1;\n    \n    for (int constr = 0; constr < 2; constr++) {\n        vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (valid_cubes[constr][x][y][z] == 1 && !visited[x][y][z]) {\n                        // Found a new component\n                        auto component = findComponent(valid_cubes[constr], visited, x, y, z);\n                        \n                        if (!component.empty()) {\n                            // Assign a new block ID to this entire component\n                            int current_block_id = block_id_counter++;\n                            \n                            for (const auto& cube : component) {\n                                int cx = get<0>(cube);\n                                int cy = get<1>(cube);\n                                int cz = get<2>(cube);\n                                b[constr][cx][cy][cz] = current_block_id;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output result\n    cout << (block_id_counter - 1) << \"\\n\";\n    \n    for (int constr = 0; constr < 2; constr++) {\n        bool first = true;\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (!first) cout << \" \";\n                    cout << b[constr][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\nusing ld = long double;\nusing pii = pair<int, int>;\nusing pll = pair<ll, ll>;\n\nconst int MAX_N = 100;\nconst int MAX_M = 300;\nconst int MAX_K = 5000;\nconst int MAX_POWER = 5000;\n\nint N, M, K;\nvector<pair<int, int>> vertices;\nvector<tuple<int, int, int>> edges;\nvector<pair<int, int>> residents;\n\n// Distance calculation\nint euclidean_distance(int i, int j) {\n    int dx = vertices[i].first - vertices[j].first;\n    int dy = vertices[i].second - vertices[j].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\nint resident_to_vertex_distance(int res_idx, int vert_idx) {\n    int dx = residents[res_idx].first - vertices[vert_idx].first;\n    int dy = residents[res_idx].second - vertices[vert_idx].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\n// Find minimum spanning tree using Prim's algorithm\nvector<bool> find_mst_edges() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vertex_reached[0] = true; // Start from vertex 1 (index 0)\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    \n    // Add all edges from vertex 1\n    for (int j = 0; j < M; j++) {\n        auto [u, v, w] = edges[j];\n        u--; v--; // Convert to 0-indexed\n        if (u == 0) {\n            pq.push({w, v, j});\n        } else if (v == 0) {\n            pq.push({w, u, j});\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [weight, to, edge_idx] = pq.top();\n        pq.pop();\n        \n        if (vertex_reached[to]) continue;\n        \n        vertex_reached[to] = true;\n        edge_used[edge_idx] = true;\n        \n        // Add edges from newly reached vertex\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            if (u == to && !vertex_reached[v]) {\n                pq.push({w, v, j});\n            } else if (v == to && !vertex_reached[u]) {\n                pq.push({w, u, j});\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\n// Calculate minimum power needed for each vertex to cover residents\nvector<int> calculate_min_power(const vector<bool>& vertex_active) {\n    vector<int> power(N, 0);\n    vector<bool> covered(K, false);\n    \n    // First pass: calculate required power for each active vertex\n    for (int i = 0; i < N; i++) {\n        if (!vertex_active[i]) continue;\n        \n        int max_dist = 0;\n        for (int k = 0; k < K; k++) {\n            int dist = resident_to_vertex_distance(k, i);\n            if (dist <= MAX_POWER) {\n                max_dist = max(max_dist, dist);\n            }\n        }\n        power[i] = max_dist;\n    }\n    \n    // Greedy approach: iteratively improve coverage\n    for (int iter = 0; iter < 3; iter++) {\n        fill(covered.begin(), covered.end(), false);\n        \n        // Mark covered residents\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i] || power[i] == 0) continue;\n            for (int k = 0; k < K; k++) {\n                if (resident_to_vertex_distance(k, i) <= power[i]) {\n                    covered[k] = true;\n                }\n            }\n        }\n        \n        // Find uncovered residents\n        vector<int> uncovered;\n        for (int k = 0; k < K; k++) {\n            if (!covered[k]) uncovered.push_back(k);\n        }\n        \n        if (uncovered.empty()) break;\n        \n        // For each active vertex, see how much additional power helps\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i]) continue;\n            \n            int max_needed = 0;\n            for (int k : uncovered) {\n                int dist = resident_to_vertex_distance(k, i);\n                if (dist <= MAX_POWER) {\n                    max_needed = max(max_needed, dist);\n                }\n            }\n            power[i] = max(power[i], max_needed);\n        }\n    }\n    \n    return power;\n}\n\n// Improved approach: use a more sophisticated method\nvector<bool> improved_edge_selection() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vector<bool> resident_covered(K, false);\n    vertex_reached[0] = true;\n    \n    // Precompute resident distances to all vertices\n    vector<vector<int>> resident_distances(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resident_distances[k][i] = resident_to_vertex_distance(k, i);\n        }\n    }\n    \n    // Greedily select edges that maximize coverage efficiency\n    for (int step = 0; step < N - 1; step++) {\n        int best_edge = -1;\n        double best_efficiency = -1e18;\n        \n        // Find the best edge to add\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            \n            // Check if this edge connects a reached and unreached vertex\n            bool connects = (vertex_reached[u] && !vertex_reached[v]) || \n                           (vertex_reached[v] && !vertex_reached[u]);\n            \n            if (!connects) continue;\n            \n            int new_vertex = vertex_reached[u] ? v : u;\n            \n            // Calculate how many new residents this would cover\n            int new_coverage = 0;\n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k] && resident_distances[k][new_vertex] <= MAX_POWER) {\n                    new_coverage++;\n                }\n            }\n            \n            // Efficiency = coverage per cost\n            double efficiency = (double)new_coverage / max(w, 1);\n            \n            if (efficiency > best_efficiency) {\n                best_efficiency = efficiency;\n                best_edge = j;\n            }\n        }\n        \n        if (best_edge == -1) break;\n        \n        edge_used[best_edge] = true;\n        auto [u, v, w] = edges[best_edge];\n        u--; v--;\n        int new_vertex = vertex_reached[u] ? v : u;\n        vertex_reached[new_vertex] = true;\n        \n        // Update covered residents\n        for (int k = 0; k < K; k++) {\n            if (resident_distances[k][new_vertex] <= MAX_POWER) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    \n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    edges.resize(M);\n    for (int j = 0; j < M; j++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n    }\n    \n    residents.resize(K);\n    for (int k = 0; k < K; k++) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n    \n    // Select edges using improved approach\n    vector<bool> edge_used = improved_edge_selection();\n    \n    // Determine which vertices are active\n    vector<bool> vertex_active(N, false);\n    vertex_active[0] = true; // Always include vertex 1\n    \n    // BFS to find all reachable vertices\n    queue<int> q;\n    q.push(0);\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int j = 0; j < M; j++) {\n            if (!edge_used[j]) continue;\n            \n            auto [v1, v2, w] = edges[j];\n            v1--; v2--; // Convert to 0-indexed\n            \n            if (v1 == u && !vertex_active[v2]) {\n                vertex_active[v2] = true;\n                q.push(v2);\n            } else if (v2 == u && !vertex_active[v1]) {\n                vertex_active[v1] = true;\n                q.push(v1);\n            }\n        }\n    }\n    \n    // Calculate power requirements\n    vector<int> power = calculate_min_power(vertex_active);\n    \n    // Output results\n    for (int i = 0; i < N; i++) {\n        cout << power[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    for (int j = 0; j < M; j++) {\n        cout << (edge_used[j] ? 1 : 0);\n        if (j < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 10000;\nconst int TOTAL_BALLS = N * (N + 1) / 2;\n\nstruct Position {\n    int x, y;\n    Position() : x(0), y(0) {}\n    Position(int _x, int _y) : x(_x), y(_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\n// Directions for adjacency (6 directions in triangular grid)\nconst vector<pair<int, int>> DIRECTIONS = {\n    {-1, -1}, {-1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1}\n};\n\nclass Pyramid {\npublic:\n    int grid[N][N];\n    vector<pair<Position, Position>> operations;\n    \n    Pyramid() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                cin >> grid[i][j];\n            }\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y <= x;\n    }\n    \n    bool is_adjacent(int x1, int y1, int x2, int y2) {\n        for (auto& dir : DIRECTIONS) {\n            int nx = x1 + dir.first;\n            int ny = y1 + dir.second;\n            if (nx == x2 && ny == y2) return true;\n        }\n        return false;\n    }\n    \n    vector<Position> get_neighbors(int x, int y) {\n        vector<Position> neighbors;\n        for (auto& dir : DIRECTIONS) {\n            int nx = x + dir.first;\n            int ny = y + dir.second;\n            if (is_valid(nx, ny)) {\n                neighbors.emplace_back(nx, ny);\n            }\n        }\n        return neighbors;\n    }\n    \n    int count_violations() {\n        int count = 0;\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] > grid[i+1][j]) count++;\n                if (grid[i][j] > grid[i+1][j+1]) count++;\n            }\n        }\n        return count;\n    }\n    \n    void swap_balls(int x1, int y1, int x2, int y2) {\n        if (!is_adjacent(x1, y1, x2, y2)) return;\n        if (operations.size() >= MAX_OPS) return;\n        \n        swap(grid[x1][y1], grid[x2][y2]);\n        operations.emplace_back(Position(x1, y1), Position(x2, y2));\n    }\n    \n    // Find position of a specific value\n    Position find_position(int value) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] == value) {\n                    return Position(i, j);\n                }\n            }\n        }\n        return Position(-1, -1);\n    }\n    \n    void output() {\n        cout << operations.size() << \"\\n\";\n        for (auto& op : operations) {\n            cout << op.first.x << \" \" << op.first.y << \" \" \n                 << op.second.x << \" \" << op.second.y << \"\\n\";\n        }\n    }\n    \n    // Bubble sort approach: move larger elements down\n    void bubble_sort_approach() {\n        // Multiple passes of bubble sort-like approach\n        for (int pass = 0; pass < 20 && operations.size() < MAX_OPS - 10; pass++) {\n            bool changed = false;\n            \n            // Go through each level from top to bottom-1\n            for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 2; level++) {\n                // Go through each position in the level\n                for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 2; pos++) {\n                    int current = grid[level][pos];\n                    int left_child = grid[level+1][pos];\n                    int right_child = grid[level+1][pos+1];\n                    \n                    // If current is larger than either child, swap with the smaller child\n                    if (current > left_child || current > right_child) {\n                        if (left_child <= right_child) {\n                            swap_balls(level, pos, level+1, pos);\n                        } else {\n                            swap_balls(level, pos, level+1, pos+1);\n                        }\n                        changed = true;\n                    }\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n    \n    // Improved approach: work systematically level by level\n    void systematic_approach() {\n        // For each position, try to get the minimum valid value there\n        for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 5; level++) {\n            for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 5; pos++) {\n                // Ensure this position has value <= both children\n                int& current = grid[level][pos];\n                int& left_child = grid[level+1][pos];\n                int& right_child = grid[level+1][pos+1];\n                \n                // Keep swapping down while violation exists\n                while ((current > left_child || current > right_child) && operations.size() < MAX_OPS - 1) {\n                    if (current > left_child && (current > right_child ? left_child <= right_child : true)) {\n                        swap_balls(level, pos, level+1, pos);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else if (current > right_child) {\n                        swap_balls(level, pos, level+1, pos+1);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Local optimization: fix immediate violations\n    void local_optimization() {\n        bool improved = true;\n        int iterations = 0;\n        const int MAX_ITERATIONS = 50;\n        \n        while (improved && iterations < MAX_ITERATIONS && operations.size() < MAX_OPS - 10) {\n            improved = false;\n            iterations++;\n            \n            // Scan through all positions and fix violations\n            for (int i = 0; i < N - 1 && operations.size() < MAX_OPS - 2; i++) {\n                for (int j = 0; j <= i && operations.size() < MAX_OPS - 2; j++) {\n                    int current = grid[i][j];\n                    int left_child = grid[i+1][j];\n                    int right_child = grid[i+1][j+1];\n                    \n                    // Fix violations\n                    if (current > left_child || current > right_child) {\n                        // Swap with smaller child\n                        if (left_child <= right_child) {\n                            swap_balls(i, j, i+1, j);\n                        } else {\n                            swap_balls(i, j, i+1, j+1);\n                        }\n                        improved = true;\n                        if (operations.size() >= MAX_OPS - 2) break;\n                    }\n                }\n                if (operations.size() >= MAX_OPS - 2) break;\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    Pyramid pyramid;\n    pyramid.read_input();\n    \n    // Try multiple strategies\n    pyramid.systematic_approach();\n    pyramid.local_optimization();\n    pyramid.bubble_sort_approach();\n    pyramid.local_optimization();\n    \n    pyramid.output();\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int D = 9;\nconst int ENTRANCE_ROW = 0;\nconst int ENTRANCE_COL = 4;\n\nint N;\nbool is_obstacle[D][D];\nbool has_container[D][D];\nint container_number[D][D];\nvector<pair<int, int>> obstacles;\n\n// Directions: up, down, left, right\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\n\n// Check if coordinates are valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\n// Check if a cell is the entrance\nbool is_entrance(int x, int y) {\n    return x == ENTRANCE_ROW && y == ENTRANCE_COL;\n}\n\n// BFS to find all reachable empty cells from entrance\nvector<vector<bool>> get_reachable() {\n    vector<vector<bool>> reachable(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    reachable[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !has_container[nx][ny] && !reachable[nx][ny]) {\n                reachable[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\n// BFS to find all reachable cells with containers from entrance\nvector<pair<int, int>> get_reachable_containers() {\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    vector<pair<int, int>> result;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    visited[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        // If this cell has a container, add it to result\n        if (has_container[x][y]) {\n            result.push_back({x, y});\n        }\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Calculate Manhattan distance from entrance\nint manhattan_distance(int x, int y) {\n    return abs(x - ENTRANCE_ROW) + abs(y - ENTRANCE_COL);\n}\n\n// Find best position to place a container\npair<int, int> find_best_position(int container_num, int total_containers) {\n    auto reachable = get_reachable();\n    \n    pair<int, int> best_pos = {-1, -1};\n    double best_score = -1e18;\n    \n    // Try all positions\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            // Skip if it's entrance, obstacle, or already has container\n            if (is_entrance(i, j) || is_obstacle[i][j] || has_container[i][j]) {\n                continue;\n            }\n            \n            // Skip if not reachable\n            if (!reachable[i][j]) {\n                continue;\n            }\n            \n            // Calculate score based on multiple factors\n            double distance_score = -manhattan_distance(i, j) * 0.1;\n            double position_score = 0;\n            \n            // Prefer positions that are less likely to block others\n            // Count how many cells would become unreachable if we place container here\n            has_container[i][j] = true;\n            auto new_reachable = get_reachable();\n            has_container[i][j] = false;\n            \n            int blocked_count = 0;\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (!is_entrance(x, y) && !is_obstacle[x][y] && !has_container[x][y]) {\n                        if (reachable[x][y] && !new_reachable[x][y]) {\n                            blocked_count++;\n                        }\n                    }\n                }\n            }\n            \n            double blocking_penalty = -blocked_count * 0.5;\n            \n            // Prefer corners and edges for higher numbers\n            double edge_bonus = 0;\n            if (i == 0 || i == D-1 || j == 0 || j == D-1) {\n                edge_bonus = 0.2;\n            }\n            \n            // For later containers, prefer positions further from entrance\n            double adaptive_distance = (double)container_num / total_containers;\n            double adaptive_score = -(manhattan_distance(i, j) - 4 * adaptive_distance) * 0.1;\n            \n            double total_score = distance_score + blocking_penalty + edge_bonus + adaptive_score;\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_pos = {i, j};\n            }\n        }\n    }\n    \n    return best_pos;\n}\n\nint main() {\n    // Read input\n    cin >> D >> N;\n    \n    // Initialize arrays\n    memset(is_obstacle, false, sizeof(is_obstacle));\n    memset(has_container, false, sizeof(has_container));\n    \n    // Read obstacles\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        obstacles.push_back({r, c});\n    }\n    \n    int total_containers = D * D - 1 - N;\n    vector<pair<int, int>> placement_order(total_containers);\n    \n    // Process each container as it arrives\n    for (int d = 0; d < total_containers; d++) {\n        int container_num;\n        cin >> container_num;\n        \n        // Find best position\n        auto pos = find_best_position(container_num, total_containers);\n        \n        // Place container\n        has_container[pos.first][pos.second] = true;\n        container_number[pos.first][pos.second] = container_num;\n        placement_order[d] = pos;\n        \n        // Output position\n        cout << pos.first << \" \" << pos.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieve containers in optimal order\n    vector<pair<int, int>> retrieval_order;\n    vector<bool> transported(total_containers, false);\n    \n    // Greedy approach: always pick the smallest accessible container number\n    while (retrieval_order.size() < total_containers) {\n        auto reachable_containers = get_reachable_containers();\n        \n        // Find the container with minimum number among reachable ones\n        int min_num = INT_MAX;\n        pair<int, int> best_container = {-1, -1};\n        \n        for (auto& pos : reachable_containers) {\n            int num = container_number[pos.first][pos.second];\n            if (num < min_num) {\n                min_num = num;\n                best_container = pos;\n            }\n        }\n        \n        // Remove this container and add to retrieval order\n        has_container[best_container.first][best_container.second] = false;\n        retrieval_order.push_back(best_container);\n    }\n    \n    // Output retrieval order\n    for (auto& pos : retrieval_order) {\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n = 50, m = 100;\nint input_grid[N][N];\nint output_grid[N][N];\n\n// Adjacency information\nvector<set<int>> adj_list(M + 1);\nvector<vector<bool>> is_adj(M + 1, vector<bool>(M + 1, false));\n\n// Position information for each color\nvector<vector<pair<int, int>>> color_positions(M + 1);\n\n// Find connected components and adjacencies\nvoid analyze_input() {\n    // Collect positions for each color\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            color_positions[color].push_back({i, j});\n        }\n    }\n    \n    // Find adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            // Check 4 directions\n            int dx[] = {-1, 1, 0, 0};\n            int dy[] = {0, 0, -1, 1};\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int neighbor_color = input_grid[ni][nj];\n                    if (color != neighbor_color) {\n                        is_adj[color][neighbor_color] = true;\n                        is_adj[neighbor_color][color] = true;\n                        adj_list[color].insert(neighbor_color);\n                        adj_list[neighbor_color].insert(color);\n                    }\n                } else {\n                    // Boundary - adjacent to outside (color 0)\n                    is_adj[color][0] = true;\n                    is_adj[0][color] = true;\n                    adj_list[color].insert(0);\n                    adj_list[0].insert(color);\n                }\n            }\n        }\n    }\n}\n\n// Simple greedy approach: place colors in a compact way\nvoid generate_output() {\n    // Initialize output grid with 0s\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output_grid[i][j] = 0;\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from center\n    int center_x = N / 2;\n    int center_y = N / 2;\n    \n    // Place color 0 (outside) everywhere first\n    // Then we'll overwrite with other colors\n    \n    vector<bool> placed(M + 1, false);\n    placed[0] = true;\n    \n    // Place colors in order, trying to make them adjacent as required\n    queue<int> to_place;\n    set<int> remaining;\n    \n    for (int i = 1; i <= m; i++) {\n        remaining.insert(i);\n    }\n    \n    // Start with color 1 at center\n    output_grid[center_x][center_y] = 1;\n    placed[1] = true;\n    remaining.erase(1);\n    to_place.push(1);\n    \n    // BFS-like placement to maintain adjacencies\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    while (!to_place.empty() && !remaining.empty()) {\n        int current_color = to_place.front();\n        to_place.pop();\n        \n        // Find adjacent positions that are still 0\n        vector<pair<int, int>> adjacent_empty;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (output_grid[i][j] == current_color) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dx[k];\n                        int nj = j + dy[k];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            if (output_grid[ni][nj] == 0) {\n                                adjacent_empty.push_back({ni, nj});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Place adjacent colors\n        for (int adj_color : adj_list[current_color]) {\n            if (!placed[adj_color] && !remaining.empty() && find(remaining.begin(), remaining.end(), adj_color) != remaining.end()) {\n                if (!adjacent_empty.empty()) {\n                    auto pos = adjacent_empty.back();\n                    adjacent_empty.pop_back();\n                    output_grid[pos.first][pos.second] = adj_color;\n                    placed[adj_color] = true;\n                    remaining.erase(adj_color);\n                    to_place.push(adj_color);\n                }\n            }\n        }\n    }\n    \n    // Place any remaining colors\n    for (int color : remaining) {\n        // Find any empty spot\n        bool placed_color = false;\n        for (int i = 0; i < N && !placed_color; i++) {\n            for (int j = 0; j < N && !placed_color; j++) {\n                if (output_grid[i][j] == 0) {\n                    output_grid[i][j] = color;\n                    placed_color = true;\n                }\n            }\n        }\n    }\n    \n    // Expand each color to make connected regions\n    for (int color = 1; color <= m; color++) {\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_grid[i][j] == color) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.empty()) continue;\n        \n        // Use BFS to expand this color to make it more connected\n        queue<pair<int, int>> q;\n        set<pair<int, int>> visited;\n        \n        for (auto pos : positions) {\n            q.push(pos);\n            visited.insert(pos);\n        }\n        \n        int expansions = min(3, 20 - (int)positions.size()); // Limit expansion\n        int expanded = 0;\n        \n        while (!q.empty() && expanded < expansions) {\n            auto current = q.front();\n            q.pop();\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = current.first + dx[k];\n                int nj = current.second + dy[k];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (output_grid[ni][nj] == 0 && visited.find({ni, nj}) == visited.end()) {\n                        output_grid[ni][nj] = color;\n                        visited.insert({ni, nj});\n                        q.push({ni, nj});\n                        expanded++;\n                        if (expanded >= expansions) break;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input_grid[i][j];\n        }\n    }\n    \n    // Analyze the input to understand adjacencies\n    analyze_input();\n    \n    // Generate optimized output\n    generate_output();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << output_grid[i][j];\n            if (j < N - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 105;\nconst int INF = 1e9;\n\nint N, D, Q;\nvector<vector<int>> win_count, total_count;\nvector<double> weight_estimates;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to query the balance\nstring query(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 result;\n    cin >> result;\n    return result;\n}\n\n// Estimate weights using Bradley-Terry model approximation\nvoid estimate_weights() {\n    // Initialize comparison matrices\n    win_count.assign(N, vector<int>(N, 0));\n    total_count.assign(N, vector<int>(N, 0));\n    \n    // First, do pairwise comparisons for all items (if possible)\n    vector<pair<int, int>> all_pairs;\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            all_pairs.push_back({i, j});\n        }\n    }\n    \n    // Shuffle to randomize\n    shuffle(all_pairs.begin(), all_pairs.end(), rng);\n    \n    int queries_used = 0;\n    \n    // Phase 1: Pairwise comparisons\n    int pairwise_limit = min(Q / 2, (int)all_pairs.size());\n    for (int i = 0; i < pairwise_limit && queries_used < Q; i++) {\n        int a = all_pairs[i].first;\n        int b = all_pairs[i].second;\n        \n        vector<int> left = {a};\n        vector<int> right = {b};\n        string result = query(left, right);\n        queries_used++;\n        \n        total_count[a][b]++;\n        total_count[b][a]++;\n        \n        if (result == \">\") {\n            win_count[a][b]++;\n        } else if (result == \"<\") {\n            win_count[b][a]++;\n        }\n        // For '=' we can count as 0.5 each way\n    }\n    \n    // Phase 2: Group comparisons to refine estimates\n    while (queries_used < Q) {\n        // Compare random subsets\n        int subset_size = min(5, N / 2);\n        if (subset_size < 1) subset_size = 1;\n        \n        vector<int> left_items, right_items;\n        vector<bool> used(N, false);\n        \n        // Select random items for left side\n        int left_count = min(subset_size, N / 2);\n        for (int i = 0; i < left_count && left_items.size() < left_count; i++) {\n            int idx = rng() % N;\n            if (!used[idx]) {\n                left_items.push_back(idx);\n                used[idx] = true;\n            }\n        }\n        \n        // Select random items for right side\n        int right_count = min(subset_size, N - (int)left_items.size());\n        for (int i = 0; i < right_count && right_items.size() < right_count; i++) {\n            int idx = rng() % N;\n            if (!used[idx]) {\n                right_items.push_back(idx);\n                used[idx] = true;\n            }\n        }\n        \n        if (left_items.empty() || right_items.empty()) {\n            // Fallback to single item comparison\n            int a = rng() % N;\n            int b = rng() % N;\n            if (a == b) continue;\n            \n            vector<int> left = {a};\n            vector<int> right = {b};\n            string result = query(left, right);\n            queries_used++;\n            \n            total_count[a][b]++;\n            total_count[b][a]++;\n            \n            if (result == \">\") {\n                win_count[a][b]++;\n            } else if (result == \"<\") {\n                win_count[b][a]++;\n            }\n        } else {\n            string result = query(left_items, right_items);\n            queries_used++;\n            \n            // Update pairwise statistics based on group results\n            // This is a simplification - in practice we'd want to be more sophisticated\n            for (int a : left_items) {\n                for (int b : right_items) {\n                    total_count[a][b]++;\n                    total_count[b][a]++;\n                    \n                    if (result == \">\") {\n                        win_count[a][b]++;\n                    } else if (result == \"<\") {\n                        win_count[b][a]++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Estimate weights using win/loss ratios\n    weight_estimates.assign(N, 1.0);\n    \n    // Simple iterative approach: items that win more against others are heavier\n    for (int iter = 0; iter < 20; iter++) {\n        vector<double> new_weights(N, 0.0);\n        vector<double> normalizers(N, 0.0);\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i == j) continue;\n                if (total_count[i][j] > 0) {\n                    double win_rate = (double)win_count[i][j] / total_count[i][j];\n                    new_weights[i] += win_rate * weight_estimates[j];\n                    normalizers[i] += weight_estimates[j];\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            if (normalizers[i] > 0) {\n                weight_estimates[i] = max(0.1, new_weights[i] / normalizers[i]);\n            }\n        }\n        \n        // Normalize\n        double sum = 0;\n        for (int i = 0; i < N; i++) sum += weight_estimates[i];\n        if (sum > 0) {\n            for (int i = 0; i < N; i++) weight_estimates[i] = weight_estimates[i] * N / sum;\n        }\n    }\n}\n\n// Karmarkar-Karp differencing algorithm for balanced partitioning\nvector<int> karmarkar_karp_partition() {\n    vector<int> assignment(N, 0);\n    \n    // Create list of (weight, item_id) pairs\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.push_back({weight_estimates[i], i});\n    }\n    \n    // Sort by weight descending\n    sort(items.begin(), items.end());\n    reverse(items.begin(), items.end());\n    \n    // Use priority queue to implement Karmarkar-Karp\n    priority_queue<pair<double, vector<int>>> pq;\n    \n    // Initialize: each item in its own group\n    for (int i = 0; i < N; i++) {\n        vector<int> group = {items[i].second};\n        pq.push({items[i].first, group});\n    }\n    \n    // Combine the two heaviest groups until we have D groups\n    while (pq.size() > D) {\n        auto heaviest = pq.top(); pq.pop();\n        auto second_heaviest = pq.top(); pq.pop();\n        \n        // Merge groups (subtract because we're combining)\n        double new_weight = heaviest.first - second_heaviest.first;\n        vector<int> new_group = heaviest.second;\n        new_group.insert(new_group.end(), second_heaviest.second.begin(), second_heaviest.second.end());\n        \n        pq.push({new_weight, new_group});\n    }\n    \n    // Assign remaining groups\n    vector<vector<int>> final_groups;\n    while (!pq.empty()) {\n        final_groups.push_back(pq.top().second);\n        pq.pop();\n    }\n    \n    // Assign group numbers\n    for (int g = 0; g < min(D, (int)final_groups.size()); g++) {\n        for (int item : final_groups[g]) {\n            assignment[item] = g;\n        }\n    }\n    \n    // Handle any remaining items (shouldn't happen with KK)\n    for (int i = 0; i < N; i++) {\n        if (assignment[i] >= D) {\n            assignment[i] = D - 1;\n        }\n    }\n    \n    return assignment;\n}\n\n// Improved greedy with local search\nvector<int> improved_greedy_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Create list of items with their estimated weights\n    vector<pair<double, int>> items_with_weights;\n    for (int i = 0; i < N; i++) {\n        items_with_weights.push_back({weight_estimates[i], i});\n    }\n    \n    // Sort by weight (descending) to place heavier items first\n    sort(items_with_weights.rbegin(), items_with_weights.rend());\n    \n    // Initial assignment using multi-way partitioning\n    for (auto& item : items_with_weights) {\n        double weight = item.first;\n        int item_id = item.second;\n        \n        // Find group with minimum current sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    // Local search improvement\n    bool improved = true;\n    int iterations = 0;\n    const int MAX_ITERATIONS = 10000;\n    \n    while (improved && iterations < MAX_ITERATIONS) {\n        improved = false;\n        iterations++;\n        \n        // Try moving each item to a different group\n        for (int i = 0; i < N; i++) {\n            int current_group = assignment[i];\n            double item_weight = weight_estimates[i];\n            \n            // Try moving to each other group\n            for (int new_group = 0; new_group < D; new_group++) {\n                if (new_group == current_group) continue;\n                \n                // Calculate current variance contribution\n                double old_mean = 0;\n                for (int g = 0; g < D; g++) old_mean += group_sums[g];\n                old_mean /= D;\n                \n                double old_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    old_variance += (group_sums[g] - old_mean) * (group_sums[g] - old_mean);\n                }\n                old_variance /= D;\n                \n                // Simulate move\n                group_sums[current_group] -= item_weight;\n                group_sums[new_group] += item_weight;\n                \n                // Calculate new variance\n                double new_mean = 0;\n                for (int g = 0; g < D; g++) new_mean += group_sums[g];\n                new_mean /= D;\n                \n                double new_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    new_variance += (group_sums[g] - new_mean) * (group_sums[g] - new_mean);\n                }\n                new_variance /= D;\n                \n                // If improvement, keep the move\n                if (new_variance < old_variance - 1e-9) {  // Small epsilon for numerical stability\n                    assignment[i] = new_group;\n                    improved = true;\n                    break;\n                } else {\n                    // Revert move\n                    group_sums[current_group] += item_weight;\n                    group_sums[new_group] -= item_weight;\n                }\n            }\n            \n            if (improved) break;\n        }\n    }\n    \n    return assignment;\n}\n\n// Simple greedy as fallback\nvector<int> simple_greedy_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Pair items and assign pairs to balance groups\n    vector<pair<double, int>> sorted_items;\n    for (int i = 0; i < N; i++) {\n        sorted_items.push_back({weight_estimates[i], i});\n    }\n    \n    sort(sorted_items.begin(), sorted_items.end());\n    \n    // Assign items in pairs (largest with smallest) to balance groups\n    for (int i = 0; i < N; i++) {\n        int item_id = sorted_items[i].second;\n        double weight = sorted_items[i].first;\n        \n        // Find group with minimum sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Estimate weights using balance comparisons\n    estimate_weights();\n    \n    // Try different partitioning strategies and pick the best\n    vector<int> result1 = improved_greedy_partition();\n    vector<int> result2 = karmarkar_karp_partition();\n    vector<int> result3 = simple_greedy_partition();\n    \n    // Calculate variance for each result and pick the best\n    auto calculate_variance = [&](const vector<int>& assignment) -> double {\n        vector<double> group_sums(D, 0.0);\n        for (int i = 0; i < N; i++) {\n            group_sums[assignment[i]] += weight_estimates[i];\n        }\n        \n        double mean = 0;\n        for (int g = 0; g < D; g++) mean += group_sums[g];\n        mean /= D;\n        \n        double variance = 0;\n        for (int g = 0; g < D; g++) {\n            variance += (group_sums[g] - mean) * (group_sums[g] - mean);\n        }\n        variance /= D;\n        \n        return variance;\n    };\n    \n    double var1 = calculate_variance(result1);\n    double var2 = calculate_variance(result2);\n    double var3 = calculate_variance(result3);\n    \n    vector<int> best_result = result1;\n    double best_var = var1;\n    \n    if (var2 < best_var) {\n        best_result = result2;\n        best_var = var2;\n    }\n    \n    if (var3 < best_var) {\n        best_result = result3;\n        best_var = var3;\n    }\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        cout << best_result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 200;\nconst int M = 10;\nconst int STACK_SIZE = N / M;\n\nstruct State {\n    vector<deque<int>> stacks;\n    vector<pair<int, int>> box_positions; // {stack_idx, position_in_stack}\n    vector<bool> removed;\n    int total_energy = 0;\n    vector<pair<int, int>> operations;\n    \n    State() : stacks(M), box_positions(N + 1), removed(N + 1, false) {}\n    \n    void initialize() {\n        for (int i = 0; i < M; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                int box = stacks[i][j];\n                box_positions[box] = {i, j};\n            }\n        }\n    }\n    \n    bool is_top(int box) {\n        auto [stack_idx, pos] = box_positions[box];\n        return pos == (int)stacks[stack_idx].size() - 1;\n    }\n    \n    int stack_height(int stack_idx) {\n        return stacks[stack_idx].size();\n    }\n    \n    pair<int, int> find_box_position(int box) {\n        return box_positions[box];\n    }\n};\n\nclass Solver {\nprivate:\n    State state;\n    \npublic:\n    Solver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Move target box to top if not already there\n            while (!state.is_top(target)) {\n                auto [stack_idx, pos] = state.find_box_position(target);\n                int boxes_above = state.stack_height(stack_idx) - pos - 1;\n                \n                // Find best destination stack\n                int best_dest = -1;\n                int min_cost = INT_MAX;\n                \n                for (int dest = 0; dest < M; dest++) {\n                    if (dest == stack_idx) continue;\n                    \n                    // Cost is number of boxes moved + 1\n                    int cost = boxes_above + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_dest = dest;\n                    }\n                }\n                \n                if (best_dest == -1) {\n                    // Fallback: pick any different stack\n                    best_dest = (stack_idx + 1) % M;\n                }\n                \n                // Execute move\n                execute_move(target, best_dest);\n            }\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\n// Improved solver with better heuristics\nclass ImprovedSolver {\nprivate:\n    State state;\n    \npublic:\n    ImprovedSolver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Bring target to top with optimized strategy\n            bring_to_top(target);\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void bring_to_top(int target) {\n        while (!state.is_top(target)) {\n            auto [source_stack, pos] = state.find_box_position(target);\n            int boxes_above = state.stack_height(source_stack) - pos - 1;\n            \n            // Smart destination selection\n            int best_dest = find_best_destination(source_stack, boxes_above);\n            \n            // Execute move\n            execute_move(target, best_dest);\n        }\n    }\n    \n    int find_best_destination(int source_stack, int boxes_above) {\n        // Prefer stacks with fewer boxes to minimize future conflicts\n        int best_dest = -1;\n        int min_height = INT_MAX;\n        \n        for (int dest = 0; dest < M; dest++) {\n            if (dest == source_stack) continue;\n            \n            int height = state.stack_height(dest);\n            if (height < min_height) {\n                min_height = height;\n                best_dest = dest;\n            }\n        }\n        \n        // If all stacks are full, pick one that's not the source\n        if (best_dest == -1) {\n            best_dest = (source_stack + 1) % M;\n        }\n        \n        return best_dest;\n    }\n    \n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    ImprovedSolver solver(stacks);\n    vector<pair<int, int>> operations = solver.solve();\n    \n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\nbool visited[MAXN][MAXN];\n\n// Directions: Right, Down, Left, Up\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\n// Check if we can move from (i,j) to direction dir\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check for walls\n    if (dir == 0 || dir == 2) { // Horizontal move\n        return v[i][min(j, nj)] == '0';\n    } else { // Vertical move\n        return h[min(i, ni)][j] == '0';\n    }\n}\n\n// DFS with priority to high dirtiness squares\nvoid dfs_priority(int i, int j, string& path) {\n    visited[i][j] = true;\n    \n    // Create list of valid unvisited neighbors\n    vector<pair<int, int>> neighbors;\n    for (int dir = 0; dir < 4; dir++) {\n        if (!can_move(i, j, dir)) continue;\n        \n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj]) {\n            neighbors.push_back({d[ni][nj], dir});\n        }\n    }\n    \n    // Sort by dirtiness (descending)\n    sort(neighbors.begin(), neighbors.end(), greater<pair<int, int>>());\n    \n    for (auto& neighbor : neighbors) {\n        int dir = neighbor.second;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        path += dir_char[dir];\n        dfs_priority(ni, nj, path);\n        path += dir_char[(dir + 2) % 4]; // Return move\n    }\n}\n\n// Create a more sophisticated path by doing multiple DFS passes\nvoid create_path(string& path) {\n    // First, do a basic DFS to ensure all squares are visited\n    memset(visited, false, sizeof(visited));\n    dfs_priority(0, 0, path);\n    \n    // If we have space, add more visits to high-value squares\n    if (path.length() < 80000) {\n        // Add a second pass, but be more selective\n        // We could implement a more complex strategy here\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    // Read dirtiness values\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    string path = \"\";\n    create_path(path);\n    \n    // Make sure path isn't too long\n    if (path.length() > 100000) {\n        path = path.substr(0, 100000);\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\nint n, m;\nint start_i, start_j;\nchar grid[N][N];\nvector<string> targets;\nvector<pair<int,int>> char_positions[26];\n\n// Preprocessing to map characters to positions\nvoid preprocess() {\n    for (int i = 0; i < 26; i++) {\n        char_positions[i].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// Find best position for a character considering future characters\npair<int, int> find_best_position(const string& s, int start_idx, int cur_i, int cur_j) {\n    char c = s[start_idx];\n    int best_cost = 1e9;\n    pair<int, int> best_pos = {0, 0};\n    \n    // Look ahead a few characters to make better decisions\n    int lookahead = min(3, (int)s.length() - start_idx - 1);\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int cost = abs(pos.first - cur_i) + abs(pos.second - cur_j) + 1;\n        \n        // If we have characters ahead, consider their positions too\n        if (lookahead > 0) {\n            char next_c = s[start_idx + 1];\n            auto next_pos = find_best_position(s, start_idx + 1, pos.first, pos.second);\n            cost += abs(next_pos.first - pos.first) + abs(next_pos.second - pos.second) + 1;\n        }\n        \n        if (cost < best_cost) {\n            best_cost = cost;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Simple greedy approach for finding position\npair<int, int> find_closest(char c, int cur_i, int cur_j) {\n    int best_dist = 1e9;\n    pair<int, int> best_pos = {cur_i, cur_j}; // Default to current position\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int dist = abs(pos.first - cur_i) + abs(pos.second - cur_j);\n        if (dist < best_dist) {\n            best_dist = dist;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Calculate overlap between two strings\nint calculate_overlap(const string& a, const string& b) {\n    int max_overlap = 0;\n    for (int i = 1; i <= min(a.length(), b.length()); i++) {\n        if (a.substr(a.length() - i) == b.substr(0, i)) {\n            max_overlap = i;\n        }\n    }\n    return max_overlap;\n}\n\n// Greedy shortest superstring construction\nstring construct_superstring() {\n    if (targets.empty()) return \"\";\n    \n    vector<string> strings = targets;\n    random_shuffle(strings.begin(), strings.end());\n    \n    // Try to merge strings with maximum overlap\n    while (strings.size() > 1) {\n        int max_overlap = -1;\n        int best_i = -1, best_j = -1;\n        string best_merged;\n        \n        int limit = min(50, (int)strings.size());\n        \n        // Check pairs for maximum overlap\n        for (int i = 0; i < limit; i++) {\n            for (int j = i + 1; j < limit; j++) {\n                // Try a + b\n                int overlap1 = calculate_overlap(strings[i], strings[j]);\n                string merged1 = strings[i] + strings[j].substr(overlap1);\n                \n                // Try b + a\n                int overlap2 = calculate_overlap(strings[j], strings[i]);\n                string merged2 = strings[j] + strings[i].substr(overlap2);\n                \n                if (overlap1 > max_overlap) {\n                    max_overlap = overlap1;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged1;\n                }\n                \n                if (overlap2 > max_overlap) {\n                    max_overlap = overlap2;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged2;\n                }\n            }\n        }\n        \n        if (best_i == -1) {\n            // No good overlap found, just concatenate first two\n            best_merged = strings[0] + strings[1];\n            best_i = 0;\n            best_j = 1;\n        }\n        \n        // Remove the two strings and add the merged one\n        if (best_i > best_j) swap(best_i, best_j);\n        strings.erase(strings.begin() + best_j);\n        strings.erase(strings.begin() + best_i);\n        strings.push_back(best_merged);\n    }\n    \n    return strings[0];\n}\n\n// Generate optimized path\nvector<pair<int, int>> generate_optimized_path(const string& s) {\n    vector<pair<int, int>> path;\n    int cur_i = start_i, cur_j = start_j;\n    \n    for (int i = 0; i < (int)s.length(); i++) {\n        auto pos = find_closest(s[i], cur_i, cur_j);\n        path.push_back(pos);\n        cur_i = pos.first;\n        cur_j = pos.second;\n    }\n    \n    return path;\n}\n\n// Count how many targets are contained\nint count_targets(const string& s) {\n    int count = 0;\n    for (const string& target : targets) {\n        if (s.find(target) != string::npos) {\n            count++;\n        }\n    }\n    return count;\n}\n\n// Try to ensure all targets are included\nstring ensure_all_targets(const string& s) {\n    string result = s;\n    vector<bool> covered(m, false);\n    \n    // Check which targets are already covered\n    for (int i = 0; i < m; i++) {\n        if (result.find(targets[i]) != string::npos) {\n            covered[i] = true;\n        }\n    }\n    \n    // Add missing targets\n    for (int i = 0; i < m; i++) {\n        if (!covered[i]) {\n            result += targets[i];\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 >> start_i >> start_j;\n    \n    for (int i = 0; i < n; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < n; j++) {\n            grid[i][j] = line[j];\n        }\n    }\n    \n    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i];\n    }\n    \n    preprocess();\n    \n    // Try multiple approaches and pick the best\n    string best_result;\n    int best_score = -1;\n    \n    // Approach 1: Greedy superstring\n    string superstring = construct_superstring();\n    superstring = ensure_all_targets(superstring);\n    \n    // Approach 2: Simple concatenation of some targets\n    string simple_concat;\n    for (int i = 0; i < min(50, m); i++) {\n        simple_concat += targets[i];\n    }\n    \n    // Choose the better approach based on coverage\n    int coverage1 = count_targets(superstring);\n    int coverage2 = count_targets(simple_concat);\n    \n    string final_string = (coverage1 >= coverage2) ? superstring : simple_concat;\n    \n    // Make sure we have all targets\n    final_string = ensure_all_targets(final_string);\n    \n    // If still too long, trim but keep as many targets as possible\n    if (final_string.length() > 2000) {\n        string trimmed;\n        int target_count = 0;\n        for (int i = 0; i < m && trimmed.length() < 1500; i++) {\n            if (trimmed.find(targets[i]) == string::npos) {\n                trimmed += targets[i];\n                target_count++;\n            }\n        }\n        final_string = trimmed;\n    }\n    \n    // Generate the path\n    auto path = generate_optimized_path(final_string);\n    \n    // Limit to maximum operations\n    if (path.size() > MAX_OPS) {\n        path.resize(MAX_OPS);\n    }\n    \n    // Output the path\n    for (const auto& pos : path) {\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\n\nusing namespace std;\n\nconst int MAX_N = 20;\n\nint N, M;\ndouble epsilon;\nvector<vector<pair<int,int>>> oil_fields;\nvector<vector<bool>> has_oil;\nvector<vector<bool>> queried;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    cin >> N >> M >> epsilon;\n    oil_fields.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        int d;\n        cin >> d;\n        oil_fields[i].resize(d);\n        for (int j = 0; j < d; j++) {\n            cin >> oil_fields[i][j].first >> oil_fields[i][j].second;\n        }\n    }\n    \n    // Initialize tracking arrays\n    has_oil.assign(N, vector<bool>(N, false));\n    queried.assign(N, vector<bool>(N, false));\n    \n    // Simple strategy: query all squares individually\n    // This is the baseline from the sample solution but more robust\n    vector<pair<int,int>> oil_squares;\n    \n    int max_queries = 2 * N * N - N * N / 2; // Leave some buffer for the answer\n    int query_count = 0;\n    \n    // Query squares in a systematic way\n    for (int i = 0; i < N && query_count < max_queries; i++) {\n        for (int j = 0; j < N && query_count < max_queries; j++) {\n            // Query this square\n            cout << \"q 1 \" << i << \" \" << j << \"\\n\";\n            cout.flush();\n            query_count++;\n            \n            int result;\n            cin >> result;\n            \n            if (result > 0) {\n                has_oil[i][j] = true;\n                oil_squares.push_back({i, j});\n            }\n            queried[i][j] = true;\n        }\n    }\n    \n    // Collect all squares that have oil\n    vector<pair<int,int>> result_squares;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (has_oil[i][j]) {\n                result_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    // Submit answer\n    cout << \"a \" << result_squares.size();\n    for (const auto& sq : result_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << \"\\n\";\n    cout.flush();\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int W = 1000;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int _i0, int _j0, int _i1, int _j1) : i0(_i0), j0(_j0), i1(_i1), j1(_j1) {}\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// Optimized packing that prioritizes area satisfaction\nvector<Rectangle> optimizedPack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Use a more sophisticated grid approach\n    int grid_rows = max(1, (int)sqrt(n));\n    int grid_cols = (n + grid_rows - 1) / grid_rows;\n    \n    int cell_height = W / max(1, grid_rows);\n    int cell_width = W / max(1, grid_cols);\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Grid position\n        int grid_row = k / grid_cols;\n        int grid_col = k % grid_cols;\n        \n        // Cell boundaries\n        int cell_top = grid_row * cell_height;\n        int cell_left = grid_col * cell_width;\n        int cell_bottom = min(W, (grid_row + 1) * cell_height);\n        int cell_right = min(W, (grid_col + 1) * cell_width);\n        \n        // Available space in cell\n        int avail_height = cell_bottom - cell_top;\n        int avail_width = cell_right - cell_left;\n        \n        // Make sure we have minimum space\n        avail_height = max(1, avail_height);\n        avail_width = max(1, avail_width);\n        \n        // Calculate optimal dimensions to satisfy area requirement\n        // Try to make it as square as possible within constraints\n        int target_height = max(1, min(avail_height, (int)sqrt(required)));\n        int target_width = max(1, (required + target_height - 1) / target_height);\n        \n        // Adjust if width exceeds available space\n        if (target_width > avail_width) {\n            target_width = avail_width;\n            target_height = max(1, (required + target_width - 1) / target_width);\n            // If still exceeding height, cap it\n            if (target_height > avail_height) {\n                target_height = avail_height;\n            }\n        }\n        \n        // Final adjustment to maximize area (to reduce penalty)\n        while (target_height < avail_height && target_width < avail_width && \n               target_height * target_width < required) {\n            if (target_height * (target_width + 1) <= required) {\n                target_width++;\n            } else if ((target_height + 1) * target_width <= required) {\n                target_height++;\n            } else {\n                // Try increasing both\n                if (target_height < avail_height) target_height++;\n                if (target_width < avail_width) target_width++;\n            }\n        }\n        \n        // Ensure we don't exceed boundaries\n        target_height = max(1, min(target_height, avail_height));\n        target_width = max(1, min(target_width, avail_width));\n        \n        // Position within cell (try to center it)\n        int final_top = cell_top + max(0, (avail_height - target_height) / 2);\n        int final_left = cell_left + max(0, (avail_width - target_width) / 2);\n        \n        // Final boundary checks\n        int final_height = min(target_height, W - final_top);\n        int final_width = min(target_width, W - final_left);\n        \n        final_height = max(1, final_height);\n        final_width = max(1, final_width);\n        \n        result.emplace_back(final_top, final_left, final_top + final_height, final_left + final_width);\n    }\n    \n    return result;\n}\n\n// Even better approach - try to maximize area to reduce shortage penalty\nvector<Rectangle> areaOptimizedPack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Calculate grid dimensions\n    int sqrt_n = max(1, (int)sqrt(n));\n    int rows = sqrt_n;\n    int cols = (n + rows - 1) / rows;\n    \n    // Cell dimensions\n    int cell_h = W / max(1, rows);\n    int cell_w = W / max(1, cols);\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Grid cell position\n        int row = k / cols;\n        int col = k % cols;\n        \n        // Cell boundaries\n        int top = row * cell_h;\n        int left = col * cell_w;\n        int bottom = min(W, (row + 1) * cell_h);\n        int right = min(W, (col + 1) * cell_w);\n        \n        // Available space\n        int h_avail = max(1, bottom - top);\n        int w_avail = max(1, right - left);\n        \n        // Strategy: Try to get as close to required area as possible\n        // Start with a reasonable guess\n        int height = max(1, min(h_avail, (int)sqrt(required)));\n        int width = max(1, min(w_avail, (required + height - 1) / height)); // ceil division\n        \n        // Greedy expansion to get closer to required area\n        bool improved = true;\n        while (improved && height <= h_avail && width <= w_avail) {\n            improved = false;\n            \n            // Try expanding width\n            if (width < w_avail) {\n                int new_width = width + 1;\n                int new_area = height * new_width;\n                if (new_area <= required && abs(new_area - required) < abs(height * width - required)) {\n                    width = new_width;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding height\n            if (height < h_avail) {\n                int new_height = height + 1;\n                int new_area = new_height * width;\n                if (new_area <= required && abs(new_area - required) < abs(height * width - required)) {\n                    height = new_height;\n                    improved = true;\n                }\n            }\n        }\n        \n        // Final check - if we're significantly under, try to expand more aggressively\n        int current_area = height * width;\n        if (current_area < required) {\n            // Expand width if possible\n            if (width < w_avail) {\n                int max_width = min(w_avail, (required + height - 1) / height);\n                if (max_width > width) {\n                    width = max_width;\n                }\n            }\n            \n            // Expand height if still needed\n            current_area = height * width;\n            if (current_area < required && height < h_avail) {\n                int max_height = min(h_avail, (required + width - 1) / width);\n                if (max_height > height) {\n                    height = max_height;\n                }\n            }\n        }\n        \n        // Ensure within bounds\n        height = max(1, min(height, h_avail));\n        width = max(1, min(width, w_avail));\n        \n        // Position in cell (centered)\n        int final_top = top + max(0, (h_avail - height) / 2);\n        int final_left = left + max(0, (w_avail - width) / 2);\n        \n        // Final safety check\n        height = min(height, W - final_top);\n        width = min(width, W - final_left);\n        height = max(1, height);\n        width = max(1, width);\n        \n        result.emplace_back(final_top, final_left, final_top + height, final_left + width);\n    }\n    \n    return result;\n}\n\n// Best attempt - focus heavily on area satisfaction\nvector<Rectangle> bestEffortPack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Use a snake-like pattern to distribute rectangles\n    int grid_dim = max(1, (int)ceil(sqrt(n)));\n    int cell_size = W / grid_dim;\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Snake pattern position\n        int row, col;\n        if ((k / grid_dim) % 2 == 0) {\n            // Left to right\n            row = k / grid_dim;\n            col = k % grid_dim;\n        } else {\n            // Right to left\n            row = k / grid_dim;\n            col = grid_dim - 1 - (k % grid_dim);\n        }\n        \n        // Cell boundaries\n        int cell_top = row * cell_size;\n        int cell_left = col * cell_size;\n        int cell_bottom = min(W, (row + 1) * cell_size);\n        int cell_right = min(W, (col + 1) * cell_size);\n        \n        // Available space\n        int h_max = max(1, cell_bottom - cell_top);\n        int w_max = max(1, cell_right - cell_left);\n        \n        // Calculate dimensions that best satisfy the area requirement\n        long long target_area = required;\n        \n        // Find factors closest to square root\n        int h = max(1, (int)sqrt(target_area));\n        int w = (target_area + h - 1) / h; // ceil division\n        \n        // Adjust to fit in available space\n        if (w > w_max) {\n            w = w_max;\n            h = (target_area + w - 1) / w;\n        }\n        if (h > h_max) {\n            h = h_max;\n            w = (target_area + h - 1) / h;\n        }\n        if (w > w_max) {\n            w = w_max;\n        }\n        \n        // Try to get as close as possible to required area\n        int best_h = h, best_w = w;\n        long long best_diff = llabs((long long)best_h * best_w - target_area);\n        \n        // Search nearby values\n        for (int dh = -5; dh <= 5; dh++) {\n            for (int dw = -5; dw <= 5; dw++) {\n                int try_h = max(1, min(h_max, h + dh));\n                int try_w = max(1, min(w_max, w + dw));\n                long long area = (long long)try_h * try_w;\n                long long diff = llabs(area - target_area);\n                if (diff < best_diff) {\n                    best_diff = diff;\n                    best_h = try_h;\n                    best_w = try_w;\n                }\n            }\n        }\n        \n        h = best_h;\n        w = best_w;\n        \n        // Final boundary enforcement\n        h = max(1, min(h, h_max));\n        w = max(1, min(w, w_max));\n        \n        // Center in cell\n        int top = cell_top + max(0, (h_max - h) / 2);\n        int left = cell_left + max(0, (w_max - w) / 2);\n        \n        // Safety bounds check\n        h = min(h, W - top);\n        w = min(w, W - left);\n        h = max(1, h);\n        w = max(1, w);\n        \n        result.emplace_back(top, left, top + h, left + w);\n    }\n    \n    return result;\n}\n\nvector<vector<Rectangle>> solve(const vector<vector<int>>& all_areas) {\n    int D = all_areas.size();\n    vector<vector<Rectangle>> result(D);\n    \n    for (int d = 0; d < D; d++) {\n        result[d] = bestEffortPack(all_areas[d]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    \n    vector<vector<int>> all_areas(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> all_areas[d][k];\n        }\n    }\n    \n    // Solve\n    auto solution = solve(all_areas);\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << solution[d][k].i0 << \" \" << solution[d][k].j0 << \" \" \n                 << solution[d][k].i1 << \" \" << solution[d][k].j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint N = 9, M = 20, K = 81;\nlong long a[9][9];\nlong long s[20][3][3];\n\nstruct Operation {\n    int stamp, row, col;\n};\n\n// Calculate the gain in sum of remainders from applying a stamp at position (r,c)\nlong long calculate_gain(long long board[9][9], int stamp, int r, int c) {\n    long long gain = 0;\n    \n    // Calculate sum of remainders for affected cells before and after\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = r + i, col = c + j;\n            long long original_remainder = board[row][col] % MOD;\n            long long new_value = board[row][col] + s[stamp][i][j];\n            long long new_remainder = new_value % MOD;\n            gain += (long long)new_remainder - (long long)original_remainder;\n        }\n    }\n    \n    return gain;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> K;\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 (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n    \n    // Keep track of actual values (not modded yet)\n    long long board[9][9];\n    for (int i = 0; i < 9; i++) {\n        for (int j = 0; j < 9; j++) {\n            board[i][j] = a[i][j];\n        }\n    }\n    \n    vector<Operation> operations;\n    \n    // More sophisticated approach: \n    // 1. First, cover the board systematically\n    // 2. Then, apply additional operations greedily on high-impact areas\n    \n    // Phase 1: Systematic coverage (use about half the operations)\n    int phase1_ops = min(K / 2, 9);  // At most 9 non-overlapping operations\n    for (int base_r = 0; base_r < 9; base_r += 3) {\n        for (int base_c = 0; base_c < 9; base_c += 3) {\n            if ((int)operations.size() >= phase1_ops) break;\n            \n            // Find the best stamp for this region\n            long long best_increase = -1;\n            int best_stamp = 0;\n            \n            for (int stamp = 0; stamp < M; stamp++) {\n                long long gain = calculate_gain(board, stamp, base_r, base_c);\n                if (gain > best_increase) {\n                    best_increase = gain;\n                    best_stamp = stamp;\n                }\n            }\n            \n            // Apply the best stamp\n            operations.push_back({best_stamp, base_r, base_c});\n            \n            // Update board values\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[base_r + i][base_c + j] += s[best_stamp][i][j];\n                }\n            }\n        }\n        if ((int)operations.size() >= phase1_ops) break;\n    }\n    \n    // Phase 2: Greedy optimization with remaining operations\n    int remaining_ops = K - operations.size();\n    for (int op = 0; op < remaining_ops; op++) {\n        long long best_gain = -1;\n        int best_stamp = -1, best_row = -1, best_col = -1;\n        \n        // Try all possible stamp placements, but prioritize high-impact ones\n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int r = 0; r <= 6; r++) {\n                for (int c = 0; c <= 6; c++) {\n                    long long gain = calculate_gain(board, stamp, r, c);\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_stamp = stamp;\n                        best_row = r;\n                        best_col = c;\n                    }\n                }\n            }\n        }\n        \n        // If no positive gain, stop early\n        if (best_gain <= 0) {\n            break;\n        }\n        \n        // Apply the best operation\n        operations.push_back({best_stamp, best_row, best_col});\n        \n        // Update board values\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_row + i][best_col + j] += s[best_stamp][i][j];\n            }\n        }\n    }\n    \n    // Output result\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << op.stamp << \" \" << op.row << \" \" << op.col << \"\\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 container_to_row[N*N];\nvector<vector<int>> A(N, vector<int>(N));\nvector<string> result(N);\n\nvoid precompute() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            container_to_row[i * N + j] = i;\n        }\n    }\n}\n\n// Simple but effective strategy\nvoid solve() {\n    precompute();\n    \n    // Read input\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Greedy strategy: each crane processes its row\n    // Crane 0 (large) can help with complex movements\n    \n    for (int turn = 0; turn < 500; turn++) {\n        for (int crane = 0; crane < N; crane++) {\n            // Simple strategy: move right, pick up containers, move to right edge, drop off\n            if (turn * 2 < crane * 10) {\n                // Initial waiting period\n                result[crane] += '.';\n            } else if (turn < 100) {\n                // Movement pattern\n                int phase = (turn - crane * 5) % 20;\n                if (phase < 4) {\n                    result[crane] += 'R';\n                } else if (phase == 4) {\n                    result[crane] += 'P'; // Pick up\n                } else if (phase < 9) {\n                    result[crane] += 'R';\n                } else if (phase == 9) {\n                    result[crane] += 'Q'; // Drop off\n                } else if (phase < 14) {\n                    result[crane] += 'L';\n                } else {\n                    result[crane] += '.';\n                }\n            } else {\n                result[crane] += '.';\n            }\n        }\n    }\n    \n    // Ensure minimum length\n    int max_len = 0;\n    for (int i = 0; i < N; i++) {\n        max_len = max(max_len, (int)result[i].length());\n    }\n    \n    for (int i = 0; i < N; i++) {\n        while (result[i].length() < max_len) {\n            result[i] += '.';\n        }\n        if (result[i].empty()) result[i] = \".\";\n        cout << result[i] << \"\\n\";\n    }\n}\n\nint main() {\n    solve();\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int MOVE_COST_BASE = 100;\n\n// Manhattan distance\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Get moves to go from (x1,y1) to (x2,y2)\nvector<string> get_path(int x1, int y1, int x2, int y2) {\n    vector<string> moves;\n    while (x1 < x2) {\n        moves.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        moves.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        moves.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        moves.push_back(\"L\");\n        y1--;\n    }\n    return moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<int>> grid(n, vector<int>(n));\n    vector<tuple<int, int, int>> sources, sinks; // x, y, amount\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n            if (grid[i][j] > 0) {\n                sources.push_back({i, j, grid[i][j]});\n            } else if (grid[i][j] < 0) {\n                sinks.push_back({i, j, -grid[i][j]});\n            }\n        }\n    }\n    \n    vector<string> result;\n    int curr_x = 0, curr_y = 0;\n    \n    // Create supply and demand lists\n    vector<pair<int, int>> supply_positions, demand_positions;\n    vector<int> supply_amounts, demand_amounts;\n    \n    for (int i = 0; i < sources.size(); i++) {\n        auto [x, y, amount] = sources[i];\n        supply_positions.push_back({x, y});\n        supply_amounts.push_back(amount);\n    }\n    \n    for (int i = 0; i < sinks.size(); i++) {\n        auto [x, y, amount] = sinks[i];\n        demand_positions.push_back({x, y});\n        demand_amounts.push_back(amount);\n    }\n    \n    // Simple greedy approach: match supplies with demands\n    vector<int> supply_left = supply_amounts;\n    vector<int> demand_left = demand_amounts;\n    \n    // For each supply point, distribute to nearby demand points\n    for (int i = 0; i < supply_positions.size(); i++) {\n        if (supply_left[i] <= 0) continue;\n        \n        int sx = supply_positions[i].first;\n        int sy = supply_positions[i].second;\n        int supply_avail = supply_left[i];\n        \n        // Create list of demands with distances\n        vector<pair<int, int>> demand_with_dist; // {distance, index}\n        for (int j = 0; j < demand_positions.size(); j++) {\n            if (demand_left[j] > 0) {\n                int dx = demand_positions[j].first;\n                int dy = demand_positions[j].second;\n                int dist = manhattan(sx, sy, dx, dy);\n                demand_with_dist.push_back({dist, j});\n            }\n        }\n        \n        // Sort by distance\n        sort(demand_with_dist.begin(), demand_with_dist.end());\n        \n        // Distribute supply to nearest demands\n        for (auto& [dist, j] : demand_with_dist) {\n            if (supply_avail <= 0) break;\n            if (demand_left[j] <= 0) continue;\n            \n            int transfer = min(supply_avail, demand_left[j]);\n            \n            // Move to supply location\n            if (curr_x != sx || curr_y != sy) {\n                auto moves = get_path(curr_x, curr_y, sx, sy);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = sx;\n                curr_y = sy;\n            }\n            \n            // Load\n            result.push_back(\"+\" + to_string(transfer));\n            \n            // Move to demand location\n            int dx = demand_positions[j].first;\n            int dy = demand_positions[j].second;\n            if (curr_x != dx || curr_y != dy) {\n                auto moves = get_path(curr_x, curr_y, dx, dy);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = dx;\n                curr_y = dy;\n            }\n            \n            // Unload\n            result.push_back(\"-\" + to_string(transfer));\n            \n            supply_avail -= transfer;\n            demand_left[j] -= transfer;\n        }\n        \n        supply_left[i] = supply_avail;\n    }\n    \n    // Output results\n    for (const string& s : result) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int SEED_COUNT = 2 * N * (N - 1); // 72\n\n// Structure to hold seed information\nstruct Seed {\n    int id;\n    vector<int> values;\n    int total_value;\n    \n    Seed() : id(0), values(M, 0), total_value(0) {}\n    \n    Seed(int _id, const vector<int>& _values) : id(_id), values(_values) {\n        total_value = accumulate(values.begin(), values.end(), 0);\n    }\n};\n\n// Calculate how much a seed contributes to potential trait maxima\nint calculatePotentialScore(const Seed& seed, const vector<int>& current_max_traits) {\n    int score = seed.total_value;\n    int bonus = 0;\n    \n    // Bonus for seeds that have high values in traits\n    for (int i = 0; i < M; i++) {\n        if (seed.values[i] >= current_max_traits[i] * 0.8) {\n            bonus += 5; // Bonus for being close to trait maximum\n        }\n        if (seed.values[i] >= current_max_traits[i] * 0.95) {\n            bonus += 10; // Extra bonus for being very close to maximum\n        }\n    }\n    \n    return score + bonus;\n}\n\n// Select best seeds considering both total value and trait contributions\nvector<Seed> selectOptimalSeeds(vector<Seed>& all_seeds) {\n    // Calculate current maximum for each trait\n    vector<int> trait_max(M, 0);\n    for (const auto& seed : all_seeds) {\n        for (int i = 0; i < M; i++) {\n            trait_max[i] = max(trait_max[i], seed.values[i]);\n        }\n    }\n    \n    // Score each seed\n    vector<pair<int, int>> seed_scores; // {score, id}\n    for (int i = 0; i < SEED_COUNT; i++) {\n        int score = calculatePotentialScore(all_seeds[i], trait_max);\n        seed_scores.push_back({score, i});\n    }\n    \n    // Sort by score descending\n    sort(seed_scores.begin(), seed_scores.end(), greater<pair<int, int>>());\n    \n    // Select top N*N seeds\n    vector<Seed> selected;\n    for (int i = 0; i < N * N; i++) {\n        selected.push_back(all_seeds[seed_scores[i].second]);\n    }\n    \n    return selected;\n}\n\n// Generate placement positions with spiral pattern from center outward\nvector<pair<int, int>> generateSpiralCenterOrder() {\n    vector<pair<int, int>> positions;\n    \n    // Create all 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    // Sort by a combination of distance to center and strategic value\n    int center_i = N / 2;\n    int center_j = N / 2;\n    \n    sort(positions.begin(), positions.end(), \n         [center_i, center_j](const pair<int, int>& a, const pair<int, int>& b) {\n             // Distance to center\n             int dist_a = abs(a.first - center_i) + abs(a.second - center_j);\n             int dist_b = abs(b.first - center_i) + abs(b.second - center_j);\n             \n             // Prefer center positions, but also consider corners and edges strategically\n             // Center is most valuable (4 neighbors), then edge centers, then corners\n             if (dist_a != dist_b) {\n                 return dist_a < dist_b;\n             }\n             \n             // For same distance, prefer positions that are more \"central\"\n             int central_a = abs(abs(a.first - center_i) - abs(a.second - center_j));\n             int central_b = abs(abs(b.first - center_i) - abs(b.second - center_j));\n             \n             return central_a < central_b;\n         });\n    \n    return positions;\n}\n\n// Advanced placement considering seed compatibility\nvector<vector<int>> placeSeedsAdvanced(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending) as primary strategy\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Get positions ordered by strategic priority\n    vector<pair<int, int>> positions = generateSpiralCenterOrder();\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = seeds[i].id;\n    }\n    \n    return grid;\n}\n\n// Simple but effective placement (fallback)\nvector<vector<int>> placeSeedsSimple(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Simple row-major order with best seeds in center area\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    // Prioritize center positions\n    int center_i = N / 2;\n    int center_j = N / 2;\n    \n    sort(positions.begin(), positions.end(), \n         [center_i, center_j](const pair<int, int>& a, const pair<int, int>& b) {\n             int dist_a = abs(a.first - center_i) + abs(a.second - center_j);\n             int dist_b = abs(b.first - center_i) + abs(b.second - center_j);\n             return dist_a < dist_b;\n         });\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = seeds[i].id;\n    }\n    \n    return grid;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N_input, M_input, T;\n    cin >> N_input >> M_input >> T;\n    \n    vector<Seed> seeds(SEED_COUNT);\n    \n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; i++) {\n        vector<int> values(M);\n        for (int j = 0; j < M; j++) {\n            cin >> values[j];\n        }\n        seeds[i] = Seed(i, values);\n    }\n    \n    // Process each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Select and place seeds\n        vector<Seed> selected_seeds = selectOptimalSeeds(seeds);\n        vector<vector<int>> grid = placeSeedsSimple(selected_seeds);\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            vector<int> values(M);\n            for (int j = 0; j < M; j++) {\n                cin >> values[j];\n            }\n            seeds[i] = Seed(i, values);\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 30;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'R', 'D', 'L', 'U'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Edge {\n    int parent, length;\n    Edge() : parent(0), length(0) {}\n    Edge(int p, int l) : parent(p), length(l) {}\n};\n\nclass Solution {\npublic:\n    int N, M, V;\n    vector<vector<int>> source, target;\n    \n    Solution(int n, int m, int v) : N(n), M(m), V(v) {\n        source.assign(N, vector<int>(N, 0));\n        target.assign(N, vector<int>(N, 0));\n    }\n    \n    void read_input() {\n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                source[i][j] = line[j] - '0';\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    void design_arm() {\n        // Create a star-like tree with root at center\n        int num_edges = min(V - 1, 8);\n        \n        cout << num_edges + 1 << endl; // Number of vertices\n        \n        // Create edges from root (0) to fingertips\n        for (int i = 1; i <= num_edges; i++) {\n            cout << 0 << \" \" << 1 << endl; // parent, length\n        }\n        \n        // Initial root position\n        cout << N/2 << \" \" << N/2 << endl;\n    }\n    \n    int manhattan_distance(int x1, int y1, int x2, int y2) {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    vector<pair<int, int>> get_positions_to_visit() {\n        vector<pair<int, int>> positions;\n        \n        // Collect source positions (where takoyaki are)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        return positions;\n    }\n    \n    void solve() {\n        read_input();\n        design_arm();\n        \n        // Simple greedy approach\n        vector<pair<int, int>> sources, targets;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1 && target[i][j] == 0) {\n                    sources.push_back({i, j});\n                }\n                if (target[i][j] == 1 && source[i][j] == 0) {\n                    targets.push_back({i, j});\n                }\n            }\n        }\n        \n        // For demonstration, just do random moves\n        int root_x = N/2, root_y = N/2;\n        vector<bool> held(min(V, 9), false);\n        \n        for (int turn = 0; turn < 2000; turn++) {\n            string command(2 * min(V, 9), '.');\n            \n            // Move root randomly but stay in bounds\n            int dir = rand() % 5;\n            if (dir < 4) {\n                int nx = root_x + dx[dir];\n                int ny = root_y + dy[dir];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    root_x = nx;\n                    root_y = ny;\n                    command[0] = dir_char[dir];\n                }\n            }\n            \n            // Check if we can pick up or drop takoyaki\n            for (int finger = 1; finger < min(V, 9); finger++) {\n                int fx = root_x;\n                int fy = root_y + finger; // Simple positioning\n                \n                if (fx >= 0 && fx < N && fy >= 0 && fy < N) {\n                    // Try to pick up\n                    if (!held[finger] && source[fx][fy] == 1 && target[fx][fy] == 0) {\n                        source[fx][fy] = 0;\n                        held[finger] = true;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                    // Try to drop\n                    else if (held[finger] && source[fx][fy] == 0 && target[fx][fy] == 1) {\n                        source[fx][fy] = 1;\n                        held[finger] = false;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(time(nullptr));\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    Solution solution(N, M, V);\n    solution.solve();\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 5000;\nconst int MAX_COORD = 100000;\nconst int MAX_VERTICES = 1000;\nconst long long MAX_PERIMETER = 400000LL;\n\nstruct Point {\n    int x, y;\n    bool is_mackerel;\n    \n    Point() : x(0), y(0), is_mackerel(false) {}\n    Point(int _x, int _y, bool _is_mackerel) : x(_x), y(_y), is_mackerel(_is_mackerel) {}\n};\n\nstruct Rectangle {\n    int x1, y1, x2, y2;\n    \n    Rectangle() : x1(0), y1(0), x2(0), y2(0) {}\n    Rectangle(int _x1, int _y1, int _x2, int _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {}\n    \n    long long perimeter() const {\n        return 2LL * (abs(x2 - x1) + abs(y2 - y1));\n    }\n    \n    bool isValid() const {\n        return x1 >= 0 && x2 <= MAX_COORD && y1 >= 0 && y2 <= MAX_COORD && \n               x1 <= x2 && y1 <= y2;\n    }\n};\n\nvector<Point> points;\nvector<Point> mackerels, sardines;\n\n// 2D grid for faster counting\nconst int GRID_SIZE = 1000;\nvector<vector<pair<int, int>>> grid_mackerel(GRID_SIZE + 1, vector<pair<int, int>>(GRID_SIZE + 1, {0, 0}));\nvector<vector<pair<int, int>>> grid_sardine(GRID_SIZE + 1, vector<pair<int, int>>(GRID_SIZE + 1, {0, 0}));\n\nint grid_x[MAX_N * 2], grid_y[MAX_N * 2];\n\nvoid buildGrid() {\n    for (int i = 0; i <= GRID_SIZE; i++) {\n        for (int j = 0; j <= GRID_SIZE; j++) {\n            grid_mackerel[i][j] = {0, 0};\n            grid_sardine[i][j] = {0, 0};\n        }\n    }\n    \n    for (const auto& p : points) {\n        int gx = min(GRID_SIZE, p.x * GRID_SIZE / MAX_COORD);\n        int gy = min(GRID_SIZE, p.y * GRID_SIZE / MAX_COORD);\n        \n        if (p.is_mackerel) {\n            grid_mackerel[gx][gy].first++;\n            grid_mackerel[gx][gy].second += p.x;\n        } else {\n            grid_sardine[gx][gy].first++;\n            grid_sardine[gx][gy].second += p.x;\n        }\n    }\n}\n\n// Count points in rectangle using grid approximation\npair<int, int> countPointsInRectApprox(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    int gx1 = max(0, min(GRID_SIZE, rect.x1 * GRID_SIZE / MAX_COORD));\n    int gy1 = max(0, min(GRID_SIZE, rect.y1 * GRID_SIZE / MAX_COORD));\n    int gx2 = max(0, min(GRID_SIZE, rect.x2 * GRID_SIZE / MAX_COORD));\n    int gy2 = max(0, min(GRID_SIZE, rect.y2 * GRID_SIZE / MAX_COORD));\n    \n    for (int gx = gx1; gx <= gx2; gx++) {\n        for (int gy = gy1; gy <= gy2; gy++) {\n            mackerel_count += grid_mackerel[gx][gy].first;\n            sardine_count += grid_sardine[gx][gy].first;\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\n// Exact count for final evaluation\npair<int, int> countPointsInRectExact(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    for (const auto& p : points) {\n        if (p.x >= rect.x1 && p.x <= rect.x2 && p.y >= rect.y1 && p.y <= rect.y2) {\n            if (p.is_mackerel) {\n                mackerel_count++;\n            } else {\n                sardine_count++;\n            }\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\nint calculateScore(const Rectangle& rect) {\n    if (!rect.isValid()) return 0;\n    \n    auto [m, s] = countPointsInRectExact(rect);\n    return max(0, m - s + 1);\n}\n\n// Try to find good rectangles using local search\nRectangle findBestRectangle() {\n    Rectangle best_rect;\n    int best_score = 0;\n    \n    // Try different sizes and positions\n    vector<int> sizes = {5000, 10000, 15000, 20000, 25000, 30000};\n    \n    for (int size : sizes) {\n        // Sample points to try as centers\n        for (int i = 0; i < min(100, (int)mackerels.size()); i += max(1, (int)mackerels.size() / 100)) {\n            int cx = mackerels[i].x;\n            int cy = mackerels[i].y;\n            \n            // Try different rectangles around this center\n            for (int dx = -size/2; dx <= size/2; dx += size/4) {\n                for (int dy = -size/2; dy <= size/2; dy += size/4) {\n                    int x1 = max(0, cx + dx - size/2);\n                    int y1 = max(0, cy + dy - size/2);\n                    int x2 = min(MAX_COORD, cx + dx + size/2);\n                    int y2 = min(MAX_COORD, cy + dy + size/2);\n                    \n                    if (x2 > x1 && y2 > y1) {\n                        Rectangle rect(x1, y1, x2, y2);\n                        int score = calculateScore(rect);\n                        if (score > best_score) {\n                            best_score = score;\n                            best_rect = rect;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\n// Greedy approach: try to expand/shrink rectangle to improve score\nRectangle optimizeRectangle(Rectangle rect) {\n    Rectangle best_rect = rect;\n    int best_score = calculateScore(rect);\n    \n    // Try expanding/shrinking each side\n    for (int step = 1000; step >= 100; step /= 2) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            \n            // Try expanding left\n            if (rect.x1 - step >= 0) {\n                Rectangle new_rect(rect.x1 - step, rect.y1, rect.x2, rect.y2);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding right\n            if (rect.x2 + step <= MAX_COORD) {\n                Rectangle new_rect(rect.x1, rect.y1, rect.x2 + step, rect.y2);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding bottom\n            if (rect.y1 - step >= 0) {\n                Rectangle new_rect(rect.x1, rect.y1 - step, rect.x2, rect.y2);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n            \n            // Try expanding top\n            if (rect.y2 + step <= MAX_COORD) {\n                Rectangle new_rect(rect.x1, rect.y1, rect.x2, rect.y2 + step);\n                int score = calculateScore(new_rect);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = new_rect;\n                    rect = new_rect;\n                    improved = true;\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\nvector<pair<int, int>> rectangleToPolygon(const Rectangle& rect) {\n    vector<pair<int, int>> polygon;\n    polygon.push_back({rect.x1, rect.y1});\n    polygon.push_back({rect.x2, rect.y1});\n    polygon.push_back({rect.x2, rect.y2});\n    polygon.push_back({rect.x1, rect.y2});\n    return polygon;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    points.reserve(2 * N);\n    mackerels.reserve(N);\n    sardines.reserve(N);\n    \n    // Read mackerels\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, true);\n        points.push_back(p);\n        mackerels.push_back(p);\n    }\n    \n    // Read sardines\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, false);\n        points.push_back(p);\n        sardines.push_back(p);\n    }\n    \n    // Build grid for faster approximation\n    buildGrid();\n    \n    // Find best rectangle\n    Rectangle best_rect = findBestRectangle();\n    \n    // Optimize it\n    if (best_rect.isValid()) {\n        best_rect = optimizeRectangle(best_rect);\n    }\n    \n    // If no good rectangle found, fallback to bounding box of mackerels\n    if (calculateScore(best_rect) == 0) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        int pad = 500;\n        best_rect = Rectangle(\n            max(0, min_x - pad),\n            max(0, min_y - pad),\n            min(MAX_COORD, max_x + pad),\n            min(MAX_COORD, max_y + pad)\n        );\n    }\n    \n    // Convert to polygon\n    auto polygon = rectangleToPolygon(best_rect);\n    \n    // Output result\n    cout << polygon.size() << \"\\n\";\n    for (const auto& vertex : polygon) {\n        cout << vertex.first << \" \" << vertex.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random number generator\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Utility functions\ninline double random_double() {\n    return uniform_real_distribution<double>(0, 1)(rng);\n}\n\ninline int random_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rectangle {\n    int w, h;\n    int idx;\n    \n    Rectangle() : w(0), h(0), idx(0) {}\n    Rectangle(int _w, int _h, int _idx) : w(_w), h(_h), idx(_idx) {}\n    \n    long long area() const { return 1LL * w * h; }\n    int perimeter() const { return w + h; }\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n    \n    Placement(int _p, int _r, char _d, int _b) : p(_p), r(_r), d(_d), b(_b) {}\n};\n\nclass Packer {\nprivate:\n    int N, T, sigma;\n    vector<Rectangle> rectangles;\n    \npublic:\n    Packer() {\n        cin >> N >> T >> sigma;\n        rectangles.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            int w, h;\n            cin >> w >> h;\n            rectangles[i] = Rectangle(w, h, i);\n        }\n    }\n    \n    // Select first k rectangles (0 to k-1)\n    vector<int> selectFirst(int count) {\n        vector<int> selected;\n        count = min(count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(i);\n        }\n        return selected;\n    }\n    \n    // Simple placement strategy\n    vector<Placement> simplePacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle at origin\n        placements.emplace_back(selected_indices[0], random_int(0, 1), 'U', -1);\n        \n        // For remaining rectangles, place them sequentially\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            char dir = (random_int(0, 1) == 0) ? 'U' : 'L';\n            int base = random_int(-1, i - 1);\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Improved packing strategy\n    vector<Placement> improvedPacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle\n        placements.emplace_back(selected_indices[0], random_int(0, 1), 'U', -1);\n        \n        // Try to build more compact structure\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            \n            // Prefer to attach to recent placements\n            char dir = (random_double() < 0.7) ? 'U' : 'L';\n            int base = random_int(-1, min(i - 1, max(1, i/2)));\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    void run() {\n        for (int t = 0; t < T; t++) {\n            vector<Placement> best_placement;\n            \n            // Cycle through different strategies\n            int strategy = t % 4;\n            \n            switch (strategy) {\n                case 0: {\n                    // Use first half of rectangles\n                    int count = max(N/2, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = simplePacking(selected);\n                    break;\n                }\n                case 1: {\n                    // Use first 3/4 of rectangles\n                    int count = max(3*N/4, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = improvedPacking(selected);\n                    break;\n                }\n                case 2: {\n                    // Use all rectangles\n                    vector<int> selected = selectFirst(N);\n                    best_placement = simplePacking(selected);\n                    break;\n                }\n                case 3: {\n                    // Use first 1/4 of rectangles\n                    int count = max(N/4, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = improvedPacking(selected);\n                    break;\n                }\n            }\n            \n            // Ensure we always have at least one rectangle\n            if (best_placement.empty()) {\n                vector<int> single = {0};\n                best_placement = simplePacking(single);\n            }\n            \n            // Output placement\n            cout << best_placement.size() << \"\\n\";\n            for (const auto& p : best_placement) {\n                cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n            }\n            cout.flush();\n            \n            // Read measurement result\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.run();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int MAXH = 10;\n\nint N, M, H;\nvector<int> beauty;\nvector<vector<int>> adj;\nvector<pair<int, int>> coords;\nvector<int> parent;\n\n// Strategy 1: High beauty first with smart expansion\nvoid solve_strategy1() {\n    vector<int> temp_parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Create priority queue with beauty values\n    priority_queue<pair<int, int>> pq;\n    for (int i = 0; i < N; i++) {\n        pq.push({beauty[i], i});\n    }\n    \n    while (!pq.empty()) {\n        int root = -1;\n        while (!pq.empty()) {\n            auto [b, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        temp_parent[root] = -1;\n        \n        // Build tree level by level\n        vector<vector<int>> levels(H + 1);\n        levels[0].push_back(root);\n        \n        for (int level = 0; level < H; level++) {\n            // Collect candidates with scoring function\n            vector<tuple<double, int, int>> candidates;\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Scoring: beauty divided by level penalty, plus connectivity bonus\n                        double score = (double)beauty[v] / sqrt(level + 2.0);\n                        // Bonus for vertices with more connections to unassigned nodes\n                        int unassigned_neighbors = 0;\n                        for (int w : adj[v]) {\n                            if (!assigned[w]) unassigned_neighbors++;\n                        }\n                        score += unassigned_neighbors * 0.5; // Connectivity bonus\n                        \n                        candidates.push_back({score, v, u});\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), greater<tuple<double, int, int>>());\n            \n            // Add top candidates with adaptive width\n            int max_add = min(35, max(15, 50 - level * 3)); // Wider trees early, narrower later\n            \n            int added = 0;\n            for (const auto& [score, vertex, parent_vertex] : candidates) {\n                if (added >= max_add) break;\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    temp_parent[vertex] = parent_vertex;\n                    levels[level + 1].push_back(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n    \n    parent = temp_parent;\n}\n\n// Strategy 2: Degree-based approach\nvoid solve_strategy2() {\n    vector<int> temp_parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Calculate combined score: beauty * degree\n    priority_queue<pair<long long, int>> pq; // {beauty * degree, vertex}\n    for (int i = 0; i < N; i++) {\n        long long score = (long long)beauty[i] * adj[i].size();\n        pq.push({score, i});\n    }\n    \n    while (!pq.empty()) {\n        int root = -1;\n        while (!pq.empty()) {\n            auto [score, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        temp_parent[root] = -1;\n        \n        // Build tree with level-aware expansion\n        vector<vector<int>> levels(H + 1);\n        levels[0].push_back(root);\n        \n        for (int level = 0; level < H; level++) {\n            vector<tuple<long long, int, int>> candidates; // {score, vertex, parent}\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Comprehensive scoring function\n                        long long base_score = (long long)beauty[v] * 1000LL;\n                        \n                        // Level preference (earlier levels preferred)\n                        base_score += (long long)(H - level) * 20LL;\n                        \n                        // Expansion potential bonus\n                        int expand_potential = 0;\n                        for (int w : adj[v]) {\n                            if (!assigned[w]) expand_potential++;\n                        }\n                        base_score += expand_potential * 15LL;\n                        \n                        // Degree bonus\n                        base_score += adj[v].size() * 5LL;\n                        \n                        candidates.push_back({base_score, v, u});\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), greater<tuple<long long, int, int>>());\n            \n            // Adaptive selection based on level\n            int quota = 0;\n            if (level == 0) quota = 40;\n            else if (level == 1) quota = 30;\n            else if (level == 2) quota = 25;\n            else quota = 20;\n            \n            int added = 0;\n            for (const auto& [score, vertex, parent_vertex] : candidates) {\n                if (added >= quota) break;\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    temp_parent[vertex] = parent_vertex;\n                    levels[level + 1].push_back(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n    \n    // Adopt this solution if it's better\n    vector<int> level_current(N, -1);\n    for (int i = 0; i < N; i++) {\n        if (parent[i] == -1) level_current[i] = 0;\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (level_current[i] == 0) q.push(i);\n    }\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (parent[v] == u && level_current[v] == -1 && level_current[u] < H) {\n                level_current[v] = level_current[u] + 1;\n                q.push(v);\n            }\n        }\n    }\n    \n    long long current_score = 0;\n    for (int i = 0; i < N; i++) {\n        if (level_current[i] != -1) {\n            current_score += (long long)(level_current[i] + 1) * beauty[i];\n        }\n    }\n    \n    // Score new solution\n    vector<int> level_new(N, -1);\n    for (int i = 0; i < N; i++) {\n        if (temp_parent[i] == -1) level_new[i] = 0;\n    }\n    \n    queue<int> q2;\n    for (int i = 0; i < N; i++) {\n        if (level_new[i] == 0) q2.push(i);\n    }\n    \n    while (!q2.empty()) {\n        int u = q2.front(); q2.pop();\n        for (int v : adj[u]) {\n            if (temp_parent[v] == u && level_new[v] == -1 && level_new[u] < H) {\n                level_new[v] = level_new[u] + 1;\n                q2.push(v);\n            }\n        }\n    }\n    \n    long long new_score = 0;\n    for (int i = 0; i < N; i++) {\n        if (level_new[i] != -1) {\n            new_score += (long long)(level_new[i] + 1) * beauty[i];\n        }\n    }\n    \n    if (new_score > current_score) {\n        parent = temp_parent;\n    }\n}\n\n// Simple local improvement: try swapping parents for better vertices\nvoid simple_local_improvement() {\n    // For each vertex, see if moving it to a better parent helps\n    for (int v = 0; v < N; v++) {\n        if (parent[v] == -1) continue; // Skip roots\n        \n        int current_parent = parent[v];\n        long long current_contribution = 0;\n        \n        // Calculate current contribution through BFS\n        vector<int> current_level(N, -1);\n        for (int i = 0; i < N; i++) {\n            if (parent[i] == -1) current_level[i] = 0;\n        }\n        \n        queue<int> q;\n        for (int i = 0; i < N; i++) {\n            if (current_level[i] == 0) q.push(i);\n        }\n        \n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int w : adj[u]) {\n                if (parent[w] == u && current_level[w] == -1 && current_level[u] < H) {\n                    current_level[w] = current_level[u] + 1;\n                    q.push(w);\n                }\n            }\n        }\n        \n        current_contribution = (long long)(current_level[v] + 1) * beauty[v];\n        \n        // Try each neighbor as a new parent\n        for (int new_parent : adj[v]) {\n            if (new_parent == current_parent) continue;\n            \n            parent[v] = new_parent;\n            \n            // Check validity quickly\n            vector<int> new_level(N, -1);\n            vector<int> in_degree(N, 0);\n            for (int i = 0; i < N; i++) {\n                if (parent[i] != -1) {\n                    in_degree[parent[i]]++;\n                }\n            }\n            \n            // Simple cycle check would be complex, so just revert for now\n            parent[v] = current_parent;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> H;\n    \n    beauty.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> beauty[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Start with strategy 1\n    solve_strategy1();\n    \n    // Try strategy 2 and keep better solution\n    solve_strategy2();\n    \n    // Apply simple local improvement\n    simple_local_improvement();\n    \n    for (int i = 0; i < N; i++) {\n        cout << parent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nstruct OniInfo {\n    int row, col;\n    char direction;\n    int moves;\n};\n\n// Check if column j has any Fukunokami above row i\nbool hasFukuAbove(const vector<vector<char>>& board, int i, int j) {\n    for (int r = 0; r < i; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if column j has any Fukunokami below row i\nbool hasFukuBelow(const vector<vector<char>>& board, int i, int j) {\n    for (int r = i + 1; r < N; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the left of column j\nbool hasFukuLeft(const vector<vector<char>>& board, int i, int j) {\n    for (int c = 0; c < j; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the right of column j\nbool hasFukuRight(const vector<vector<char>>& board, int i, int j) {\n    for (int c = j + 1; c < N; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<char>> board(N, vector<char>(N));\n    vector<pair<int, int>> oniPositions;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            board[i][j] = line[j];\n            if (line[j] == 'x') {\n                oniPositions.push_back({i, j});\n            }\n        }\n    }\n    \n    vector<pair<char, int>> moves;\n    \n    // Strategy: Process rows and columns to remove all Oni\n    // First, let's group Oni by their positions\n    \n    // Count Oni in each row and column\n    vector<int> oniInRow(N, 0), oniInCol(N, 0);\n    for (const auto& pos : oniPositions) {\n        oniInRow[pos.first]++;\n        oniInCol[pos.second]++;\n    }\n    \n    // For each row, determine if it's better to shift left or right\n    for (int i = 0; i < N; i++) {\n        if (oniInRow[i] == 0) continue;\n        \n        // Check if we can safely shift left or right in this row\n        bool canShiftLeft = true, canShiftRight = true;\n        \n        // Check left: ensure no Fukunokami to the left of any Oni in this row\n        for (const auto& pos : oniPositions) {\n            if (pos.first == i) { // This Oni is in row i\n                if (hasFukuLeft(board, i, pos.second)) {\n                    canShiftLeft = false;\n                    break;\n                }\n            }\n        }\n        \n        // Check right: ensure no Fukunokami to the right of any Oni in this row\n        for (const auto& pos : oniPositions) {\n            if (pos.first == i) { // This Oni is in row i\n                if (hasFukuRight(board, i, pos.second)) {\n                    canShiftRight = false;\n                    break;\n                }\n            }\n        }\n        \n        // If we can shift in either direction, choose the one that moves fewer pieces off the board\n        if (canShiftLeft || canShiftRight) {\n            if (canShiftLeft && canShiftRight) {\n                // Choose direction that requires fewer moves for the furthest Oni\n                int maxLeftMoves = 0, maxRightMoves = 0;\n                for (const auto& pos : oniPositions) {\n                    if (pos.first == i) {\n                        maxLeftMoves = max(maxLeftMoves, pos.second);\n                        maxRightMoves = max(maxRightMoves, N - 1 - pos.second);\n                    }\n                }\n                if (maxLeftMoves <= maxRightMoves) {\n                    // Shift left\n                    for (int k = 0; k < maxLeftMoves; k++) {\n                        moves.push_back({'L', i});\n                    }\n                    for (int k = 0; k < maxLeftMoves; k++) {\n                        moves.push_back({'R', i});\n                    }\n                } else {\n                    // Shift right\n                    for (int k = 0; k < maxRightMoves; k++) {\n                        moves.push_back({'R', i});\n                    }\n                    for (int k = 0; k < maxRightMoves; k++) {\n                        moves.push_back({'L', i});\n                    }\n                }\n            } else if (canShiftLeft) {\n                // Shift left\n                int maxLeftMoves = 0;\n                for (const auto& pos : oniPositions) {\n                    if (pos.first == i) {\n                        maxLeftMoves = max(maxLeftMoves, pos.second);\n                    }\n                }\n                for (int k = 0; k < maxLeftMoves; k++) {\n                    moves.push_back({'L', i});\n                }\n                for (int k = 0; k < maxLeftMoves; k++) {\n                    moves.push_back({'R', i});\n                }\n            } else if (canShiftRight) {\n                // Shift right\n                int maxRightMoves = 0;\n                for (const auto& pos : oniPositions) {\n                    if (pos.first == i) {\n                        maxRightMoves = max(maxRightMoves, N - 1 - pos.second);\n                    }\n                }\n                for (int k = 0; k < maxRightMoves; k++) {\n                    moves.push_back({'R', i});\n                }\n                for (int k = 0; k < maxRightMoves; k++) {\n                    moves.push_back({'L', i});\n                }\n            }\n        }\n    }\n    \n    // For each column, determine if it's better to shift up or down\n    for (int j = 0; j < N; j++) {\n        if (oniInCol[j] == 0) continue;\n        \n        // Check if we can safely shift up or down in this column\n        bool canShiftUp = true, canShiftDown = true;\n        \n        // Check up: ensure no Fukunokami above any Oni in this column\n        for (const auto& pos : oniPositions) {\n            if (pos.second == j) { // This Oni is in column j\n                if (hasFukuAbove(board, pos.first, j)) {\n                    canShiftUp = false;\n                    break;\n                }\n            }\n        }\n        \n        // Check down: ensure no Fukunokami below any Oni in this column\n        for (const auto& pos : oniPositions) {\n            if (pos.second == j) { // This Oni is in column j\n                if (hasFukuBelow(board, pos.first, j)) {\n                    canShiftDown = false;\n                    break;\n                }\n            }\n        }\n        \n        // If we can shift in either direction, choose the one that moves fewer pieces off the board\n        if (canShiftUp || canShiftDown) {\n            if (canShiftUp && canShiftDown) {\n                // Choose direction that requires fewer moves for the furthest Oni\n                int maxUpMoves = 0, maxDownMoves = 0;\n                for (const auto& pos : oniPositions) {\n                    if (pos.second == j) {\n                        maxUpMoves = max(maxUpMoves, pos.first);\n                        maxDownMoves = max(maxDownMoves, N - 1 - pos.first);\n                    }\n                }\n                if (maxUpMoves <= maxDownMoves) {\n                    // Shift up\n                    for (int k = 0; k < maxUpMoves; k++) {\n                        moves.push_back({'U', j});\n                    }\n                    for (int k = 0; k < maxUpMoves; k++) {\n                        moves.push_back({'D', j});\n                    }\n                } else {\n                    // Shift down\n                    for (int k = 0; k < maxDownMoves; k++) {\n                        moves.push_back({'D', j});\n                    }\n                    for (int k = 0; k < maxDownMoves; k++) {\n                        moves.push_back({'U', j});\n                    }\n                }\n            } else if (canShiftUp) {\n                // Shift up\n                int maxUpMoves = 0;\n                for (const auto& pos : oniPositions) {\n                    if (pos.second == j) {\n                        maxUpMoves = max(maxUpMoves, pos.first);\n                    }\n                }\n                for (int k = 0; k < maxUpMoves; k++) {\n                    moves.push_back({'U', j});\n                }\n                for (int k = 0; k < maxUpMoves; k++) {\n                    moves.push_back({'D', j});\n                }\n            } else if (canShiftDown) {\n                // Shift down\n                int maxDownMoves = 0;\n                for (const auto& pos : oniPositions) {\n                    if (pos.second == j) {\n                        maxDownMoves = max(maxDownMoves, N - 1 - pos.first);\n                    }\n                }\n                for (int k = 0; k < maxDownMoves; k++) {\n                    moves.push_back({'D', j});\n                }\n                for (int k = 0; k < maxDownMoves; k++) {\n                    moves.push_back({'U', j});\n                }\n            }\n        }\n    }\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint target[N];\nint a[N], b[N];\n\n// Ultra-fast error estimation without full simulation\nlong long estimate_error() {\n    // Very simple estimation: just run a short simulation\n    // and extrapolate - but this is still too slow\n    \n    // Instead, let's use a completely different approach:\n    // Make a greedy assignment based on targets\n    \n    return 0;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(42); // Fixed seed for reproducibility\n    \n    int dummy_L, L;\n    cin >> dummy_L >> L;\n    for (int i = 0; i < N; i++) {\n        cin >> target[i];\n    }\n    \n    // Simple but effective strategy:\n    // Create a structure where employees with higher targets \n    // are pointed to more frequently\n    \n    // Sort employees by target (descending)\n    vector<pair<int, int>> targets;\n    for (int i = 0; i < N; i++) {\n        targets.push_back({target[i], i});\n    }\n    sort(targets.begin(), targets.end(), greater<pair<int, int>>());\n    \n    // Create a more balanced assignment\n    // High target employees should appear in many transitions\n    \n    // Simple ring structure first\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    \n    // Now adjust to favor high-target employees\n    // Make sure top employees are pointed to frequently\n    for (int i = 0; i < min(20, N); i++) {\n        int favored = targets[i].second;\n        // Point several random employees to this favored one\n        for (int j = 0; j < 3; j++) {\n            int from = rand() % N;\n            if (rand() % 2) {\n                a[from] = favored;\n            } else {\n                b[from] = favored;\n            }\n        }\n    }\n    \n    // Ensure connectivity - avoid dead ends\n    for (int i = 0; i < N; i++) {\n        if (a[i] < 0 || a[i] >= N) a[i] = 0;\n        if (b[i] < 0 || b[i] >= N) b[i] = 0;\n    }\n    \n    // Output result\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\nconst int N = 800;\nconst int MAX_Q = 400;\nconst int MAX_L = 15;\n\nint n, m, q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<pair<long long, long long>> centers;\nvector<vector<int>> groups;\nint queries_used = 0;\n\n// Query function with proper count tracking\nvector<pair<int, int>> query(const vector<int>& cities) {\n    if (queries_used >= q) {\n        return {}; // Don't make more queries than allowed\n    }\n    \n    if (cities.size() < 2 || cities.size() > L) {\n        return {};\n    }\n    \n    cout << \"? \" << cities.size();\n    for (int city : cities) {\n        cout << \" \" << city;\n    }\n    cout << endl;\n    cout.flush();\n    \n    queries_used++;\n    \n    vector<pair<int, int>> result;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        if (u > v) swap(u, v);\n        result.push_back({u, v});\n    }\n    \n    return result;\n}\n\n// Calculate squared distance between centers (to avoid floating point)\nlong long calc_center_distance_sq(int i, int j) {\n    long long cx1 = lx[i] + rx[i]; // Using sum to avoid division\n    long long cy1 = ly[i] + ry[i];\n    long long cx2 = lx[j] + rx[j];\n    long long cy2 = ly[j] + ry[j];\n    return (cx1 - cx2) * (cx1 - cx2) + (cy1 - cy2) * (cy1 - cy2);\n}\n\n// Spatial clustering using a greedy approach\nvoid spatial_clustering() {\n    // Calculate centers\n    centers.clear();\n    for (int i = 0; i < n; i++) {\n        long long cx = (long long)(lx[i] + rx[i]);\n        long long cy = (long long)(ly[i] + ry[i]);\n        centers.push_back({cx, cy});\n    }\n    \n    // Initialize groups\n    groups.clear();\n    groups.resize(m);\n    \n    // Create list of all cities with their indices\n    vector<int> cities(n);\n    iota(cities.begin(), cities.end(), 0);\n    \n    // Shuffle cities to avoid bias\n    random_shuffle(cities.begin(), cities.end());\n    \n    // Assign first M cities, one to each group\n    for (int i = 0; i < min(m, n); i++) {\n        groups[i].push_back(cities[i]);\n    }\n    \n    // Assign remaining cities to the group whose current members are closest on average\n    for (int i = m; i < n; i++) {\n        int city_idx = cities[i];\n        int best_group = 0;\n        long long best_score = 1e18;\n        \n        // Find the group that minimizes average distance to this city\n        for (int g = 0; g < m; g++) {\n            if (groups[g].empty()) {\n                best_group = g;\n                break;\n            }\n            \n            long long total_dist = 0;\n            for (int member : groups[g]) {\n                total_dist += calc_center_distance_sq(city_idx, member);\n            }\n            long long avg_dist = total_dist / groups[g].size();\n            \n            if (avg_dist < best_score) {\n                best_score = avg_dist;\n                best_group = g;\n            }\n        }\n        \n        // Check if this group still needs more members\n        if ((int)groups[best_group].size() < G[best_group]) {\n            groups[best_group].push_back(city_idx);\n        } else {\n            // Find a group that still needs members\n            for (int g = 0; g < m; g++) {\n                if ((int)groups[g].size() < G[g]) {\n                    groups[g].push_back(city_idx);\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Fix any groups that don't have the right size (shouldn't happen with correct logic)\n    // This is a safety net\n    vector<int> unassigned;\n    for (int g = 0; g < m; g++) {\n        while ((int)groups[g].size() > G[g]) {\n            unassigned.push_back(groups[g].back());\n            groups[g].pop_back();\n        }\n    }\n    \n    for (int g = 0; g < m && !unassigned.empty(); g++) {\n        while ((int)groups[g].size() < G[g] && !unassigned.empty()) {\n            groups[g].push_back(unassigned.back());\n            unassigned.pop_back();\n        }\n    }\n}\n\n// Use queries strategically\nvoid strategic_querying() {\n    // First, query small groups entirely if possible\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= 1) continue;\n        \n        // If group size is small enough, query the whole group\n        if (G[i] <= L) {\n            query(groups[i]);\n            if (queries_used >= q) return;\n        }\n    }\n    \n    // For larger groups, do strategic querying\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= L) continue; // Already handled above\n        if (G[i] <= 1) continue;\n        \n        // Query overlapping windows to build better connectivity information\n        int window_size = min(L, G[i]);\n        int step = max(1, window_size - 1);\n        \n        for (int start = 0; start < G[i] - 1 && queries_used < q; start += step) {\n            int end = min(start + window_size, G[i]);\n            vector<int> subset;\n            for (int j = start; j < end; j++) {\n                subset.push_back(groups[i][j]);\n            }\n            \n            if (subset.size() >= 2) {\n                query(subset);\n            }\n            \n            if (queries_used >= q) break;\n        }\n        \n        if (queries_used >= q) break;\n    }\n    \n    // Use remaining queries for cross-validation or boundary detection\n    // Query triplets at boundaries of groups to improve connectivity\n    for (int i = 0; i < m && queries_used < q - 2; i++) {\n        if (G[i] <= 2) continue;\n        \n        // Query first few cities\n        vector<int> start_subset;\n        int end_start = min(3, G[i]);\n        for (int j = 0; j < end_start; j++) {\n            start_subset.push_back(groups[i][j]);\n        }\n        if (start_subset.size() >= 2) {\n            query(start_subset);\n        }\n        if (queries_used >= q) break;\n        \n        // Query last few cities\n        vector<int> end_subset;\n        int start_end = max(0, G[i] - 3);\n        for (int j = start_end; j < G[i]; j++) {\n            end_subset.push_back(groups[i][j]);\n        }\n        if (end_subset.size() >= 2) {\n            query(end_subset);\n        }\n        if (queries_used >= q) break;\n    }\n}\n\n// Improved MST building using Union-Find for better approximation\nclass UnionFind {\nprivate:\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]); // Path compression\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int root_x = find(x);\n        int root_y = find(y);\n        \n        if (root_x == root_y) return false;\n        \n        // Union by rank\n        if (rank[root_x] < rank[root_y]) {\n            swap(root_x, root_y);\n        }\n        parent[root_y] = root_x;\n        if (rank[root_x] == rank[root_y]) {\n            rank[root_x]++;\n        }\n        return true;\n    }\n};\n\n// Build MST for group with better approximation\nvector<pair<int, int>> build_group_mst(const vector<int>& group) {\n    if (group.size() <= 1) return {};\n    \n    // If we can query the entire group and still have queries left\n    if ((int)group.size() <= L && queries_used < q) {\n        return query(group);\n    }\n    \n    // Otherwise, build approximate MST using center distances\n    vector<tuple<long long, int, int>> edges;\n    \n    // Generate all possible edges with their approximate weights\n    for (int i = 0; i < (int)group.size(); i++) {\n        for (int j = i + 1; j < (int)group.size(); j++) {\n            long long dist = calc_center_distance_sq(group[i], group[j]);\n            edges.push_back({dist, group[i], group[j]});\n        }\n    }\n    \n    // Sort edges by weight\n    sort(edges.begin(), edges.end());\n    \n    // Kruskal's algorithm\n    UnionFind uf(n);\n    vector<pair<int, int>> mst;\n    \n    for (const auto& edge : edges) {\n        long long weight;\n        int u, v;\n        tie(weight, u, v) = edge;\n        \n        if (uf.unite(u, v)) {\n            mst.push_back({min(u, v), max(u, v)});\n            if ((int)mst.size() == (int)group.size() - 1) break;\n        }\n    }\n    \n    return mst;\n}\n\n// Build MSTs for all groups\nvector<vector<pair<int, int>>> build_all_msts() {\n    vector<vector<pair<int, int>>> result(m);\n    \n    for (int i = 0; i < m; i++) {\n        result[i] = build_group_mst(groups[i]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // For reproducibility\n    srand(42);\n    \n    // Read input\n    cin >> n >> m >> q >> L >> W;\n    G.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> G[i];\n    }\n    \n    lx.resize(n);\n    rx.resize(n);\n    ly.resize(n);\n    ry.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Perform spatial clustering\n    spatial_clustering();\n    \n    // Strategic querying\n    strategic_querying();\n    \n    // Build MSTs for final answer\n    vector<vector<pair<int, int>>> msts = build_all_msts();\n    \n    // Output final answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            cout << groups[i][j];\n            if (j < (int)groups[i].size() - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n        \n        for (const auto& edge : msts[i]) {\n            cout << edge.first << \" \" << edge.second << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int _x, int _y) : x(_x), y(_y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass SkatingSolver {\nprivate:\n    int grid[N][N]; // 0 = empty, 1 = block\n    Point pos;\n    vector<Point> targets;\n    vector<string> actions;\n    \npublic:\n    SkatingSolver() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        int n, m;\n        cin >> n >> m;\n        int x, y;\n        cin >> x >> y;\n        pos = Point(x, y);\n        \n        targets.resize(m);\n        for (int i = 0; i < m; i++) {\n            cin >> targets[i].x >> targets[i].y;\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void add_action(char action, char direction) {\n        actions.push_back(string(1, action) + \" \" + string(1, direction));\n    }\n    \n    // Move one step in given direction\n    bool move(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (!is_valid(nx, ny) || grid[nx][ny] == 1) {\n            return false;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('M', dir_chars[dir]);\n        return true;\n    }\n    \n    // Slide until hitting a block or boundary\n    void slide(int dir) {\n        int nx = pos.x, ny = pos.y;\n        \n        while (true) {\n            int tx = nx + dx[dir];\n            int ty = ny + dy[dir];\n            \n            if (!is_valid(tx, ty) || grid[tx][ty] == 1) {\n                break;\n            }\n            \n            nx = tx;\n            ny = ty;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('S', dir_chars[dir]);\n    }\n    \n    // Place or remove block\n    void alter(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            grid[nx][ny] = 1 - grid[nx][ny];\n        }\n        \n        add_action('A', dir_chars[dir]);\n    }\n    \n    // Find direction from point a to point b\n    int get_direction(Point a, Point b) {\n        if (a.x > b.x) return 0; // U\n        if (a.x < b.x) return 1; // D\n        if (a.y > b.y) return 2; // L\n        if (a.y < b.y) return 3; // R\n        return -1; // Same position\n    }\n    \n    // Manhattan distance\n    int manhattan_distance(Point a, Point b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Simple path finding using moves only\n    void move_to_target(Point target) {\n        // Use greedy approach - move in the direction that reduces distance\n        for (int step = 0; step < 1000 && !(pos == target); step++) {\n            int best_dir = -1;\n            int min_dist = manhattan_distance(pos, target);\n            \n            // Try all directions\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = pos.x + dx[dir];\n                int ny = pos.y + dy[dir];\n                \n                if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                    int dist = abs(nx - target.x) + abs(ny - target.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_dir = dir;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                move(best_dir);\n            } else {\n                // If stuck, try any valid move\n                bool moved = false;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (move(dir)) {\n                        moved = true;\n                        break;\n                    }\n                }\n                if (!moved) break;\n            }\n        }\n    }\n    \n    // Enhanced strategy using slides when possible\n    void smart_move_to_target(Point target) {\n        if (pos == target) return;\n        \n        // If in same row or column, consider sliding\n        if (pos.x == target.x || pos.y == target.y) {\n            int dir = get_direction(pos, target);\n            if (dir != -1) {\n                // Check if we can slide directly\n                bool can_slide_directly = true;\n                Point temp_pos = pos;\n                \n                while (!(temp_pos == target)) {\n                    int nx = temp_pos.x + dx[dir];\n                    int ny = temp_pos.y + dy[dir];\n                    \n                    if (!is_valid(nx, ny)) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    if (grid[nx][ny] == 1) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    temp_pos.x = nx;\n                    temp_pos.y = ny;\n                }\n                \n                if (can_slide_directly) {\n                    slide(dir);\n                    return;\n                }\n            }\n        }\n        \n        // Otherwise use regular move-to-target\n        move_to_target(target);\n    }\n    \n    void solve() {\n        // Visit each target in order\n        for (int i = 1; i < (int)targets.size(); i++) {\n            // If target has a block, remove it first\n            if (grid[targets[i].x][targets[i].y] == 1) {\n                // Find adjacent empty spot to remove block\n                for (int dir = 0; dir < 4; dir++) {\n                    int nx = targets[i].x + dx[dir];\n                    int ny = targets[i].y + dy[dir];\n                    \n                    if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                        // Move to adjacent position and remove block\n                        Point adj_pos(nx, ny);\n                        \n                        // Move to adjacent position\n                        move_to_target(adj_pos);\n                        \n                        // Remove block (opposite direction)\n                        int opposite_dir = (dir == 0) ? 1 : (dir == 1) ? 0 : (dir == 2) ? 3 : 2;\n                        alter(opposite_dir);\n                        break;\n                    }\n                }\n            }\n            \n            // Move to target\n            smart_move_to_target(targets[i]);\n        }\n    }\n    \n    void print_solution() {\n        for (const string& action : actions) {\n            cout << action << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    SkatingSolver solver;\n    solver.read_input();\n    solver.solve();\n    solver.print_solution();\n    \n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int id, x, y, r;\n};\n\nstruct Rectangle {\n    int a, b, c, d; // (a,b) to (c,d) where a<c and b<d\n};\n\nconst int SIZE = 10000;\nvector<Rectangle> rectangles;\nvector<Company> companies;\n\n// Check if two rectangles overlap (touching edges is OK)\nbool overlap(int a1, int b1, int c1, int d1, int a2, int b2, int c2, int d2) {\n    return !(c1 <= a2 || c2 <= a1 || d1 <= b2 || d2 <= b1);\n}\n\n// Check if rectangle overlaps with existing rectangles\nbool has_overlap(int a, int b, int c, int d) {\n    for (const auto& rect : rectangles) {\n        if (rect.a != -1) {\n            if (overlap(a, b, c, d, rect.a, rect.b, rect.c, rect.d)) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Find reasonable factors of area (optimized)\nvector<pair<int, int>> get_factors(int area) {\n    vector<pair<int, int>> factors;\n    \n    // More comprehensive but still limited factor search\n    int limit = min(120, (int)sqrt(area) + 40);\n    \n    for (int w = 1; w <= min(limit, area); w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            if (h <= SIZE) {\n                factors.push_back({w, h});\n                if (w != h && h <= limit && w <= SIZE) {\n                    factors.push_back({h, w});\n                }\n            }\n        }\n    }\n    \n    // Sort by how square-like (but not too aggressively)\n    sort(factors.begin(), factors.end(), [](const pair<int,int>& a, const pair<int,int>& b) {\n        int diff_a = abs(a.first - a.second);\n        int diff_b = abs(b.first - b.second);\n        return diff_a < diff_b;\n    });\n    \n    // Remove duplicates and limit\n    factors.erase(unique(factors.begin(), factors.end()), factors.end());\n    \n    if (factors.size() > 30) {\n        factors.resize(30);\n    }\n    \n    return factors;\n}\n\n// Try to place rectangle for company - optimized\nbool place_company(const Company& comp) {\n    int target_x = comp.x;\n    int target_y = comp.y;\n    int area = comp.r;\n    \n    auto factors = get_factors(area);\n    \n    // Try exact area with adaptive search\n    for (auto& factor : factors) {\n        int w = factor.first;\n        int h = factor.second;\n        \n        // Adaptive search window based on rectangle size\n        int base_search = min(25, max(8, min(w, h) / 3));\n        int search_limit = min(base_search, max(10, abs(target_x - SIZE/2) / 100 + abs(target_y - SIZE/2) / 100 + 5));\n        \n        int center_a = target_x - w/2;\n        int center_b = target_y - h/2;\n        \n        // Spiral search pattern for better coverage\n        for (int radius = 0; radius <= search_limit; radius++) {\n            for (int dx = -radius; dx <= radius; dx++) {\n                int dy_vals[2] = {-radius, radius};\n                if (radius == 0) dy_vals[1] = 0;\n                \n                for (int j = 0; j < (radius == 0 ? 1 : 2); j++) {\n                    int dy = dy_vals[j];\n                    int a = center_a + dx;\n                    int b = center_b + dy;\n                    int c = a + w;\n                    int d = b + h;\n                    \n                    if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                        if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                            if (!has_overlap(a, b, c, d)) {\n                                rectangles[comp.id] = {a, b, c, d};\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Also check the vertical sides of the square\n            if (radius > 0) {\n                for (int dy = -radius + 1; dy < radius; dy++) {\n                    int dx_vals[2] = {-radius, radius};\n                    for (int k = 0; k < 2; k++) {\n                        int dx = dx_vals[k];\n                        int a = center_a + dx;\n                        int b = center_b + dy;\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                            if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                if (!has_overlap(a, b, c, d)) {\n                                    rectangles[comp.id] = {a, b, c, d};\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Try approximate areas with smaller search\n    for (int delta = 1; delta <= min(25, area/150); delta++) {\n        vector<int> test_areas;\n        if (area + delta <= SIZE * SIZE) test_areas.push_back(area + delta);\n        if (area - delta > 0) test_areas.push_back(area - delta);\n        \n        for (int test_area : test_areas) {\n            auto test_factors = get_factors(test_area);\n            for (auto& factor : test_factors) {\n                int w = factor.first;\n                int h = factor.second;\n                \n                int search_limit = min(18, max(4, min(w, h) / 4));\n                int center_a = target_x - w/2;\n                int center_b = target_y - h/2;\n                \n                // Smaller search for approximate areas\n                for (int dx = -search_limit; dx <= search_limit; dx += max(1, search_limit/5)) {\n                    for (int dy = -search_limit; dy <= search_limit; dy += max(1, search_limit/5)) {\n                        int a = center_a + dx;\n                        int b = center_b + dy;\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                            if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                if (!has_overlap(a, b, c, d)) {\n                                    rectangles[comp.id] = {a, b, c, d};\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Enhanced fallback - try multiple strategies\n    // Strategy 1: Grid-based placement near target\n    for (int grid_step = 1; grid_step <= 3; grid_step++) {\n        for (int dx = -15; dx <= 15; dx += grid_step) {\n            for (int dy = -15; dy <= 15; dy += grid_step) {\n                // Try different reasonable widths\n                for (int w_factor = 1; w_factor <= 4; w_factor++) {\n                    int w = min(SIZE-1, max(1, area / (10 * w_factor)));\n                    if (area % w == 0 || w <= area) {\n                        int h = (area + w - 1) / w; // Ceiling division\n                        if (h > SIZE) {\n                            h = min(SIZE, area);\n                            w = (area + h - 1) / h;\n                        }\n                        \n                        int a = max(0, min(SIZE - w, target_x + dx));\n                        int b = max(0, min(SIZE - h, target_y + dy));\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                            if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                if (!has_overlap(a, b, c, d)) {\n                                    rectangles[comp.id] = {a, b, c, d};\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Strategy 2: Very local placement\n    for (int dx = -3; dx <= 3; dx++) {\n        for (int dy = -3; dy <= 3; dy++) {\n            int a = max(0, min(SIZE - 1, target_x + dx));\n            int b = max(0, min(SIZE - 1, target_y + dy));\n            int c = min(SIZE, a + max(1, area/100));\n            int d = min(SIZE, b + max(1, area/100));\n            a = max(0, c - (area + (d-b) - 1) / (d-b));\n            b = max(0, d - (area + (c-a) - 1) / (c-a));\n            \n            if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                    if (!has_overlap(a, b, c, d)) {\n                        rectangles[comp.id] = {a, b, c, d};\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Absolute last resort\n    rectangles[comp.id] = {0, 0, 1, 1};\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    companies.resize(n);\n    rectangles.assign(n, {-1, -1, -1, -1});\n    \n    vector<pair<int, int>> areas_indices;\n    \n    for (int i = 0; i < n; i++) {\n        companies[i].id = i;\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        areas_indices.push_back({companies[i].r, i});\n    }\n    \n    // Sort by area descending\n    sort(areas_indices.rbegin(), areas_indices.rend());\n    \n    // Place each company\n    for (const auto& area_idx : areas_indices) {\n        int idx = area_idx.second;\n        place_company(companies[idx]);\n    }\n    \n    // Output results\n    for (const auto& rect : rectangles) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SIZE = 50;\nint si, sj;\nint tile_id[SIZE][SIZE];\nint points[SIZE][SIZE];\nvector<pair<int,int>> tile_cells[2500];\nbool tile_visited[2500];\n\n// Directions: U, D, L, R\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nvoid preprocess_tiles() {\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            int tid = tile_id[i][j];\n            tile_cells[tid].push_back({i, j});\n        }\n    }\n}\n\nbool is_valid_position(int x, int y) {\n    return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n}\n\nstring solve() {\n    // Reset visited status\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int x = si, y = sj;\n    int current_tile = tile_id[x][y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    // Simple greedy approach\n    for (int step = 0; step < 2500; step++) {\n        // Find best valid move\n        int best_value = -1;\n        int best_dir = -1;\n        int best_nx = -1, best_ny = -1;\n        int best_next_tile = -1;\n        \n        // Try all 4 directions from current position\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (is_valid_position(nx, ny)) {\n                int next_tile = tile_id[nx][ny];\n                if (!tile_visited[next_tile]) {\n                    // Calculate value of this tile\n                    int tile_value = 0;\n                    for (auto& cell : tile_cells[next_tile]) {\n                        tile_value += points[cell.first][cell.second];\n                    }\n                    \n                    if (tile_value > best_value) {\n                        best_value = tile_value;\n                        best_dir = d;\n                        best_nx = nx;\n                        best_ny = ny;\n                        best_next_tile = next_tile;\n                    }\n                }\n            }\n        }\n        \n        // If no valid move, stop\n        if (best_dir == -1) {\n            break;\n        }\n        \n        // Make the move\n        path += dir_char[best_dir];\n        x = best_nx;\n        y = best_ny;\n        tile_visited[best_next_tile] = true;\n        current_tile = best_next_tile;\n    }\n    \n    return path;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> tile_id[i][j];\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess_tiles();\n    \n    string result = solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int QUERY_COUNT = 1000;\n\n// Edge weight estimates with confidence\nvector<vector<double>> h_edges; // horizontal edges (i,j) to (i,j+1)\nvector<vector<double>> v_edges; // vertical edges (i,j) to (i+1,j)\nvector<vector<double>> h_confidence; // confidence in h_edge estimates\nvector<vector<double>> v_confidence; // confidence in v_edge estimates\n\n// Count of times each edge has been used\nvector<vector<int>> h_usage_count;\nvector<vector<int>> v_usage_count;\n\n// Initialize edge weights\nvoid initialize_weights() {\n    // Better initial estimate based on problem parameters\n    h_edges.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 5000.0));\n    v_edges.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 5000.0));\n    \n    // Initialize confidence (lower means less certain)\n    h_confidence.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 1.0));\n    v_confidence.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 1.0));\n    \n    // Usage counts\n    h_usage_count.assign(GRID_SIZE, vector<int>(GRID_SIZE - 1, 0));\n    v_usage_count.assign(GRID_SIZE - 1, vector<int>(GRID_SIZE, 0));\n}\n\n// Calculate path length using current estimates\ndouble calculate_estimated_length(const vector<pair<int,int>>& path) {\n    double length = 0.0;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) {\n            length += h_edges[r1][c1];\n        } else if (r1 == r2 && c2 == c1 - 1) {\n            length += h_edges[r1][c2];\n        } else if (c1 == c2 && r2 == r1 + 1) {\n            length += v_edges[r1][c1];\n        } else if (c1 == c2 && r2 == r1 - 1) {\n            length += v_edges[r2][c1];\n        }\n    }\n    return length;\n}\n\n// Get actual length from the last query\nint get_actual_length() {\n    int actual_length;\n    cin >> actual_length;\n    return actual_length;\n}\n\n// Find shortest path using A* with current estimates and some exploration\nvector<pair<int,int>> find_shortest_path(int start_r, int start_c, int end_r, int end_c, int query_num) {\n    // For very short distances, just use Manhattan path\n    int manhattan_dist = abs(start_r - end_r) + abs(start_c - end_c);\n    if (manhattan_dist <= 10 && query_num > 100) {\n        vector<pair<int,int>> path;\n        path.push_back({start_r, start_c});\n        int r = start_r, c = start_c;\n        \n        // Move vertically first\n        while (r < end_r) {\n            r++;\n            path.push_back({r, c});\n        }\n        while (r > end_r) {\n            r--;\n            path.push_back({r, c});\n        }\n        \n        // Then horizontally\n        while (c < end_c) {\n            c++;\n            path.push_back({r, c});\n        }\n        while (c > end_c) {\n            c--;\n            path.push_back({r, c});\n        }\n        return path;\n    }\n    \n    // Priority queue: {f_score, g_score, row, col}\n    priority_queue<tuple<double, double, int, int>, vector<tuple<double, double, int, int>>, greater<>> pq;\n    \n    // Distance and parent tracking\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int,int>>> parent(GRID_SIZE, vector<pair<int,int>>(GRID_SIZE, {-1, -1}));\n    \n    auto heuristic = [&](int r, int c) {\n        return abs(r - end_r) + abs(c - end_c); // Manhattan distance\n    };\n    \n    dist[start_r][start_c] = 0;\n    pq.push({heuristic(start_r, start_c), 0.0, start_r, start_c});\n    \n    vector<pair<int,int>> directions = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // U, D, L, R\n    \n    while (!pq.empty()) {\n        auto [f_score, g_score, r, c] = pq.top();\n        pq.pop();\n        \n        if (g_score > dist[r][c]) continue;\n        \n        if (r == end_r && c == end_c) break;\n        \n        // Explore neighbors\n        for (int dir = 0; dir < 4; dir++) {\n            int dr = directions[dir].first;\n            int dc = directions[dir].second;\n            int nr = r + dr;\n            int nc = c + dc;\n            \n            // Check bounds\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            \n            double edge_cost = 0;\n            if (dr == 0 && dc == 1) { // Right\n                edge_cost = h_edges[r][c];\n            } else if (dr == 0 && dc == -1) { // Left\n                edge_cost = h_edges[r][nc];\n            } else if (dr == 1 && dc == 0) { // Down\n                edge_cost = v_edges[r][c];\n            } else if (dr == -1 && dc == 0) { // Up\n                edge_cost = v_edges[nr][c];\n            }\n            \n            // Add exploration bonus for less confident edges (early queries)\n            if (query_num < 200) {\n                double exploration_bonus = 0;\n                if (dr == 0 && dc == 1) { // Right\n                    exploration_bonus = (1.0 / (h_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 0 && dc == -1) { // Left\n                    exploration_bonus = (1.0 / (h_confidence[r][nc] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 1 && dc == 0) { // Down\n                    exploration_bonus = (1.0 / (v_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == -1 && dc == 0) { // Up\n                    exploration_bonus = (1.0 / (v_confidence[nr][c] + 1e-6)) * (200 - query_num) * 0.1;\n                }\n                edge_cost += exploration_bonus;\n            }\n            \n            double new_g_score = g_score + edge_cost;\n            if (new_g_score < dist[nr][nc]) {\n                dist[nr][nc] = new_g_score;\n                parent[nr][nc] = {r, c};\n                double f_score = new_g_score + heuristic(nr, nc);\n                pq.push({f_score, new_g_score, nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int r = end_r, c = end_c;\n    while (r != -1 && c != -1) {\n        path.push_back({r, c});\n        auto p = parent[r][c];\n        r = p.first;\n        c = p.second;\n    }\n    reverse(path.begin(), path.end());\n    \n    return path;\n}\n\n// Convert path to direction string\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r2 == r1 - 1) result += 'U';\n        else if (r2 == r1 + 1) result += 'D';\n        else if (c2 == c1 - 1) result += 'L';\n        else if (c2 == c1 + 1) result += 'R';\n    }\n    return result;\n}\n\n// Update edge weights based on actual path performance with confidence tracking\nvoid update_weights(const vector<pair<int,int>>& path, int actual_length, int query_num) {\n    if (path.size() < 2) return;\n    \n    double estimated_length = calculate_estimated_length(path);\n    double error = actual_length - estimated_length;\n    \n    // Adaptive learning rate based on query number and path length\n    double base_learning_rate = 0.3;\n    double learning_rate = base_learning_rate * exp(-0.001 * query_num);\n    \n    // Update each edge in the path\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) { // Right\n            h_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c1] += learning_rate * edge_error;\n            h_edges[r1][c1] = max(100.0, min(10000.0, h_edges[r1][c1]));\n            // Update confidence - more usage means higher confidence\n            h_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (r1 == r2 && c2 == c1 - 1) { // Left\n            h_usage_count[r1][c2]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c2] += learning_rate * edge_error;\n            h_edges[r1][c2] = max(100.0, min(10000.0, h_edges[r1][c2]));\n            h_confidence[r1][c2] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 + 1) { // Down\n            v_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r1][c1] += learning_rate * edge_error;\n            v_edges[r1][c1] = max(100.0, min(10000.0, v_edges[r1][c1]));\n            v_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 - 1) { // Up\n            v_usage_count[r2][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r2][c1] += learning_rate * edge_error;\n            v_edges[r2][c1] = max(100.0, min(10000.0, v_edges[r2][c1]));\n            v_confidence[r2][c1] += learning_rate * 10.0;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_weights();\n    \n    for (int query = 0; query < QUERY_COUNT; query++) {\n        int start_r, start_c, end_r, end_c;\n        cin >> start_r >> start_c >> end_r >> end_c;\n        \n        vector<pair<int,int>> path = find_shortest_path(start_r, start_c, end_r, end_c, query);\n        \n        string path_str = path_to_string(path);\n        cout << path_str << endl;\n        cout.flush();\n        \n        // Get actual length and update weights\n        int actual_length = get_actual_length();\n        update_weights(path, actual_length, query);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst string ALPHABET = \"ABCDEFGH\";\n\nvector<string> matrix(N, string(N, '.'));\nvector<string> strings;\nint M;\n\n// Check if string can be placed at position (r,c) in given direction\nbool canPlace(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        \n        if (matrix[nr][nc] != '.' && matrix[nr][nc] != s[i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place string at position (r,c) in given direction\nvoid placeString(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        matrix[nr][nc] = s[i];\n    }\n}\n\n// Count how many strings are currently matched\nint countMatches() {\n    int count = 0;\n    for (const string& s : strings) {\n        bool found = false;\n        \n        // Check horizontal placements\n        for (int r = 0; r < N && !found; r++) {\n            for (int c = 0; c < N && !found; c++) {\n                bool match = true;\n                for (int i = 0; i < (int)s.length(); i++) {\n                    int nc = (c + i) % N;\n                    if (matrix[r][nc] != s[i]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) {\n                    found = true;\n                }\n            }\n        }\n        \n        // Check vertical placements\n        if (!found) {\n            for (int c = 0; c < N && !found; c++) {\n                for (int r = 0; r < N && !found; r++) {\n                    bool match = true;\n                    for (int i = 0; i < (int)s.length(); i++) {\n                        int nr = (r + i) % N;\n                        if (matrix[nr][c] != s[i]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                    }\n                }\n            }\n        }\n        \n        if (found) count++;\n    }\n    return count;\n}\n\n// Try to place as many strings as possible\nvoid greedyPlacement() {\n    // Sort strings by length (longer first might be better)\n    vector<pair<int, int>> str_lengths;\n    for (int i = 0; i < M; i++) {\n        str_lengths.push_back({(int)strings[i].length(), i});\n    }\n    sort(str_lengths.rbegin(), str_lengths.rend());\n    \n    for (const auto& p : str_lengths) {\n        int idx = p.second;\n        const string& s = strings[idx];\n        \n        // Try to place this string\n        bool placed = false;\n        \n        // Try horizontal placements first\n        for (int r = 0; r < N && !placed; r++) {\n            for (int c = 0; c < N && !placed; c++) {\n                if (canPlace(s, r, c, true)) {\n                    placeString(s, r, c, true);\n                    placed = true;\n                }\n            }\n        }\n        \n        // Try vertical placements if horizontal didn't work\n        if (!placed) {\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    if (canPlace(s, r, c, false)) {\n                        placeString(s, r, c, false);\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Improve by trying to fill empty spots with valid characters\nvoid fillEmptySpots() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    // For each empty cell, try to determine the best character\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matrix[r][c] == '.') {\n                // Simple approach: pick a random valid character\n                matrix[r][c] = ALPHABET[gen() % ALPHABET.length()];\n            }\n        }\n    }\n}\n\n// Simple randomized approach\nvoid randomImprovement() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    int current_matches = countMatches();\n    \n    // Try random changes - but be more conservative\n    for (int iter = 0; iter < 500; iter++) {\n        // Pick a random cell\n        int r = gen() % N;\n        int c = gen() % N;\n        char original = matrix[r][c];\n        \n        // Try a random character\n        char new_char = ALPHABET[gen() % ALPHABET.length()];\n        matrix[r][c] = new_char;\n        \n        int new_matches = countMatches();\n        // Only accept improvements\n        if (new_matches <= current_matches) {\n            matrix[r][c] = original; // Revert\n        } else {\n            current_matches = new_matches;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> M;\n    strings.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    // Initialize matrix\n    for (int i = 0; i < N; i++) {\n        matrix[i] = string(N, '.');\n    }\n    \n    // Greedy placement\n    greedyPlacement();\n    \n    // Fill empty spots\n    fillEmptySpots();\n    \n    // Gentle improvement\n    randomImprovement();\n    \n    // Ensure all characters are valid before output\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (matrix[i][j] == '.' || ALPHABET.find(matrix[i][j]) == string::npos) {\n                matrix[i][j] = 'A'; // Fallback to 'A' if somehow invalid\n            }\n        }\n    }\n    \n    // Output result\n    for (const string& row : matrix) {\n        cout << row << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 70;\nint N, si, sj;\nchar grid[MAX_N][MAX_N];\nbool is_road[MAX_N][MAX_N];\nint cost[MAX_N][MAX_N];\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Calculate visible squares from a given position\nset<pair<int,int>> get_visible_squares(int x, int y) {\n    set<pair<int,int>> visible;\n    \n    // Horizontal visibility (same row)\n    // Left direction\n    for (int j = y; j >= 0; j--) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    // Right direction\n    for (int j = y; j < N; j++) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    \n    // Vertical visibility (same column)\n    // Up direction\n    for (int i = x; i >= 0; i--) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    // Down direction\n    for (int i = x; i < N; i++) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    \n    return visible;\n}\n\n// Check if position is valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && is_road[x][y];\n}\n\n// BFS to find shortest path between two points\nvector<char> bfs_path(int start_x, int start_y, int end_x, int end_y) {\n    if (start_x == end_x && start_y == end_y) return {};\n    \n    queue<pair<int,int>> q;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    \n    q.push({start_x, start_y});\n    visited[start_x][start_y] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            \n            if (is_valid(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = {x, y};\n                q.push({nx, ny});\n                \n                if (nx == end_x && ny == end_y) {\n                    // Reconstruct path\n                    vector<char> path;\n                    int cx = end_x, cy = end_y;\n                    \n                    while (parent[cx][cy].first != -1) {\n                        auto [px, py] = parent[cx][cy];\n                        // Determine direction from parent to current\n                        if (cx == px - 1 && cy == py) path.push_back('U');\n                        else if (cx == px + 1 && cy == py) path.push_back('D');\n                        else if (cx == px && cy == py - 1) path.push_back('L');\n                        else if (cx == px && cy == py + 1) path.push_back('R');\n                        \n                        cx = px;\n                        cy = py;\n                    }\n                    \n                    reverse(path.begin(), path.end());\n                    return path;\n                }\n            }\n        }\n    }\n    \n    return {}; // No path found\n}\n\n// Get all road positions\nvector<pair<int,int>> get_all_roads() {\n    vector<pair<int,int>> roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) {\n                roads.push_back({i, j});\n            }\n        }\n    }\n    return roads;\n}\n\n// Generate path using improved greedy coverage approach\nvector<char> generate_greedy_coverage_path() {\n    vector<char> path;\n    int current_x = si, current_y = sj;\n    \n    // Get all roads\n    auto all_roads = get_all_roads();\n    if (all_roads.empty()) return path;\n    \n    // Track covered roads\n    set<pair<int,int>> covered;\n    auto initial_visible = get_visible_squares(current_x, current_y);\n    covered.insert(initial_visible.begin(), initial_visible.end());\n    \n    // Limit iterations but allow more thorough exploration\n    int max_iterations = min(500, N * N);\n    \n    for (int iter = 0; iter < max_iterations && path.size() < 2800; iter++) {\n        // Find the position that maximizes new coverage\n        pair<int,int> best_pos = {-1, -1};\n        int best_new_coverage = -1;\n        vector<char> best_segment;\n        \n        // Sample more candidates for better selection\n        int sample_size = min(100, (int)all_roads.size());\n        vector<pair<int,int>> candidates;\n        \n        // Include strategic positions for better coverage\n        for (int k = 0; k < sample_size && k < (int)all_roads.size(); k++) {\n            int idx = (iter * 31 + k * 17) % all_roads.size();\n            candidates.push_back(all_roads[idx]);\n        }\n        \n        // Also include some grid-based systematic positions\n        for (int i = 0; i < N && (int)candidates.size() < sample_size + 30; i += max(1, N/8)) {\n            for (int j = 0; j < N && (int)candidates.size() < sample_size + 30; j += max(1, N/8)) {\n                if (is_road[i][j]) {\n                    candidates.push_back({i, j});\n                }\n            }\n        }\n        \n        // Evaluate candidates\n        for (const auto& pos : candidates) {\n            int target_x = pos.first;\n            int target_y = pos.second;\n            \n            // Skip if already at this position\n            if (target_x == current_x && target_y == current_y) continue;\n            \n            // Get path to this position\n            auto segment = bfs_path(current_x, current_y, target_x, target_y);\n            if (segment.empty() || segment.size() > 100) continue; // Avoid very long segments\n            \n            // Calculate new coverage from this position\n            auto visible = get_visible_squares(target_x, target_y);\n            int new_coverage = 0;\n            for (const auto& p : visible) {\n                if (covered.find(p) == covered.end()) {\n                    new_coverage++;\n                }\n            }\n            \n            // Prefer positions with good new coverage relative to path length\n            double efficiency = (double)new_coverage / (segment.size() + 1);\n            if (new_coverage > best_new_coverage || \n                (new_coverage == best_new_coverage && efficiency > (double)best_new_coverage / (best_segment.size() + 1))) {\n                best_new_coverage = new_coverage;\n                best_pos = {target_x, target_y};\n                best_segment = segment;\n            }\n        }\n        \n        // If no good position found and we have good coverage, consider finishing\n        if (best_pos.first == -1) {\n            if (covered.size() >= 0.95 * all_roads.size()) {\n                break; // Good enough, return to start\n            }\n            // Try simple exploration moves\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = current_x + dx[dir];\n                int ny = current_y + dy[dir];\n                if (is_valid(nx, ny)) {\n                    best_segment = {dir_char[dir]};\n                    best_pos = {nx, ny};\n                    break;\n                }\n            }\n            if (best_pos.first == -1) break; // No valid moves\n        }\n        \n        // Add this segment to path if it fits\n        if (path.size() + best_segment.size() <= 2800) {\n            path.insert(path.end(), best_segment.begin(), best_segment.end());\n            current_x = best_pos.first;\n            current_y = best_pos.second;\n            \n            // Update coverage\n            auto new_visible = get_visible_squares(current_x, current_y);\n            covered.insert(new_visible.begin(), new_visible.end());\n        } else {\n            break;\n        }\n        \n        // If we have very good coverage, stop early to save moves for return\n        if (covered.size() >= 0.98 * all_roads.size() && path.size() > 2000) {\n            break;\n        }\n    }\n    \n    // Final thorough coverage attempt\n    if (covered.size() < all_roads.size() && path.size() < 2700) {\n        // Try to visit remaining uncovered roads specifically\n        vector<pair<int,int>> uncovered_roads;\n        for (const auto& road : all_roads) {\n            if (covered.find(road) == covered.end()) {\n                uncovered_roads.push_back(road);\n            }\n        }\n        \n        // Visit up to 20 uncovered roads if possible\n        int visit_limit = min(20, (int)uncovered_roads.size());\n        for (int i = 0; i < visit_limit && path.size() < 2700; i++) {\n            auto target = uncovered_roads[i];\n            auto segment = bfs_path(current_x, current_y, target.first, target.second);\n            if (!segment.empty() && path.size() + segment.size() <= 2700) {\n                path.insert(path.end(), segment.begin(), segment.end());\n                current_x = target.first;\n                current_y = target.second;\n                auto vis = get_visible_squares(current_x, current_y);\n                covered.insert(vis.begin(), vis.end());\n            }\n        }\n    }\n    \n    // Return to start\n    if (current_x != si || current_y != sj) {\n        auto return_segment = bfs_path(current_x, current_y, si, sj);\n        if (path.size() + return_segment.size() <= 2999) {\n            path.insert(path.end(), return_segment.begin(), return_segment.end());\n        } else if (path.size() < 2999) {\n            // Truncate return path if necessary\n            int space_left = 2999 - path.size();\n            if (space_left > 0 && space_left <= (int)return_segment.size()) {\n                return_segment.resize(space_left);\n                path.insert(path.end(), return_segment.begin(), return_segment.end());\n            }\n        }\n    }\n    \n    return path;\n}\n\n// Optimize path by ensuring validity\nvector<char> optimize_path(const vector<char>& original_path) {\n    if (original_path.empty()) return original_path;\n    \n    // Simulate path to verify it's valid and returns to start\n    int x = si, y = sj;\n    \n    for (char c : original_path) {\n        int dir = -1;\n        for (int i = 0; i < 4; i++) {\n            if (dir_char[i] == c) {\n                dir = i;\n                break;\n            }\n        }\n        \n        if (dir != -1) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            if (is_valid(nx, ny)) {\n                x = nx;\n                y = ny;\n            } else {\n                // Invalid move - truncate path here\n                vector<char> fixed_path;\n                int tx = si, ty = sj;\n                for (char fc : original_path) {\n                    int fdir = -1;\n                    for (int i = 0; i < 4; i++) {\n                        if (dir_char[i] == fc) {\n                            fdir = i;\n                            break;\n                        }\n                    }\n                    if (fdir != -1) {\n                        int fnx = tx + dx[fdir];\n                        int fny = ty + dy[fdir];\n                        if (is_valid(fnx, fny)) {\n                            fixed_path.push_back(fc);\n                            tx = fnx;\n                            ty = fny;\n                        } else {\n                            break;\n                        }\n                    }\n                }\n                return fixed_path;\n            }\n        }\n    }\n    \n    // If we don't end at start, try to return\n    if (x != si || y != sj) {\n        vector<char> fixed_path = original_path;\n        auto return_segment = bfs_path(x, y, si, sj);\n        if (fixed_path.size() + return_segment.size() <= 2999) {\n            fixed_path.insert(fixed_path.end(), return_segment.begin(), return_segment.end());\n        }\n        return fixed_path;\n    }\n    \n    return original_path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j];\n            if (line[j] == '#') {\n                is_road[i][j] = false;\n            } else {\n                is_road[i][j] = true;\n                cost[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    // Generate path using improved greedy coverage approach\n    vector<char> path = generate_greedy_coverage_path();\n    \n    // Ensure path validity\n    path = optimize_path(path);\n    \n    // Final length check\n    if (path.size() > 2999) {\n        path.resize(2999);\n    }\n    \n    // Output result\n    for (char c : path) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int MAX_N = 1000;\nconst int MAX_M = 20;\nconst int MAX_K = 20;\nconst int MAX_DAYS = 2000;\n\n// Global variables\nint N, M, K, R;\nvector<vector<int>> task_skills;  // [task][skill] = required level\nvector<vector<int>> member_skills; // [member][skill] = estimated level\nvector<vector<int>> task_times;    // [task][member] = observed time\nvector<vector<int>> dependencies;  // [task] = list of prerequisite tasks\nvector<vector<int>> reverse_dependencies; // [task] = list of dependent tasks\nvector<int> task_status;           // -1:not started, 0:in progress, 1:completed\nvector<int> member_status;         // -1:free, task_id:working on task\nvector<int> task_completion_day;   // when each task was completed\nvector<set<int>> completed_tasks_by_member; // track what each member completed\n\n// For skill estimation\nvector<int> task_start_day;\nvector<vector<pair<int,int>>> member_task_history; // {task_id, completion_time}\n\n// Topological sorting helper\nvector<int> in_degree;\nqueue<int> ready_tasks;\n\nvoid read_input() {\n    cin >> N >> M >> K >> R;\n    \n    task_skills.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_skills[i][j];\n        }\n    }\n    \n    dependencies.resize(N);\n    reverse_dependencies.resize(N);\n    in_degree.assign(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--; // Convert to 0-indexed\n        dependencies[v].push_back(u);\n        reverse_dependencies[u].push_back(v);\n        in_degree[v]++;\n    }\n}\n\n// Initialize data structures\nvoid initialize() {\n    task_status.assign(N, -1);\n    member_status.assign(M, -1);\n    task_completion_day.assign(N, -1);\n    task_start_day.assign(N, -1);\n    completed_tasks_by_member.resize(M);\n    member_task_history.resize(M);\n    \n    // Initialize skill estimates with reasonable defaults\n    member_skills.resize(M, vector<int>(K, 10)); // Start with moderate skills\n    task_times.resize(N, vector<int>(M, 1));     // Default time estimate\n    \n    // Find initially ready tasks (no dependencies)\n    for (int i = 0; i < N; i++) {\n        if (in_degree[i] == 0) {\n            ready_tasks.push(i);\n        }\n    }\n}\n\n// Estimate member skills based on history\nvoid update_skill_estimates() {\n    // Simple approach: for each member, look at tasks they completed quickly\n    for (int member = 0; member < M; member++) {\n        if (member_task_history[member].size() == 0) continue;\n        \n        // Look at recent successful completions (time = 1 day usually means skill >= difficulty)\n        map<int, vector<int>> skill_samples; // skill_index -> list of observed levels\n        \n        for (auto& [task_id, completion_time] : member_task_history[member]) {\n            if (completion_time <= 2) { // Completed quickly\n                for (int k = 0; k < K; k++) {\n                    // If completed quickly, member's skill is likely >= task requirement\n                    skill_samples[k].push_back(task_skills[task_id][k]);\n                }\n            }\n        }\n        \n        // Update skill estimates\n        for (int k = 0; k < K; k++) {\n            if (!skill_samples[k].empty()) {\n                // Take maximum observed requirement they handled well\n                sort(skill_samples[k].begin(), skill_samples[k].end());\n                member_skills[member][k] = max(member_skills[member][k], \n                                             skill_samples[k].back());\n            }\n        }\n    }\n}\n\n// Calculate estimated time for a member to complete a task\nint estimate_time(int task_id, int member_id) {\n    int w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0, task_skills[task_id][k] - member_skills[member_id][k]);\n    }\n    \n    if (w == 0) return 1;\n    else return max(1, w); // Simplified - ignoring randomness for planning\n}\n\n// Get best available member for a task\nint get_best_member(int task_id) {\n    int best_member = 0;\n    int min_time = estimate_time(task_id, 0);\n    \n    for (int member = 1; member < M; member++) {\n        int time = estimate_time(task_id, member);\n        if (time < min_time) {\n            min_time = time;\n            best_member = member;\n        }\n    }\n    \n    return best_member;\n}\n\n// Update ready tasks based on completed tasks\nvoid update_ready_tasks(int completed_task) {\n    for (int dependent : reverse_dependencies[completed_task]) {\n        in_degree[dependent]--;\n        if (in_degree[dependent] == 0) {\n            ready_tasks.push(dependent);\n        }\n    }\n}\n\n// Main assignment logic\nvector<pair<int, int>> assign_tasks(int current_day) {\n    vector<pair<int, int>> assignments;\n    \n    // Find free members\n    vector<int> free_members;\n    for (int member = 0; member < M; member++) {\n        if (member_status[member] == -1) {\n            free_members.push_back(member);\n        }\n    }\n    \n    if (free_members.empty() || ready_tasks.empty()) {\n        return assignments;\n    }\n    \n    // Create list of ready tasks with priorities\n    vector<pair<int, int>> task_priority; // {priority, task_id}\n    queue<int> temp_queue = ready_tasks; // Copy to avoid modifying original\n    \n    while (!temp_queue.empty()) {\n        int task_id = temp_queue.front();\n        temp_queue.pop();\n        \n        // Priority: tasks with more dependents first, then lower ID\n        int priority = -reverse_dependencies[task_id].size() * 1000 - task_id;\n        task_priority.push_back({priority, task_id});\n    }\n    \n    sort(task_priority.begin(), task_priority.end());\n    \n    // Assign tasks to free members\n    int task_count = min((int)free_members.size(), (int)task_priority.size());\n    \n    for (int i = 0; i < task_count; i++) {\n        int member_id = free_members[i];\n        int task_id = task_priority[i].second;\n        \n        // Remove this task from ready queue (we'll re-add if not assigned)\n        // Actually, let's handle this more carefully in the main loop\n        \n        assignments.push_back({member_id, task_id});\n        task_status[task_id] = 0; // Mark as in progress\n        member_status[member_id] = task_id;\n        task_start_day[task_id] = current_day;\n    }\n    \n    return assignments;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    read_input();\n    initialize();\n    \n    int day = 0;\n    \n    while (day < MAX_DAYS) {\n        day++;\n        \n        // Process completed tasks from previous day\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) {\n            break; // Done\n        }\n        \n        vector<int> completed_members(n_completed);\n        for (int i = 0; i < n_completed; i++) {\n            cin >> completed_members[i];\n            completed_members[i]--; // Convert to 0-indexed\n        }\n        \n        // Update based on completed tasks\n        for (int member_idx : completed_members) {\n            int task_id = member_status[member_idx];\n            if (task_id != -1) {\n                task_status[task_id] = 1;\n                task_completion_day[task_id] = day;\n                member_status[member_idx] = -1;\n                completed_tasks_by_member[member_idx].insert(task_id);\n                \n                // Record completion for skill estimation\n                int duration = day - task_start_day[task_id];\n                member_task_history[member_idx].push_back({task_id, duration});\n                \n                // Update ready tasks\n                update_ready_tasks(task_id);\n            }\n        }\n        \n        // Update skill estimates periodically\n        if (day % 10 == 0) {\n            update_skill_estimates();\n        }\n        \n        // Make new assignments\n        vector<pair<int, int>> assignments = assign_tasks(day);\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& [member, task] : assignments) {\n            cout << \" \" << (member + 1) << \" \" << (task + 1);\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst int NUM_ORDERS = 1000;\nconst int SELECT_COUNT = 50;\n\nstruct Order {\n    int id, a, b, c, d;\n};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan_distance(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nint manhattan_distance(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Simple greedy route construction\nvector<Point> build_route(const vector<Order>& selected_orders) {\n    vector<Point> route;\n    route.emplace_back(DEPOT_X, DEPOT_Y);\n    \n    // Create list of all points with their type and order id\n    vector<pair<Point, pair<int, bool>>> all_points; // point, {order_id, is_pickup}\n    \n    for (const auto& order : selected_orders) {\n        all_points.emplace_back(Point(order.a, order.b), make_pair(order.id, true));   // pickup\n        all_points.emplace_back(Point(order.c, order.d), make_pair(order.id, false));  // delivery\n    }\n    \n    vector<bool> picked_up(NUM_ORDERS + 1, false);\n    \n    // Greedy construction: at each step, pick the nearest valid point\n    while (!all_points.empty()) {\n        Point current = route.back();\n        int best_idx = -1;\n        int best_dist = 1e9;\n        \n        // Find the best next point to visit\n        for (size_t i = 0; i < all_points.size(); i++) {\n            const Point& point = all_points[i].first;\n            int order_id = all_points[i].second.first;\n            bool is_pickup = all_points[i].second.second;\n            \n            if (is_pickup) {\n                // Always valid to pick up\n                int dist = manhattan_distance(current, point);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_idx = i;\n                }\n            } else {\n                // Can only deliver if picked up\n                if (picked_up[order_id]) {\n                    int dist = manhattan_distance(current, point);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        // If no valid delivery found, pick the closest pickup\n        if (best_idx == -1) {\n            for (size_t i = 0; i < all_points.size(); i++) {\n                const Point& point = all_points[i].first;\n                bool is_pickup = all_points[i].second.second;\n                if (is_pickup) {\n                    int dist = manhattan_distance(current, point);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        // If still no point found, take the first one\n        if (best_idx == -1) {\n            best_idx = 0;\n        }\n        \n        // Add the selected point to route\n        const Point& selected_point = all_points[best_idx].first;\n        int order_id = all_points[best_idx].second.first;\n        bool is_pickup = all_points[best_idx].second.second;\n        \n        route.push_back(selected_point);\n        \n        if (is_pickup) {\n            picked_up[order_id] = true;\n        }\n        \n        // Remove the selected point\n        all_points.erase(all_points.begin() + best_idx);\n    }\n    \n    // Return to depot\n    route.emplace_back(DEPOT_X, DEPOT_Y);\n    \n    return route;\n}\n\n// Select orders based on efficiency\nvector<Order> select_orders(vector<Order>& orders) {\n    // Calculate efficiency score: direct distance + average distance to depot\n    vector<pair<int, int>> scores; // {score, order_id}\n    \n    for (int i = 0; i < NUM_ORDERS; i++) {\n        int direct_dist = manhattan_distance(orders[i].a, orders[i].b, orders[i].c, orders[i].d);\n        int pickup_dist = manhattan_distance(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b);\n        int delivery_dist = manhattan_distance(DEPOT_X, DEPOT_Y, orders[i].c, orders[i].d);\n        int score = direct_dist + (pickup_dist + delivery_dist) / 2;\n        scores.emplace_back(score, i);\n    }\n    \n    // Sort by score (lower is better)\n    sort(scores.begin(), scores.end());\n    \n    // Select best orders\n    vector<Order> selected_orders;\n    for (int i = 0; i < SELECT_COUNT; i++) {\n        selected_orders.push_back(orders[scores[i].second]);\n    }\n    \n    return selected_orders;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<Order> orders(NUM_ORDERS);\n    \n    // Read input\n    for (int i = 0; i < NUM_ORDERS; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i + 1;\n    }\n    \n    // Select orders\n    vector<Order> selected_orders = select_orders(orders);\n    \n    // Build route\n    vector<Point> route = build_route(selected_orders);\n    \n    // Output selected orders\n    cout << SELECT_COUNT;\n    for (const auto& order : selected_orders) {\n        cout << \" \" << order.id;\n    }\n    cout << \"\\n\";\n    \n    // Output route\n    cout << route.size();\n    for (const auto& point : route) {\n        cout << \" \" << point.x << \" \" << point.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\nconst int M = 1995;\n\nstruct Edge {\n    int u, v;\n    int d; // euclidean distance (rounded)\n    int l; // actual length (revealed online)\n    double ratio; // l/d ratio\n};\n\nvector<pair<int, int>> coords(N);\nvector<Edge> edges(M);\nvector<int> parent(N);\nint component_count = N;\n\nvoid init_union_find() {\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n}\n\nint find(int x) {\n    if (parent[x] != x) {\n        parent[x] = find(parent[x]);\n    }\n    return parent[x];\n}\n\nbool unite(int x, int y) {\n    x = find(x);\n    y = find(y);\n    if (x == y) return false;\n    parent[x] = y;\n    component_count--;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read coordinates\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Read edges\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        \n        // Calculate euclidean distance\n        long long dx = coords[edges[i].u].first - coords[edges[i].v].first;\n        long long dy = coords[edges[i].u].second - coords[edges[i].v].second;\n        edges[i].d = (int)round(sqrt(dx * dx + dy * dy));\n    }\n    \n    init_union_find();\n    \n    // Process each edge as it comes\n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        edges[i].l = l;\n        edges[i].ratio = (double)l / edges[i].d;\n        \n        int u = edges[i].u;\n        int v = edges[i].v;\n        \n        // Check if this edge connects two different components\n        bool would_connect = (find(u) != find(v));\n        \n        bool accept = false;\n        \n        // Always accept edges that connect different components until we have a spanning tree\n        if (would_connect && component_count > 1) {\n            accept = true;\n        }\n        // For remaining edges, be selective based on cost efficiency\n        else if (component_count == 1) {\n            // Even after connectivity, accept very cheap edges that could improve the tree\n            // Only accept if significantly better than average\n            if (edges[i].ratio <= 1.3) {\n                accept = true;\n            }\n        }\n        \n        if (accept) {\n            unite(u, v);\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nconst int INF = 100000000;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Point pos;\n    int type;\n    Pet() : pos(Point(0, 0)), type(0) {}\n    Pet(Point p, int t) : pos(p), type(t) {}\n};\n\nstruct Human {\n    Point pos;\n    Human() : pos(Point(0, 0)) {}\n    Human(Point p) : pos(p) {}\n};\n\n// Directions: up, down, left, right\nconst vector<Point> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"UDLR\";\nconst string BLOCK_CHARS = \"udlr\";\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nvector<vector<int>> grid; // 0 = passable, 1 = blocked\n\n// Check if position is valid\nbool valid(int x, int y) {\n    return x >= 1 && x <= H && y >= 1 && y <= W;\n}\n\nbool valid_point(Point p) {\n    return valid(p.x, p.y);\n}\n\n// Check if a square is adjacent to any pet\nbool is_adjacent_to_pet(Point p) {\n    for (auto& pet : pets) {\n        if (abs(pet.pos.x - p.x) + abs(pet.pos.y - p.y) <= 1) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a square contains any pet\nbool contains_pet(Point p) {\n    for (auto& pet : pets) {\n        if (pet.pos == p) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a square will contain any human after moves\nbool will_contain_human(Point p, const vector<Point>& intended_moves, int exclude_index) {\n    for (int i = 0; i < M; i++) {\n        if (i != exclude_index && intended_moves[i] == p) {\n            return true;\n        }\n    }\n    return false;\n}\n\nstring decide_actions(int turn) {\n    string actions(M, '.');\n    \n    // Determine intended moves first\n    vector<Point> intended_moves(M);\n    for (int i = 0; i < M; i++) {\n        intended_moves[i] = humans[i].pos; // default to staying\n    }\n    \n    // Simple strategy: early game move away from pets, later game block strategically\n    for (int i = 0; i < M; i++) {\n        Point cur = humans[i].pos;\n        \n        if (turn < 100) {\n            // Early game: move away from nearby pets\n            int best_dist = -1;\n            int best_dir = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(next) && grid[next.x][next.y] == 0) {\n                    // Calculate minimum distance to any pet\n                    int min_dist = INF;\n                    for (auto& pet : pets) {\n                        int dist = abs(pet.pos.x - next.x) + abs(pet.pos.y - next.y);\n                        min_dist = min(min_dist, dist);\n                    }\n                    int cur_dist = INF;\n                    for (auto& pet : pets) {\n                        int dist = abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y);\n                        cur_dist = min(cur_dist, dist);\n                    }\n                    \n                    if (min_dist > cur_dist && min_dist > best_dist) {\n                        best_dist = min_dist;\n                        best_dir = d;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                actions[i] = DIR_CHARS[best_dir];\n                intended_moves[i] = {cur.x + DIRS[best_dir].x, cur.y + DIRS[best_dir].y};\n            }\n        } else {\n            // Later game: try to block strategically\n            int best_score = -1;\n            int best_dir = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                    !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos)) {\n                    \n                    // Simple scoring\n                    int score = 0;\n                    // Prefer edge positions\n                    if (block_pos.x == 1 || block_pos.x == H || block_pos.y == 1 || block_pos.y == W) {\n                        score += 10;\n                    }\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = d;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                actions[i] = BLOCK_CHARS[best_dir];\n            }\n        }\n    }\n    \n    // Second pass: validate all actions to avoid conflicts\n    vector<vector<int>> will_be_blocked(H + 1, vector<int>(W + 1, 0));\n    \n    // Mark all blocking actions first\n    for (int i = 0; i < M; i++) {\n        char action = actions[i];\n        if (action >= 'a' && action <= 'z') { // Blocking action\n            size_t dir_idx = BLOCK_CHARS.find(action);\n            if (dir_idx != string::npos) {\n                Point cur = humans[i].pos;\n                Point block_pos = {cur.x + DIRS[dir_idx].x, cur.y + DIRS[dir_idx].y};\n                \n                // Validate block - check if any human will be in this square\n                bool conflict = false;\n                for (int j = 0; j < M; j++) {\n                    if (i != j && intended_moves[j] == block_pos) {\n                        conflict = true;\n                        break;\n                    }\n                }\n                \n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                    !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos) && !conflict) {\n                    will_be_blocked[block_pos.x][block_pos.y] = 1;\n                } else {\n                    actions[i] = '.'; // Invalid block, cancel it\n                }\n            }\n        }\n    }\n    \n    // Validate all movement actions\n    for (int i = 0; i < M; i++) {\n        char action = actions[i];\n        if (action >= 'A' && action <= 'Z') { // Movement action\n            size_t dir_idx = DIR_CHARS.find(action);\n            if (dir_idx != string::npos) {\n                Point cur = humans[i].pos;\n                Point next = {cur.x + DIRS[dir_idx].x, cur.y + DIRS[dir_idx].y};\n                \n                if (!valid_point(next) || grid[next.x][next.y] == 1 || \n                    will_be_blocked[next.x][next.y]) {\n                    actions[i] = '.'; // Invalid move, cancel it\n                }\n            }\n        }\n    }\n    \n    return actions;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Initialize grid\n    grid.assign(H + 1, vector<int>(W + 1, 0));\n    \n    // Read initial positions\n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t;\n        cin >> x >> y >> t;\n        pets[i] = Pet(Point(x, y), t);\n    }\n    \n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        humans[i] = Human(Point(x, y));\n    }\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // Decide actions\n        string actions = decide_actions(turn);\n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        string pet_moves;\n        getline(cin, pet_moves);\n        if (pet_moves.empty()) {\n            getline(cin, pet_moves);\n        }\n        \n        stringstream ss(pet_moves);\n        string move;\n        for (int i = 0; i < N && ss >> move; i++) {\n            // Update pet position based on movement\n            for (char c : move) {\n                switch (c) {\n                    case 'U': pets[i].pos.x--; break;\n                    case 'D': pets[i].pos.x++; break;\n                    case 'L': pets[i].pos.y--; break;\n                    case 'R': pets[i].pos.y++; break;\n                }\n            }\n        }\n        \n        // Update human positions and grid based on actions\n        vector<vector<int>> will_be_blocked(H + 1, vector<int>(W + 1, 0));\n        vector<Point> new_positions = vector<Point>(M);\n        for (int i = 0; i < M; i++) {\n            new_positions[i] = humans[i].pos; // default to staying\n        }\n        \n        // First, mark all blocking actions\n        for (int i = 0; i < M; i++) {\n            char action = actions[i];\n            if (action >= 'a' && action <= 'z') { // Blocking\n                size_t dir_idx = BLOCK_CHARS.find(action);\n                if (dir_idx != string::npos) {\n                    Point block_pos = {humans[i].pos.x + DIRS[dir_idx].x, \n                                     humans[i].pos.y + DIRS[dir_idx].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                        !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos)) {\n                        will_be_blocked[block_pos.x][block_pos.y] = 1;\n                    }\n                }\n            }\n        }\n        \n        // Then, process movements\n        for (int i = 0; i < M; i++) {\n            char action = actions[i];\n            if (action >= 'A' && action <= 'Z') { // Movement\n                size_t dir_idx = DIR_CHARS.find(action);\n                if (dir_idx != string::npos) {\n                    Point next = {humans[i].pos.x + DIRS[dir_idx].x, \n                                humans[i].pos.y + DIRS[dir_idx].y};\n                    if (valid_point(next) && grid[next.x][next.y] == 0 && \n                        !will_be_blocked[next.x][next.y]) {\n                        new_positions[i] = next;\n                    }\n                }\n            }\n        }\n        \n        // Apply movements\n        for (int i = 0; i < M; i++) {\n            humans[i].pos = new_positions[i];\n        }\n        \n        // Apply blocking\n        for (int i = 0; i < M; i++) {\n            char action = actions[i];\n            if (action >= 'a' && action <= 'z') { // Blocking\n                size_t dir_idx = BLOCK_CHARS.find(action);\n                if (dir_idx != string::npos) {\n                    Point block_pos = {humans[i].pos.x + DIRS[dir_idx].x, \n                                     humans[i].pos.y + DIRS[dir_idx].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                        !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos)) {\n                        grid[block_pos.x][block_pos.y] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint si, sj, ti, tj;\ndouble p;\nbool h_wall[N][N-1]; // horizontal walls\nbool v_wall[N-1][N]; // vertical walls\n\n// Direction mappings\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nbool can_move(int x, int y, int dir) {\n    if (dir == 0) { // Up\n        if (x == 0) return false;\n        return !v_wall[x-1][y];\n    } else if (dir == 1) { // Down\n        if (x == N-1) return false;\n        return !v_wall[x][y];\n    } else if (dir == 2) { // Left\n        if (y == 0) return false;\n        return !h_wall[x][y-1];\n    } else { // Right\n        if (y == N-1) return false;\n        return !h_wall[x][y];\n    }\n}\n\n// Create a robust path using a strategy that builds in redundancy\nstring create_robust_path() {\n    string path;\n    \n    // Strategy: Create a path with built-in redundancy\n    // We'll use a \"thick path\" approach where we don't just follow\n    // the shortest route, but create a wider corridor\n    \n    int x = si, y = sj;\n    \n    // Since home is in top-left (0-4, 0-4) and office is in bottom-right (15-19, 15-19)\n    // We generally want to go right and down\n    \n    // Main strategy:\n    // 1. Go right in a robust manner\n    // 2. Go down in a robust manner\n    // 3. Fine-tune to exact position\n    \n    // Phase 1: Move toward target column with redundancy\n    while (y < tj && path.length() < 180) {\n        if (can_move(x, y, 3)) { // Right\n            path += 'R';\n            y++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try down then right\n            if (x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n                moved = true;\n            } else if (x > 0 && can_move(x, y, 0)) {\n                path += 'U';\n                x--;\n                moved = true;\n            }\n            \n            if (moved && y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n            } else if (moved) {\n                // Undo the vertical move if we can't go right\n                if (x > si) {\n                    path += 'U';\n                    x--;\n                } else {\n                    path += 'D';\n                    x++;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Move toward target row with redundancy\n    while (x < ti && path.length() < 195) {\n        if (can_move(x, y, 1)) { // Down\n            path += 'D';\n            x++;\n        } else {\n            // Try to go around obstacles\n            bool moved = false;\n            // Try right then down\n            if (y < N-1 && can_move(x, y, 3)) {\n                path += 'R';\n                y++;\n                moved = true;\n            } else if (y > 0 && can_move(x, y, 2)) {\n                path += 'L';\n                y--;\n                moved = true;\n            }\n            \n            if (moved && x < N-1 && can_move(x, y, 1)) {\n                path += 'D';\n                x++;\n            } else if (moved) {\n                // Undo the horizontal move if we can't go down\n                if (y > sj) {\n                    path += 'L';\n                    y--;\n                } else {\n                    path += 'R';\n                    y++;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Fine adjustment\n    while ((x != ti || y != tj) && path.length() < 200) {\n        if (x < ti && can_move(x, y, 1)) {\n            path += 'D';\n            x++;\n        } else if (x > ti && can_move(x, y, 0)) {\n            path += 'U';\n            x--;\n        } else if (y < tj && can_move(x, y, 3)) {\n            path += 'R';\n            y++;\n        } else if (y > tj && can_move(x, y, 2)) {\n            path += 'L';\n            y--;\n        } else {\n            break;\n        }\n    }\n    \n    return path;\n}\n\n// Alternative approach: Create a path with explicit redundancy\nstring create_redundant_path() {\n    string path;\n    int x = si, y = sj;\n    \n    // Create a path where every few steps, we add a small loop\n    // This provides redundancy - if one move is forgotten, \n    // the loop gives us another chance\n    \n    int steps_since_loop = 0;\n    \n    while ((x != ti || y != tj) && path.length() < 200) {\n        // Determine best direction\n        int best_dir = -1;\n        int best_value = -1000;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(x, y, dir)) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                // Heuristic: prefer moves that get us closer to target\n                int value = -(abs(nx - ti) + abs(ny - tj));\n                \n                // Slight preference for right/down moves to maintain progress\n                if (dir == 1 || dir == 3) value += 1;\n                \n                if (value > best_value) {\n                    best_value = value;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            path += dir_char[best_dir];\n            x += dx[best_dir];\n            y += dy[best_dir];\n            steps_since_loop++;\n            \n            // Every few steps, add a small redundant loop if space allows\n            if (steps_since_loop >= 4 && path.length() < 190) {\n                // Try to add a small 2-step loop\n                int perpendicular_dir1 = (best_dir + 1) % 4;\n                int perpendicular_dir2 = (best_dir + 3) % 4;\n                \n                if (can_move(x, y, perpendicular_dir1) && \n                    can_move(x + dx[perpendicular_dir1], y + dy[perpendicular_dir1], \n                             (perpendicular_dir1 + 2) % 4) &&\n                    path.length() < 198) {\n                    path += dir_char[perpendicular_dir1];\n                    path += dir_char[(perpendicular_dir1 + 2) % 4];\n                    steps_since_loop = 0;\n                } else if (can_move(x, y, perpendicular_dir2) && \n                           can_move(x + dx[perpendicular_dir2], y + dy[perpendicular_dir2], \n                                    (perpendicular_dir2 + 2) % 4) &&\n                           path.length() < 198) {\n                    path += dir_char[perpendicular_dir2];\n                    path += dir_char[(perpendicular_dir2 + 2) % 4];\n                    steps_since_loop = 0;\n                }\n            }\n        } else {\n            break; // No valid moves\n        }\n    }\n    \n    return path;\n}\n\nint main() {\n    // Read input\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N-1; j++) {\n            h_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N-1; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            v_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Generate path - try the redundant approach\n    string result = create_redundant_path();\n    \n    // Fallback to simpler approach if needed\n    if (result.empty() || result.length() > 200) {\n        result = create_robust_path();\n    }\n    \n    // Ensure we don't exceed 200 characters\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction: 0=left, 1=up, 2=right, 3=down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Transition table: to[tile_type][entry_direction] = exit_direction (-1 if invalid)\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // tile 0\n    {3, -1, -1, 0},  // tile 1\n    {-1, -1, 3, 2},  // tile 2\n    {-1, 2, 1, -1},  // tile 3\n    {1, 0, 3, 2},    // tile 4\n    {3, 2, 1, 0},    // tile 5\n    {2, -1, 0, -1},  // tile 6\n    {-1, 3, -1, 1}   // tile 7\n};\n\nconst int N = 30;\nint grid[N][N];\nint rotation[N][N];\n\n// Get actual tile type after rotation\nint get_rotated_tile(int base_tile, int rot) {\n    static const int rotation_map[8][4] = {\n        {0, 1, 2, 3},  // tile 0\n        {1, 2, 3, 0},  // tile 1\n        {2, 3, 0, 1},  // tile 2\n        {3, 0, 1, 2},  // tile 3\n        {4, 5, 4, 5},  // tile 4\n        {5, 4, 5, 4},  // tile 5\n        {6, 7, 6, 7},  // tile 6\n        {7, 6, 7, 6}   // tile 7\n    };\n    return rotation_map[base_tile][rot % 4];\n}\n\n// Check if coordinates are valid\nbool valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\n// Find loop length with reasonable limits\nint find_loop_length(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        int tile_type = get_rotated_tile(grid[i][j], rotation[i][j]);\n        int d2 = to[tile_type][d];\n        \n        if (d2 == -1) return 0;  // Broken line\n        \n        i += di[d2];\n        j += dj[d2];\n        \n        if (!valid(i, j)) return 0;  // Out of bounds\n        \n        d = (d2 + 2) % 4;  // Reverse direction\n        length++;\n        \n        // Reasonable limit to prevent timeout\n        if (length > 200) return 0;\n        \n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\n// Find top loops more efficiently\npair<int, int> find_top_two_loops() {\n    vector<int> loops;\n    \n    // More comprehensive but still efficient sampling\n    for (int i = 0; i < N; i += 2) {\n        for (int j = 0; j < N; j += 2) {\n            for (int d = 0; d < 4; d++) {\n                int length = find_loop_length(i, j, d);\n                if (length > 10) {\n                    loops.push_back(length);\n                }\n            }\n        }\n    }\n    \n    if (loops.size() < 2) return {0, 0};\n    \n    sort(loops.rbegin(), loops.rend());\n    return {loops[0], loops[1]};\n}\n\n// Calculate score\nlong long calculate_score() {\n    auto result = find_top_two_loops();\n    if (result.second == 0) return 0;\n    return 1LL * result.first * result.second;\n}\n\n// Better initialization\nvoid initialize_better() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> rot_dis(0, 3);\n    \n    // Pattern that encourages connectivity\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] >= 4 && grid[i][j] <= 5) {\n                // Double curves\n                rotation[i][j] = 0;\n            } else if (grid[i][j] >= 6 && grid[i][j] <= 7) {\n                // Straights\n                rotation[i][j] = (i % 2) * 2;\n            } else {\n                // Single curves\n                rotation[i][j] = (i + j) % 4;\n            }\n        }\n    }\n}\n\n// Optimized local search - back to the working approach\nvoid optimized_local_search() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    \n    long long current_score = calculate_score();\n    \n    // Good balance of iterations\n    for (int iter = 0; iter < 15000; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        int new_rotation = (old_rotation + 1 + (gen() % 3)) % 4;\n        \n        rotation[i][j] = new_rotation;\n        long long new_score = calculate_score();\n        \n        if (new_score >= current_score) {\n            current_score = new_score;\n        } else {\n            rotation[i][j] = old_rotation;  // Revert\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Better initialization\n    initialize_better();\n    \n    // Optimized local search\n    optimized_local_search();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 10;\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst char inv_dir_chars[4] = {'D', 'U', 'R', 'L'};\n\nint N, T;\nint board[MAX_N][MAX_N];\nint empty_x, empty_y;\n\n// Check if two adjacent tiles are connected\nbool isConnected(int x1, int y1, int x2, int y2) {\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (board[x1][y1] == 0 || board[x2][y2] == 0) return false;\n    \n    // Check if they connect\n    if (x1 == x2 && y1 == y2 - 1) { // Right connection\n        return (board[x1][y1] & 4) && (board[x2][y2] & 1);\n    }\n    if (x1 == x2 && y1 == y2 + 1) { // Left connection\n        return (board[x1][y1] & 1) && (board[x2][y2] & 4);\n    }\n    if (x1 == x2 - 1 && y1 == y2) { // Down connection\n        return (board[x1][y1] & 8) && (board[x2][y2] & 2);\n    }\n    if (x1 == x2 + 1 && y1 == y2) { // Up connection\n        return (board[x1][y1] & 2) && (board[x2][y2] & 8);\n    }\n    return false;\n}\n\n// Find all connected components\nvector<vector<int>> findComponents() {\n    vector<vector<int>> component_id(N, vector<int>(N, -1));\n    int current_component = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || component_id[i][j] != -1) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({i, j});\n            component_id[i][j] = current_component;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                \n                // Check 4 neighbors\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dx[k];\n                    int ny = y + dy[k];\n                    \n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && \n                        component_id[nx][ny] == -1 && board[nx][ny] != 0 && \n                        isConnected(x, y, nx, ny)) {\n                        component_id[nx][ny] = current_component;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            current_component++;\n        }\n    }\n    \n    return component_id;\n}\n\n// Count component sizes\nvector<int> getComponentSizes(const vector<vector<int>>& component_id) {\n    int max_id = -1;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (component_id[i][j] > max_id) max_id = component_id[i][j];\n        }\n    }\n    \n    vector<int> sizes(max_id + 1, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (component_id[i][j] != -1) {\n                sizes[component_id[i][j]]++;\n            }\n        }\n    }\n    \n    return sizes;\n}\n\n// Calculate how many components would be connected by a move\nint calculateConnectionGain(int from_x, int from_y) {\n    // Temporarily move the tile\n    int temp = board[from_x][from_y];\n    board[from_x][from_y] = 0;\n    board[empty_x][empty_y] = temp;\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    \n    // Find components after move\n    auto component_id = findComponents();\n    auto sizes = getComponentSizes(component_id);\n    \n    int max_component_size = 0;\n    if (!sizes.empty()) {\n        max_component_size = *max_element(sizes.begin(), sizes.end());\n    }\n    \n    // Count how many components would be reduced (meaning they got connected)\n    int unique_components = 0;\n    for (int size : sizes) {\n        if (size > 0) unique_components++;\n    }\n    \n    // Restore\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    board[empty_x][empty_y] = 0;\n    board[from_x][from_y] = temp;\n    \n    // Return a score that prioritizes larger components and fewer total components\n    return max_component_size * 1000 - unique_components;\n}\n\n// Try to make a move\nbool makeMove(char move, string& result) {\n    int dir = -1;\n    for (int i = 0; i < 4; i++) {\n        if (dir_chars[i] == move) {\n            dir = i;\n            break;\n        }\n    }\n    \n    int new_x = empty_x + dx[dir];\n    int new_y = empty_y + dy[dir];\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) {\n        return false;\n    }\n    \n    // Perform move\n    board[empty_x][empty_y] = board[new_x][new_y];\n    board[new_x][new_y] = 0;\n    empty_x = new_x;\n    empty_y = new_y;\n    result += move;\n    \n    return true;\n}\n\n// Get current largest tree size\nint getCurrentMaxComponentSize() {\n    auto component_id = findComponents();\n    auto sizes = getComponentSizes(component_id);\n    \n    if (sizes.empty()) return 0;\n    return *max_element(sizes.begin(), sizes.end());\n}\n\n// Check if we can form connections with neighbors of the empty cell\nint getNeighborConnectionPotential() {\n    int potential = 0;\n    for (int k = 0; k < 4; k++) {\n        int nx = empty_x + dx[k];\n        int ny = empty_y + dy[k];\n        if (nx >= 0 && nx < N && ny >= 0 && ny < N && board[nx][ny] != 0) {\n            potential++;\n        }\n    }\n    return potential;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    \n    // Read board\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_x = i;\n                empty_y = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int last_dir = -1;\n    \n    // Enhanced approach with better component analysis\n    for (int step = 0; step < T && (int)result.length() < T; step++) {\n        int best_score = INT_MIN;\n        int best_dir = -1;\n        \n        // Try all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            // Avoid immediate reversals unless necessary\n            if (step > 0 && dir == (last_dir ^ 1)) continue;\n            \n            int from_x = empty_x + dx[dir];\n            int from_y = empty_y + dy[dir];\n            \n            if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n            \n            int score = calculateConnectionGain(from_x, from_y);\n            \n            // Bonus for moves that could connect to multiple neighbors\n            if (step < T * 0.7) { // In early game, prioritize flexibility\n                // Temporarily make move to check neighbor potential\n                int temp = board[from_x][from_y];\n                board[from_x][from_y] = 0;\n                board[empty_x][empty_y] = temp;\n                swap(empty_x, from_x);\n                swap(empty_y, from_y);\n                \n                score += getNeighborConnectionPotential() * 10;\n                \n                // Restore\n                swap(empty_x, from_x);\n                swap(empty_y, from_y);\n                board[empty_x][empty_y] = 0;\n                board[from_x][from_y] = temp;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        // If no good move found, relax constraints\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                \n                if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n                \n                int score = calculateConnectionGain(from_x, from_y);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        // If still no move, pick any valid move\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                if (from_x >= 0 && from_x < N && from_y >= 0 && from_y < N) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            makeMove(dir_chars[best_dir], result);\n            last_dir = best_dir;\n        } else {\n            break;\n        }\n        \n        // Early termination if we have a near-optimal solution\n        int current_max = getCurrentMaxComponentSize();\n        if (current_max >= N * N - 2 && result.length() < T * 0.7) {\n            // Try a few more moves to complete the tree\n            if (result.length() + 10 < T) {\n                continue;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing P = pair<int, int>;\n\nconst int MAX_N = 10000;\nconst int RADIUS = 10000;\nconst int BOUND = 1000000000;\n\nstruct Strawberry {\n    int x, y;\n    int id;\n};\n\nint N, K;\nint a[11]; // a[1] to a[10]\nvector<Strawberry> strawberries;\n\n// Generate line through two points\ntuple<ll, ll, ll, ll> line_through_points(ll x1, ll y1, ll x2, ll y2) {\n    if (x1 == x2 && y1 == y2) {\n        x2 += 1;\n    }\n    return {x1, y1, x2, y2};\n}\n\n// Calculate centroid of strawberries\npair<double, double> calculate_centroid() {\n    if (strawberries.empty()) return {0, 0};\n    \n    double sum_x = 0, sum_y = 0;\n    for (const auto& s : strawberries) {\n        sum_x += s.x;\n        sum_y += s.y;\n    }\n    return {sum_x / N, sum_y / N};\n}\n\n// Proven effective strategy from the 30M solution\nvoid proven_effective_strategy(vector<tuple<ll, ll, ll, ll>>& lines) {\n    if (strawberries.empty()) return;\n    \n    // Calculate centroid\n    auto [centroid_x, centroid_y] = calculate_centroid();\n    \n    int used_lines = 0;\n    \n    // 1. Radial lines from centroid - proven effective\n    int radial_count = min(25, K/3);\n    for (int i = 0; i < radial_count && used_lines < K; i++) {\n        double angle = 2.0 * M_PI * i / max(1, radial_count);\n        // Golden ratio offset for better distribution\n        double offset = (sqrt(5.0) - 1.0) / 2.0;\n        angle += (i * offset);\n        \n        ll px = (ll)(centroid_x + 200000 * cos(angle));\n        ll py = (ll)(centroid_y + 200000 * sin(angle));\n        ll qx = (ll)(centroid_x - 200000 * cos(angle));\n        ll qy = (ll)(centroid_y - 200000 * sin(angle));\n        lines.push_back({px, py, qx, qy});\n        used_lines++;\n    }\n    \n    // 2. Grid lines - proven effective\n    int grid_dim = min(8, (int)sqrt((K - used_lines)/2));\n    if (grid_dim > 0) {\n        // Horizontal lines\n        for (int i = 0; i <= grid_dim && used_lines < K; i++) {\n            double ratio = (double)i / max(1, grid_dim);\n            // Add some non-linearity for better distribution\n            ratio = pow(ratio, 0.8);\n            int y_pos = (int)(centroid_y - RADIUS + 2 * RADIUS * ratio);\n            lines.push_back(line_through_points(-BOUND, y_pos, BOUND, y_pos));\n            used_lines++;\n        }\n        \n        // Vertical lines\n        for (int i = 0; i <= grid_dim && used_lines < K; i++) {\n            double ratio = (double)i / max(1, grid_dim);\n            // Add some non-linearity for better distribution\n            ratio = pow(ratio, 1.2);\n            int x_pos = (int)(centroid_x - RADIUS + 2 * RADIUS * ratio);\n            lines.push_back(line_through_points(x_pos, -BOUND, x_pos, BOUND));\n            used_lines++;\n        }\n    }\n    \n    // 3. Strategic separators between nearby strawberries - proven effective\n    // Create a distance matrix for nearest neighbors\n    vector<pair<double, pair<int, int>>> distances;\n    for (int i = 0; i < min(N, 30); i++) {\n        for (int j = i + 1; j < min(N, 30); j++) {\n            double dist = sqrt(pow(strawberries[i].x - strawberries[j].x, 2) + \n                              pow(strawberries[i].y - strawberries[j].y, 2));\n            distances.push_back({dist, {i, j}});\n        }\n    }\n    \n    // Sort by distance and create separators for closest pairs\n    sort(distances.begin(), distances.end());\n    \n    for (int i = 0; i < min(15, (int)distances.size()) && used_lines < K - 3; i++) {\n        int idx1 = distances[i].second.first;\n        int idx2 = distances[i].second.second;\n        \n        if (idx1 != idx2) {\n            // Perpendicular bisector with perturbation\n            double mid_x = (strawberries[idx1].x + strawberries[idx2].x) / 2.0;\n            double mid_y = (strawberries[idx1].y + strawberries[idx2].y) / 2.0;\n            int dx = strawberries[idx2].x - strawberries[idx1].x;\n            int dy = strawberries[idx2].y - strawberries[idx1].y;\n            \n            // Add intelligent perturbation based on index\n            double perturb_x = (i % 7 - 3) * 2.5;\n            double perturb_y = (i % 5 - 2) * 2.5;\n            \n            lines.push_back({(ll)(mid_x - dy + perturb_x), \n                           (ll)(mid_y + dx + perturb_y),\n                           (ll)(mid_x + dy + perturb_x), \n                           (ll)(mid_y - dx + perturb_y)});\n            used_lines++;\n        }\n    }\n    \n    // 4. High-priority isolation for a_1 demand - proven effective\n    int singles_to_isolate = min(a[1], 8);\n    for (int i = 0; i < singles_to_isolate && used_lines < K - 1; i++) {\n        if (i < N) {\n            int x = strawberries[i].x;\n            int y = strawberries[i].y;\n            \n            // Create a cross pattern around this strawberry\n            int offset = 70 + (i % 30);\n            \n            if (used_lines < K) {\n                lines.push_back(line_through_points(x - offset, y, x + offset + (i%7), y + (i%5 - 2)));\n                used_lines++;\n            }\n            if (used_lines < K) {\n                lines.push_back(line_through_points(x, y - offset, x + (i%4 - 2), y + offset + (i%6)));\n                used_lines++;\n            }\n        }\n    }\n    \n    // 5. Fill remaining with diversified high-quality lines - proven effective\n    while (used_lines < K) {\n        // Weighted strategy selection\n        int choice = rand() % 100;\n        \n        if (choice < 30) {\n            // Smart radial\n            double angle = 2.0 * M_PI * used_lines / max(1, K);\n            // Use golden ratio for even better distribution\n            double phi = (1.0 + sqrt(5.0)) / 2.0;\n            angle += (used_lines / phi);\n            \n            ll px = (ll)(centroid_x + 150000 * cos(angle));\n            ll py = (ll)(centroid_y + 150000 * sin(angle));\n            ll qx = (ll)(centroid_x - 150000 * cos(angle));\n            ll qy = (ll)(centroid_y - 150000 * sin(angle));\n            lines.push_back({px, py, qx, qy});\n        }\n        else if (choice < 55) {\n            // Smart grid\n            int pos_x = (rand() % (2 * RADIUS)) - RADIUS + (int)centroid_x;\n            int pos_y = (rand() % (2 * RADIUS)) - RADIUS + (int)centroid_y;\n            \n            if (rand() % 2) {\n                lines.push_back(line_through_points(pos_x - 100000, pos_y, pos_x + 100000, pos_y));\n            } else {\n                lines.push_back(line_through_points(pos_x, pos_y - 100000, pos_x, pos_y + 100000));\n            }\n        }\n        else if (choice < 75) {\n            // Intelligent separator\n            if (N > 1) {\n                int idx1 = rand() % N;\n                int idx2 = (idx1 + 1 + rand() % min(10, max(1, N-1))) % N;\n                \n                if (idx1 != idx2) {\n                    double mid_x = (strawberries[idx1].x + strawberries[idx2].x) / 2.0;\n                    double mid_y = (strawberries[idx1].y + strawberries[idx2].y) / 2.0;\n                    int dx = strawberries[idx2].x - strawberries[idx1].x;\n                    int dy = strawberries[idx2].y - strawberries[idx1].y;\n                    \n                    lines.push_back({(ll)(mid_x - dy + (rand()%11 - 5)), \n                                   (ll)(mid_y + dx + (rand()%11 - 5)),\n                                   (ll)(mid_x + dy + (rand()%11 - 5)), \n                                   (ll)(mid_y - dx + (rand()%11 - 5))});\n                } else {\n                    goto random_line;\n                }\n            } else {\n                goto random_line;\n            }\n        }\n        else {\n            random_line:\n            // High-quality random line\n            ll px = (ll)((rand() % (2 * BOUND)) - BOUND);\n            ll py = (ll)((rand() % (2 * BOUND)) - BOUND);\n            ll qx = (ll)((rand() % (2 * BOUND)) - BOUND);\n            ll qy = (ll)((rand() % (2 * BOUND)) - BOUND);\n            \n            // Ensure points are sufficiently different\n            if (abs(px - qx) + abs(py - qy) < 100) {\n                qx += (rand() % 100) + 10;\n                qy += (rand() % 100) - 50;\n            }\n            \n            lines.push_back({px, py, qx, qy});\n        }\n        used_lines++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // High quality random seeding\n    auto seed = time(nullptr) ^ (intptr_t)&cout ^ chrono::duration_cast<chrono::nanoseconds>(\n        chrono::high_resolution_clock::now().time_since_epoch()).count();\n    srand(seed);\n    \n    cin >> N >> K;\n    \n    int total_demand = 0;\n    for (int d = 1; d <= 10; d++) {\n        cin >> a[d];\n        total_demand += a[d];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n    }\n    \n    // Use the proven effective strategy\n    vector<tuple<ll, ll, ll, ll>> lines;\n    proven_effective_strategy(lines);\n    \n    // Ensure we don't exceed K lines\n    if ((int)lines.size() > K) {\n        lines.resize(K);\n    }\n    \n    // Output result\n    cout << lines.size() << \"\\n\";\n    for (const auto& line : lines) {\n        auto [px, py, qx, qy] = line;\n        cout << px << \" \" << py << \" \" << qx << \" \" << qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int MAX_N = 65;\nbool grid[MAX_N][MAX_N];\nint N, M;\nvector<pair<int, int>> initial_dots;\nvector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n// Store edges of drawn rectangles to prevent overlaps\nset<pair<pair<int, int>, pair<int, int>>> drawn_edges;\n\nauto start_time = high_resolution_clock::now();\nconst double TIME_LIMIT = 4.7;\n\n// Weight calculation\ninline long long weight(int x, int y) {\n    int c = (N - 1) / 2;\n    int dx = x - c;\n    int dy = y - c;\n    return (long long)dx * dx + (long long)dy * dy + 1;\n}\n\nbool time_limit_exceeded() {\n    auto now = high_resolution_clock::now();\n    auto duration = duration_cast<milliseconds>(now - start_time);\n    return duration.count() > TIME_LIMIT * 1000;\n}\n\n// Generate all points on a line segment\nvector<pair<int, int>> get_line_points(int x1, int y1, int x2, int y2) {\n    vector<pair<int, int>> points;\n    \n    if (x1 == x2 && y1 == y2) {\n        points.push_back({x1, y1});\n        return points;\n    }\n    \n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int steps = max(abs(dx), abs(dy));\n    \n    for (int i = 0; i <= steps; i++) {\n        int x = x1 + (dx * i) / steps;\n        int y = y1 + (dy * i) / steps;\n        points.push_back({x, y});\n    }\n    return points;\n}\n\n// Normalize edge to have consistent representation\npair<pair<int, int>, pair<int, int>> normalize_edge(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        return {{x2, y2}, {x1, y1}};\n    }\n    return {{x1, y1}, {x2, y2}};\n}\n\n// Get all edges of a rectangle\nvector<pair<pair<int, int>, pair<int, int>>> get_rectangle_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    vector<pair<pair<int, int>, pair<int, int>>> edges;\n    edges.push_back(normalize_edge(x1, y1, x2, y2));\n    edges.push_back(normalize_edge(x2, y2, x3, y3));\n    edges.push_back(normalize_edge(x3, y3, x4, y4));\n    edges.push_back(normalize_edge(x4, y4, x1, y1));\n    return edges;\n}\n\n// Check if rectangle edges overlap with existing edges\nbool has_edge_overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto edges = get_rectangle_edges(x1, y1, x2, y2, x3, y3, x4, y4);\n    for (const auto& edge : edges) {\n        if (drawn_edges.count(edge)) return true;\n    }\n    return false;\n}\n\n// Add edges of a rectangle to the drawn set\nvoid add_rectangle_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto edges = get_rectangle_edges(x1, y1, x2, y2, x3, y3, x4, y4);\n    for (const auto& edge : edges) {\n        drawn_edges.insert(edge);\n    }\n}\n\n// Check if four points form a valid rectangle (axis-parallel or 45-degree)\nbool is_valid_rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check if diagonals bisect each other (parallelogram property)\n    if (x1 + x3 != x2 + x4 || y1 + y3 != y2 + y4) {\n        return false;\n    }\n    \n    // Check if all sides are valid directions (axis-parallel or 45-degree)\n    vector<pair<int, int>> points = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    for (int i = 0; i < 4; i++) {\n        int j = (i + 1) % 4;\n        int dx = points[j].first - points[i].first;\n        int dy = points[j].second - points[i].second;\n        \n        // Valid moves: horizontal, vertical, or diagonal (|dx| = |dy|)\n        if (dx == 0 && dy == 0) return false; // Same point\n        if (!(dx == 0 || dy == 0 || abs(dx) == abs(dy))) {\n            return false;\n        }\n    }\n    \n    // Check that it's actually a rectangle by verifying diagonals are equal\n    long long diag1_sq = (long long)(x3 - x1) * (x3 - x1) + (long long)(y3 - y1) * (y3 - y1);\n    long long diag2_sq = (long long)(x4 - x2) * (x4 - x2) + (long long)(y4 - y2) * (y4 - y2);\n    \n    if (diag1_sq != diag2_sq) return false;\n    \n    return true;\n}\n\n// Check if there are no dots on the perimeter except the 4 vertices\nbool no_dots_on_perimeter(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    set<pair<int, int>> vertices = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    // Check each side\n    auto side1 = get_line_points(x1, y1, x2, y2);\n    auto side2 = get_line_points(x2, y2, x3, y3);\n    auto side3 = get_line_points(x3, y3, x4, y4);\n    auto side4 = get_line_points(x4, y4, x1, y1);\n    \n    for (const auto& p : side1) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side2) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side3) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side4) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    \n    return true;\n}\n\nvoid solve() {\n    // Initialize with initial dots\n    vector<pair<int, int>> dots;\n    for (int i = 0; i < M; i++) {\n        dots.push_back(initial_dots[i]);\n        grid[initial_dots[i].first][initial_dots[i].second] = true;\n    }\n    \n    // Keep trying until no more valid operations\n    while (!time_limit_exceeded()) {\n        bool found = false;\n        \n        // Create candidate positions sorted by weight\n        vector<tuple<long long, int, int>> candidates;\n        for (int x = 1; x < N - 1; x++) {\n            for (int y = 1; y < N - 1; y++) {\n                if (!grid[x][y]) {\n                    long long w = weight(x, y);\n                    candidates.push_back({w, x, y});\n                }\n            }\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Try candidates in order of weight\n        for (const auto& candidate : candidates) {\n            if (time_limit_exceeded()) break;\n            \n            int x1 = get<1>(candidate);\n            int y1 = get<2>(candidate);\n            \n            // Try combinations of existing dots\n            int sz = dots.size();\n            \n            // Limit search to avoid timeout - focus on recent dots which are more likely to form rectangles\n            int start_idx = max(0, sz - 50);\n            int end_idx = sz;\n            \n            for (int i = start_idx; i < end_idx && !found; i++) {\n                for (int j = i + 1; j < end_idx && !found; j++) {\n                    for (int k = j + 1; k < end_idx && !found; k++) {\n                        if (time_limit_exceeded()) return;\n                        \n                        int x2 = dots[i].first, y2 = dots[i].second;\n                        int x3 = dots[j].first, y3 = dots[j].second;\n                        int x4 = dots[k].first, y4 = dots[k].second;\n                        \n                        // Try all permutations\n                        vector<vector<int>> perms = {\n                            {x2, y2, x3, y3, x4, y4},\n                            {x2, y2, x4, y4, x3, y3},\n                            {x3, y3, x2, y2, x4, y4},\n                            {x3, y3, x4, y4, x2, y2},\n                            {x4, y4, x2, y2, x3, y3},\n                            {x4, y4, x3, y3, x2, y2}\n                        };\n                        \n                        for (const auto& perm : perms) {\n                            if (is_valid_rectangle(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                if (no_dots_on_perimeter(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                    if (!has_edge_overlap(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                        // Valid operation\n                                        operations.push_back(make_tuple(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]));\n                                        grid[x1][y1] = true;\n                                        dots.push_back({x1, y1});\n                                        add_rectangle_edges(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]);\n                                        found = true;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (found) break;\n        }\n        \n        if (!found) break;\n    }\n}\n\nint main() {\n    start_time = high_resolution_clock::now();\n    \n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    initial_dots.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> initial_dots[i].first >> initial_dots[i].second;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" \n             << get<2>(op) << \" \" << get<3>(op) << \" \"\n             << get<4>(op) << \" \" << get<5>(op) << \" \"\n             << get<6>(op) << \" \" << get<7>(op) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 10;\nconst int TOTAL_CANDIES = 100;\n\n// Directions: F(forward/up), B(backward/down), L(left), R(right)\nconst vector<pair<int, int>> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"FBLR\";\n\nclass CandyBox {\nprivate:\n    vector<vector<int>> grid; // 0 = empty, 1,2,3 = flavors\n\npublic:\n    CandyBox() : grid(GRID_SIZE, vector<int>(GRID_SIZE, 0)) {}\n\n    void place_candy(int pos, int flavor) {\n        int empty_count = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] == 0) {\n                    empty_count++;\n                    if (empty_count == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulate tilting in given direction\n    void tilt(int dir_idx) {\n        auto [di, dj] = DIRS[dir_idx];\n        \n        if (dir_idx == 0) { // Forward (up) - process top to bottom\n            for (int i = 0; i < GRID_SIZE; i++) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 1) { // Backward (down) - process bottom to top\n            for (int i = GRID_SIZE - 1; i >= 0; i--) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 2) { // Left - process left to right\n            for (int j = 0; j < GRID_SIZE; j++) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else { // Right - process right to left\n            for (int j = GRID_SIZE - 1; j >= 0; j--) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        }\n    }\n\nprivate:\n    void move_candy(int i, int j, int di, int dj) {\n        int flavor = grid[i][j];\n        grid[i][j] = 0;\n        \n        int ni = i + di, nj = j + dj;\n        while (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == 0) {\n            i = ni;\n            j = nj;\n            ni += di;\n            nj += dj;\n        }\n        \n        grid[i][j] = flavor;\n    }\n\npublic:\n    // Simple but effective evaluation: sum of squares of component sizes\n    long long evaluate_clustering() {\n        vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n        long long total_score = 0;\n        \n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int component_size = dfs_component(i, j, grid[i][j], visited);\n                    total_score += (long long)component_size * component_size;\n                }\n            }\n        }\n        \n        return total_score;\n    }\n\nprivate:\n    int dfs_component(int i, int j, int flavor, vector<vector<bool>>& visited) {\n        if (i < 0 || i >= GRID_SIZE || j < 0 || j >= GRID_SIZE || \n            visited[i][j] || grid[i][j] != flavor) {\n            return 0;\n        }\n        \n        visited[i][j] = true;\n        int size = 1;\n        \n        // Check 4 adjacent cells\n        for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n            size += dfs_component(i + di, j + dj, flavor, visited);\n        }\n        \n        return size;\n    }\n\npublic:\n    CandyBox copy() const {\n        CandyBox new_box;\n        new_box.grid = grid;\n        return new_box;\n    }\n    \n    // Count immediate connections (adjacent same-flavor candies)\n    int count_connections() {\n        int connections = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0) {\n                    int flavor = grid[i][j];\n                    // Check adjacent cells\n                    for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n                        int ni = i + di, nj = j + dj;\n                        if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == flavor) {\n                            connections++;\n                        }\n                    }\n                }\n            }\n        }\n        return connections / 2; // Each connection counted twice\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<int> flavors(TOTAL_CANDIES);\n    for (int i = 0; i < TOTAL_CANDIES; i++) {\n        cin >> flavors[i];\n    }\n    \n    CandyBox box;\n    \n    for (int t = 0; t < TOTAL_CANDIES; t++) {\n        int pos;\n        cin >> pos;\n        \n        // Place the candy\n        box.place_candy(pos, flavors[t]);\n        \n        if (t == TOTAL_CANDIES - 1) {\n            // No need to output direction for last candy\n            break;\n        }\n        \n        // Evaluate each possible tilt direction\n        int best_direction = 0;\n        long long best_score = -1;\n        \n        // Try all directions and pick the best one\n        for (int dir = 0; dir < 4; dir++) {\n            CandyBox temp_box = box.copy();\n            temp_box.tilt(dir);\n            long long score = temp_box.evaluate_clustering();\n            \n            // Small bonus for creating more connections\n            score += temp_box.count_connections() * 2;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_direction = dir;\n            }\n        }\n        \n        cout << DIR_CHARS[best_direction] << endl;\n        cout.flush();\n        \n        // Actually perform the tilt\n        box.tilt(best_direction);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n\nusing namespace std;\n\n// Fast I/O optimization\nstatic auto fast_io = []() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n    return 0;\n}();\n\n// Convert adjacency matrix to string representation\nstring graphToString(const vector<vector<int>>& adj, int n) {\n    string result;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            result += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return result;\n}\n\n// Convert string to adjacency matrix\nvector<vector<int>> stringToGraph(const string& s, int n) {\n    vector<vector<int>> adj(n, vector<int>(n, 0));\n    int idx = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[idx] == '1') {\n                adj[i][j] = adj[j][i] = 1;\n            }\n            idx++;\n        }\n    }\n    return adj;\n}\n\n// Count edges\nint countEdges(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            count += adj[i][j];\n        }\n    }\n    return count;\n}\n\n// Generate graphs with systematic edge distribution\nvector<string> generateGraphs(int M, int N) {\n    vector<string> graphs;\n    \n    int max_edges = N * (N - 1) / 2;\n    \n    for (int k = 0; k < M; ++k) {\n        vector<vector<int>> adj(N, vector<int>(N, 0));\n        \n        // Calculate target edge count with better distribution\n        int target_edges = 0;\n        if (M > 1) {\n            target_edges = (k * max_edges) / (M - 1);\n        }\n        \n        // Ensure valid range\n        target_edges = max(0, min(max_edges, target_edges));\n        \n        // Add edges systematically with improved pattern\n        int added = 0;\n        \n        // Use deterministic pattern based on k for better separation\n        for (int i = 0; i < N && added < target_edges; ++i) {\n            for (int j = i + 1; j < N && added < target_edges; ++j) {\n                // Better hash function for more even distribution\n                long long hash = (1LL * i * 11 + 1LL * j * 13 + 1LL * k * 17) % 29;\n                if (hash < 15) {\n                    adj[i][j] = adj[j][i] = 1;\n                    added++;\n                }\n            }\n        }\n        \n        // Fill remaining edges if needed\n        if (added < target_edges) {\n            for (int i = 0; i < N && added < target_edges; ++i) {\n                for (int j = i + 1; j < N && added < target_edges; ++j) {\n                    if (!adj[i][j]) {\n                        adj[i][j] = adj[j][i] = 1;\n                        added++;\n                    }\n                }\n            }\n        }\n        \n        graphs.push_back(graphToString(adj, N));\n    }\n    \n    return graphs;\n}\n\n// Prediction function with slight enhancement\nint predictGraph(const vector<vector<int>>& noisy_adj, int N, int M, double epsilon, \n                 const vector<int>& template_edge_counts) {\n    int edge_count = countEdges(noisy_adj, N);\n    \n    // Find the closest match\n    int best_match = 0;\n    int min_diff = abs(edge_count - template_edge_counts[0]);\n    \n    for (int i = 1; i < M; ++i) {\n        int diff = abs(edge_count - template_edge_counts[i]);\n        if (diff < min_diff) {\n            min_diff = diff;\n            best_match = i;\n        }\n    }\n    \n    return best_match;\n}\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n    \n    // Conservative N selection based on proven good performance\n    int N;\n    if (epsilon > 0.3) {\n        // Very high noise: smaller graphs\n        N = max(6, min(12, 6 + M/8));\n    } else if (epsilon > 0.2) {\n        // High noise\n        N = max(8, min(18, 8 + M/6));\n    } else if (epsilon > 0.1) {\n        // Medium noise\n        N = max(10, min(25, 10 + M/4));\n    } else if (epsilon > 0.05) {\n        // Low-medium noise\n        N = max(12, min(35, 12 + M/3));\n    } else {\n        // Low noise: larger graphs for better discrimination\n        N = max(15, min(50, 15 + M/2));\n    }\n    \n    // Ensure bounds with better minimum for small M\n    if (M <= 20) {\n        N = max(N, 10);  // Ensure decent size for small M\n    }\n    \n    N = min(N, 100);\n    N = max(N, 4);\n    \n    // Generate template graphs\n    auto graphs = generateGraphs(M, N);\n    \n    // Precompute template edge counts\n    vector<int> template_edge_counts(M);\n    for (int i = 0; i < M; ++i) {\n        auto adj = stringToGraph(graphs[i], N);\n        template_edge_counts[i] = countEdges(adj, N);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        auto noisy_adj = stringToGraph(h_str, N);\n        \n        // Predict which graph it came from\n        int prediction = predictGraph(noisy_adj, N, M, epsilon, template_edge_counts);\n        \n        cout << prediction << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<vector<pair<int, int>>> adj;\n\n// Calculate edge scores - simpler but effective approach\nvector<pair<double, int>> scoreEdges() {\n    vector<pair<double, int>> scores(M);\n    \n    for (int i = 0; i < M; i++) {\n        const auto& e = edges[i];\n        \n        // Degree of endpoints\n        int deg_u = adj[e.u].size();\n        int deg_v = adj[e.v].size();\n        \n        // Common neighbors (measure of redundancy)\n        int common_neighbors = 0;\n        vector<bool> neighbor_u(N, false);\n        for (auto& p : adj[e.u]) {\n            if (p.first != e.v) {\n                neighbor_u[p.first] = true;\n            }\n        }\n        for (auto& p : adj[e.v]) {\n            if (p.first != e.u && neighbor_u[p.first]) {\n                common_neighbors++;\n            }\n        }\n        \n        // Criticality score: higher score = more critical (should be repaired later)\n        // Heuristic: lighter edges between low-degree vertices with few alternatives are more critical\n        double score = (1.0 / e.w) * sqrt((double)deg_u * deg_v) / (1.0 + common_neighbors);\n        \n        scores[i] = {score, i};\n    }\n    \n    return scores;\n}\n\n// Assign days with balanced distribution\nvector<int> assignDays() {\n    vector<int> result(M);\n    \n    // Get edge scores\n    auto scores = scoreEdges();\n    \n    // Sort by criticality (ascending - less critical first)\n    sort(scores.begin(), scores.end());\n    \n    // Distribute edges across days\n    vector<int> day_count(D, 0);\n    \n    // Assign edges trying to balance load\n    for (int i = 0; i < M; i++) {\n        int edge_id = scores[i].second;\n        \n        // Find the best day to place this edge\n        int best_day = 0;\n        int min_count = K + 1;\n        \n        // Prefer days under the limit with fewer edges\n        for (int day = 0; day < D; day++) {\n            if (day_count[day] < K && day_count[day] < min_count) {\n                min_count = day_count[day];\n                best_day = day;\n            }\n        }\n        \n        // If all days are at capacity, put in the least loaded day\n        if (min_count == K + 1) {\n            min_count = INF;\n            for (int day = 0; day < D; day++) {\n                if (day_count[day] < min_count) {\n                    min_count = day_count[day];\n                    best_day = day;\n                }\n            }\n        }\n        \n        result[edge_id] = best_day + 1;\n        day_count[best_day]++;\n    }\n    \n    return result;\n}\n\n// Simple fallback approach based purely on weights\nvector<int> weightBasedAssignment() {\n    vector<int> result(M);\n    \n    // Sort edges by weight (lighter edges first - more critical)\n    vector<pair<int, int>> weights(M);\n    for (int i = 0; i < M; i++) {\n        weights[i] = {edges[i].w, i};\n    }\n    sort(weights.begin(), weights.end());\n    \n    // Assign to days sequentially\n    for (int i = 0; i < M; i++) {\n        int edge_id = weights[i].second;\n        int day = min(i / K, D - 1);\n        result[edge_id] = day + 1;\n    }\n    \n    // Ensure we don't exceed K edges per day\n    vector<int> day_count(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_count[result[i]]++;\n    }\n    \n    // Fix violations by redistribution\n    vector<vector<int>> day_edges(D);\n    for (int i = 0; i < M; i++) {\n        day_edges[result[i] - 1].push_back(i);\n    }\n    \n    for (int day = 0; day < D; day++) {\n        while (day_edges[day].size() > K) {\n            int edge_id = day_edges[day].back();\n            day_edges[day].pop_back();\n            \n            // Find a day with space\n            bool placed = false;\n            for (int target_day = 0; target_day < D; target_day++) {\n                if (day_edges[target_day].size() < K) {\n                    day_edges[target_day].push_back(edge_id);\n                    result[edge_id] = target_day + 1;\n                    placed = true;\n                    break;\n                }\n            }\n            // If no space found, put in last resort day\n            if (!placed) {\n                if (day != D - 1) {\n                    day_edges[D - 1].push_back(edge_id);\n                    result[edge_id] = D;\n                }\n            }\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 >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--; // Convert to 0-indexed\n        edges[i] = {u, v, w, i};\n    }\n    \n    // Skip coordinate input\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Build adjacency list\n    adj.assign(N, vector<pair<int, int>>());\n    for (const auto& e : edges) {\n        adj[e.u].push_back({e.v, e.w});\n        adj[e.v].push_back({e.u, e.w});\n    }\n    \n    // Use the better approach from solution 3\n    vector<int> result = assignDays();\n    \n    // Output result\n    for (int i = 0; i < M; i++) {\n        cout << result[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_D = 14;\nint D;\nchar f[2][MAX_D][MAX_D];\nchar r[2][MAX_D][MAX_D];\n\n// 3D grid for each construction\nint b[2][MAX_D][MAX_D][MAX_D];\n\n// Directions for 6-connectivity\nconst int dx[6] = {1, -1, 0, 0, 0, 0};\nconst int dy[6] = {0, 0, 1, -1, 0, 0};\nconst int dz[6] = {0, 0, 0, 0, 1, -1};\n\nbool isValid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n\n// Simple BFS to find connected component\nvector<tuple<int,int,int>> findComponent(int grid[MAX_D][MAX_D][MAX_D], \n                                        vector<vector<vector<bool>>>& visited,\n                                        int start_x, int start_y, int start_z) {\n    vector<tuple<int,int,int>> component;\n    \n    if (!isValid(start_x, start_y, start_z) || \n        grid[start_x][start_y][start_z] == 0 || \n        visited[start_x][start_y][start_z]) {\n        return component;\n    }\n    \n    queue<tuple<int,int,int>> q;\n    q.push({start_x, start_y, start_z});\n    visited[start_x][start_y][start_z] = true;\n    component.push_back({start_x, start_y, start_z});\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front(); q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            \n            if (isValid(nx, ny, nz) && \n                !visited[nx][ny][nz] && \n                grid[nx][ny][nz] == 1) {\n                visited[nx][ny][nz] = true;\n                q.push({nx, ny, nz});\n                component.push_back({nx, ny, nz});\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read input\n    for (int i = 0; i < 2; i++) {\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int x = 0; x < D; x++) {\n                f[i][z][x] = line[x];\n            }\n        }\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int y = 0; y < D; y++) {\n                r[i][z][y] = line[y];\n            }\n        }\n    }\n    \n    // Initialize grids - place unit cubes where both silhouettes allow\n    int valid_cubes[2][MAX_D][MAX_D][MAX_D] = {0};\n    \n    for (int constr = 0; constr < 2; constr++) {\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[constr][z][x] == '1' && r[constr][z][y] == '1') {\n                        valid_cubes[constr][x][y][z] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Reset output grid\n    memset(b, 0, sizeof(b));\n    \n    // For each construction, find connected components and assign block IDs\n    int block_id_counter = 1;\n    \n    for (int constr = 0; constr < 2; constr++) {\n        vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (valid_cubes[constr][x][y][z] == 1 && !visited[x][y][z]) {\n                        // Found a new component\n                        auto component = findComponent(valid_cubes[constr], visited, x, y, z);\n                        \n                        if (!component.empty()) {\n                            // Assign a new block ID to this entire component\n                            int current_block_id = block_id_counter++;\n                            \n                            for (const auto& cube : component) {\n                                int cx = get<0>(cube);\n                                int cy = get<1>(cube);\n                                int cz = get<2>(cube);\n                                b[constr][cx][cy][cz] = current_block_id;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output result\n    cout << (block_id_counter - 1) << \"\\n\";\n    \n    for (int constr = 0; constr < 2; constr++) {\n        bool first = true;\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (!first) cout << \" \";\n                    cout << b[constr][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\nusing ld = long double;\nusing pii = pair<int, int>;\nusing pll = pair<ll, ll>;\n\nconst int MAX_N = 100;\nconst int MAX_M = 300;\nconst int MAX_K = 5000;\nconst int MAX_POWER = 5000;\n\nint N, M, K;\nvector<pair<int, int>> vertices;\nvector<tuple<int, int, int>> edges;\nvector<pair<int, int>> residents;\n\n// Distance calculation\nint euclidean_distance(int i, int j) {\n    int dx = vertices[i].first - vertices[j].first;\n    int dy = vertices[i].second - vertices[j].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\nint resident_to_vertex_distance(int res_idx, int vert_idx) {\n    int dx = residents[res_idx].first - vertices[vert_idx].first;\n    int dy = residents[res_idx].second - vertices[vert_idx].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\n// Find minimum spanning tree using Prim's algorithm\nvector<bool> find_mst_edges() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vertex_reached[0] = true; // Start from vertex 1 (index 0)\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    \n    // Add all edges from vertex 1\n    for (int j = 0; j < M; j++) {\n        auto [u, v, w] = edges[j];\n        u--; v--; // Convert to 0-indexed\n        if (u == 0) {\n            pq.push({w, v, j});\n        } else if (v == 0) {\n            pq.push({w, u, j});\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [weight, to, edge_idx] = pq.top();\n        pq.pop();\n        \n        if (vertex_reached[to]) continue;\n        \n        vertex_reached[to] = true;\n        edge_used[edge_idx] = true;\n        \n        // Add edges from newly reached vertex\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            if (u == to && !vertex_reached[v]) {\n                pq.push({w, v, j});\n            } else if (v == to && !vertex_reached[u]) {\n                pq.push({w, u, j});\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\n// Calculate minimum power needed for each vertex to cover residents\nvector<int> calculate_min_power(const vector<bool>& vertex_active) {\n    vector<int> power(N, 0);\n    vector<bool> covered(K, false);\n    \n    // First pass: calculate required power for each active vertex\n    for (int i = 0; i < N; i++) {\n        if (!vertex_active[i]) continue;\n        \n        int max_dist = 0;\n        for (int k = 0; k < K; k++) {\n            int dist = resident_to_vertex_distance(k, i);\n            if (dist <= MAX_POWER) {\n                max_dist = max(max_dist, dist);\n            }\n        }\n        power[i] = max_dist;\n    }\n    \n    // Greedy approach: iteratively improve coverage\n    for (int iter = 0; iter < 3; iter++) {\n        fill(covered.begin(), covered.end(), false);\n        \n        // Mark covered residents\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i] || power[i] == 0) continue;\n            for (int k = 0; k < K; k++) {\n                if (resident_to_vertex_distance(k, i) <= power[i]) {\n                    covered[k] = true;\n                }\n            }\n        }\n        \n        // Find uncovered residents\n        vector<int> uncovered;\n        for (int k = 0; k < K; k++) {\n            if (!covered[k]) uncovered.push_back(k);\n        }\n        \n        if (uncovered.empty()) break;\n        \n        // For each active vertex, see how much additional power helps\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i]) continue;\n            \n            int max_needed = 0;\n            for (int k : uncovered) {\n                int dist = resident_to_vertex_distance(k, i);\n                if (dist <= MAX_POWER) {\n                    max_needed = max(max_needed, dist);\n                }\n            }\n            power[i] = max(power[i], max_needed);\n        }\n    }\n    \n    return power;\n}\n\n// Improved approach: use a more sophisticated method\nvector<bool> improved_edge_selection() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vector<bool> resident_covered(K, false);\n    vertex_reached[0] = true;\n    \n    // Precompute resident distances to all vertices\n    vector<vector<int>> resident_distances(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resident_distances[k][i] = resident_to_vertex_distance(k, i);\n        }\n    }\n    \n    // Greedily select edges that maximize coverage efficiency\n    for (int step = 0; step < N - 1; step++) {\n        int best_edge = -1;\n        double best_efficiency = -1e18;\n        \n        // Find the best edge to add\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            \n            // Check if this edge connects a reached and unreached vertex\n            bool connects = (vertex_reached[u] && !vertex_reached[v]) || \n                           (vertex_reached[v] && !vertex_reached[u]);\n            \n            if (!connects) continue;\n            \n            int new_vertex = vertex_reached[u] ? v : u;\n            \n            // Calculate how many new residents this would cover\n            int new_coverage = 0;\n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k] && resident_distances[k][new_vertex] <= MAX_POWER) {\n                    new_coverage++;\n                }\n            }\n            \n            // Efficiency = coverage per cost\n            double efficiency = (double)new_coverage / max(w, 1);\n            \n            if (efficiency > best_efficiency) {\n                best_efficiency = efficiency;\n                best_edge = j;\n            }\n        }\n        \n        if (best_edge == -1) break;\n        \n        edge_used[best_edge] = true;\n        auto [u, v, w] = edges[best_edge];\n        u--; v--;\n        int new_vertex = vertex_reached[u] ? v : u;\n        vertex_reached[new_vertex] = true;\n        \n        // Update covered residents\n        for (int k = 0; k < K; k++) {\n            if (resident_distances[k][new_vertex] <= MAX_POWER) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    \n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    edges.resize(M);\n    for (int j = 0; j < M; j++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n    }\n    \n    residents.resize(K);\n    for (int k = 0; k < K; k++) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n    \n    // Select edges using improved approach\n    vector<bool> edge_used = improved_edge_selection();\n    \n    // Determine which vertices are active\n    vector<bool> vertex_active(N, false);\n    vertex_active[0] = true; // Always include vertex 1\n    \n    // BFS to find all reachable vertices\n    queue<int> q;\n    q.push(0);\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int j = 0; j < M; j++) {\n            if (!edge_used[j]) continue;\n            \n            auto [v1, v2, w] = edges[j];\n            v1--; v2--; // Convert to 0-indexed\n            \n            if (v1 == u && !vertex_active[v2]) {\n                vertex_active[v2] = true;\n                q.push(v2);\n            } else if (v2 == u && !vertex_active[v1]) {\n                vertex_active[v1] = true;\n                q.push(v1);\n            }\n        }\n    }\n    \n    // Calculate power requirements\n    vector<int> power = calculate_min_power(vertex_active);\n    \n    // Output results\n    for (int i = 0; i < N; i++) {\n        cout << power[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    for (int j = 0; j < M; j++) {\n        cout << (edge_used[j] ? 1 : 0);\n        if (j < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 10000;\nconst int TOTAL_BALLS = N * (N + 1) / 2;\n\nstruct Position {\n    int x, y;\n    Position() : x(0), y(0) {}\n    Position(int _x, int _y) : x(_x), y(_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\n// Directions for adjacency (6 directions in triangular grid)\nconst vector<pair<int, int>> DIRECTIONS = {\n    {-1, -1}, {-1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1}\n};\n\nclass Pyramid {\npublic:\n    int grid[N][N];\n    vector<pair<Position, Position>> operations;\n    \n    Pyramid() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                cin >> grid[i][j];\n            }\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y <= x;\n    }\n    \n    bool is_adjacent(int x1, int y1, int x2, int y2) {\n        for (auto& dir : DIRECTIONS) {\n            int nx = x1 + dir.first;\n            int ny = y1 + dir.second;\n            if (nx == x2 && ny == y2) return true;\n        }\n        return false;\n    }\n    \n    vector<Position> get_neighbors(int x, int y) {\n        vector<Position> neighbors;\n        for (auto& dir : DIRECTIONS) {\n            int nx = x + dir.first;\n            int ny = y + dir.second;\n            if (is_valid(nx, ny)) {\n                neighbors.emplace_back(nx, ny);\n            }\n        }\n        return neighbors;\n    }\n    \n    int count_violations() {\n        int count = 0;\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] > grid[i+1][j]) count++;\n                if (grid[i][j] > grid[i+1][j+1]) count++;\n            }\n        }\n        return count;\n    }\n    \n    void swap_balls(int x1, int y1, int x2, int y2) {\n        if (!is_adjacent(x1, y1, x2, y2)) return;\n        if (operations.size() >= MAX_OPS) return;\n        \n        swap(grid[x1][y1], grid[x2][y2]);\n        operations.emplace_back(Position(x1, y1), Position(x2, y2));\n    }\n    \n    // Find position of a specific value\n    Position find_position(int value) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] == value) {\n                    return Position(i, j);\n                }\n            }\n        }\n        return Position(-1, -1);\n    }\n    \n    void output() {\n        cout << operations.size() << \"\\n\";\n        for (auto& op : operations) {\n            cout << op.first.x << \" \" << op.first.y << \" \" \n                 << op.second.x << \" \" << op.second.y << \"\\n\";\n        }\n    }\n    \n    // Bubble sort approach: move larger elements down\n    void bubble_sort_approach() {\n        // Multiple passes of bubble sort-like approach\n        for (int pass = 0; pass < 20 && operations.size() < MAX_OPS - 10; pass++) {\n            bool changed = false;\n            \n            // Go through each level from top to bottom-1\n            for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 2; level++) {\n                // Go through each position in the level\n                for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 2; pos++) {\n                    int current = grid[level][pos];\n                    int left_child = grid[level+1][pos];\n                    int right_child = grid[level+1][pos+1];\n                    \n                    // If current is larger than either child, swap with the smaller child\n                    if (current > left_child || current > right_child) {\n                        if (left_child <= right_child) {\n                            swap_balls(level, pos, level+1, pos);\n                        } else {\n                            swap_balls(level, pos, level+1, pos+1);\n                        }\n                        changed = true;\n                    }\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n    \n    // Improved approach: work systematically level by level\n    void systematic_approach() {\n        // For each position, try to get the minimum valid value there\n        for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 5; level++) {\n            for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 5; pos++) {\n                // Ensure this position has value <= both children\n                int& current = grid[level][pos];\n                int& left_child = grid[level+1][pos];\n                int& right_child = grid[level+1][pos+1];\n                \n                // Keep swapping down while violation exists\n                while ((current > left_child || current > right_child) && operations.size() < MAX_OPS - 1) {\n                    if (current > left_child && (current > right_child ? left_child <= right_child : true)) {\n                        swap_balls(level, pos, level+1, pos);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else if (current > right_child) {\n                        swap_balls(level, pos, level+1, pos+1);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Local optimization: fix immediate violations\n    void local_optimization() {\n        bool improved = true;\n        int iterations = 0;\n        const int MAX_ITERATIONS = 50;\n        \n        while (improved && iterations < MAX_ITERATIONS && operations.size() < MAX_OPS - 10) {\n            improved = false;\n            iterations++;\n            \n            // Scan through all positions and fix violations\n            for (int i = 0; i < N - 1 && operations.size() < MAX_OPS - 2; i++) {\n                for (int j = 0; j <= i && operations.size() < MAX_OPS - 2; j++) {\n                    int current = grid[i][j];\n                    int left_child = grid[i+1][j];\n                    int right_child = grid[i+1][j+1];\n                    \n                    // Fix violations\n                    if (current > left_child || current > right_child) {\n                        // Swap with smaller child\n                        if (left_child <= right_child) {\n                            swap_balls(i, j, i+1, j);\n                        } else {\n                            swap_balls(i, j, i+1, j+1);\n                        }\n                        improved = true;\n                        if (operations.size() >= MAX_OPS - 2) break;\n                    }\n                }\n                if (operations.size() >= MAX_OPS - 2) break;\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    Pyramid pyramid;\n    pyramid.read_input();\n    \n    // Try multiple strategies\n    pyramid.systematic_approach();\n    pyramid.local_optimization();\n    pyramid.bubble_sort_approach();\n    pyramid.local_optimization();\n    \n    pyramid.output();\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int D = 9;\nconst int ENTRANCE_ROW = 0;\nconst int ENTRANCE_COL = 4;\n\nint N;\nbool is_obstacle[D][D];\nbool has_container[D][D];\nint container_number[D][D];\nvector<pair<int, int>> obstacles;\n\n// Directions: up, down, left, right\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\n\n// Check if coordinates are valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\n// Check if a cell is the entrance\nbool is_entrance(int x, int y) {\n    return x == ENTRANCE_ROW && y == ENTRANCE_COL;\n}\n\n// BFS to find all reachable empty cells from entrance\nvector<vector<bool>> get_reachable() {\n    vector<vector<bool>> reachable(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    reachable[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !has_container[nx][ny] && !reachable[nx][ny]) {\n                reachable[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\n// BFS to find all reachable cells with containers from entrance\nvector<pair<int, int>> get_reachable_containers() {\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    vector<pair<int, int>> result;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    visited[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        // If this cell has a container, add it to result\n        if (has_container[x][y]) {\n            result.push_back({x, y});\n        }\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Calculate Manhattan distance from entrance\nint manhattan_distance(int x, int y) {\n    return abs(x - ENTRANCE_ROW) + abs(y - ENTRANCE_COL);\n}\n\n// Find best position to place a container\npair<int, int> find_best_position(int container_num, int total_containers) {\n    auto reachable = get_reachable();\n    \n    pair<int, int> best_pos = {-1, -1};\n    double best_score = -1e18;\n    \n    // Try all positions\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            // Skip if it's entrance, obstacle, or already has container\n            if (is_entrance(i, j) || is_obstacle[i][j] || has_container[i][j]) {\n                continue;\n            }\n            \n            // Skip if not reachable\n            if (!reachable[i][j]) {\n                continue;\n            }\n            \n            // Calculate score based on multiple factors\n            double distance_score = -manhattan_distance(i, j) * 0.1;\n            double position_score = 0;\n            \n            // Prefer positions that are less likely to block others\n            // Count how many cells would become unreachable if we place container here\n            has_container[i][j] = true;\n            auto new_reachable = get_reachable();\n            has_container[i][j] = false;\n            \n            int blocked_count = 0;\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (!is_entrance(x, y) && !is_obstacle[x][y] && !has_container[x][y]) {\n                        if (reachable[x][y] && !new_reachable[x][y]) {\n                            blocked_count++;\n                        }\n                    }\n                }\n            }\n            \n            double blocking_penalty = -blocked_count * 0.5;\n            \n            // Prefer corners and edges for higher numbers\n            double edge_bonus = 0;\n            if (i == 0 || i == D-1 || j == 0 || j == D-1) {\n                edge_bonus = 0.2;\n            }\n            \n            // For later containers, prefer positions further from entrance\n            double adaptive_distance = (double)container_num / total_containers;\n            double adaptive_score = -(manhattan_distance(i, j) - 4 * adaptive_distance) * 0.1;\n            \n            double total_score = distance_score + blocking_penalty + edge_bonus + adaptive_score;\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_pos = {i, j};\n            }\n        }\n    }\n    \n    return best_pos;\n}\n\nint main() {\n    // Read input\n    cin >> D >> N;\n    \n    // Initialize arrays\n    memset(is_obstacle, false, sizeof(is_obstacle));\n    memset(has_container, false, sizeof(has_container));\n    \n    // Read obstacles\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        obstacles.push_back({r, c});\n    }\n    \n    int total_containers = D * D - 1 - N;\n    vector<pair<int, int>> placement_order(total_containers);\n    \n    // Process each container as it arrives\n    for (int d = 0; d < total_containers; d++) {\n        int container_num;\n        cin >> container_num;\n        \n        // Find best position\n        auto pos = find_best_position(container_num, total_containers);\n        \n        // Place container\n        has_container[pos.first][pos.second] = true;\n        container_number[pos.first][pos.second] = container_num;\n        placement_order[d] = pos;\n        \n        // Output position\n        cout << pos.first << \" \" << pos.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieve containers in optimal order\n    vector<pair<int, int>> retrieval_order;\n    vector<bool> transported(total_containers, false);\n    \n    // Greedy approach: always pick the smallest accessible container number\n    while (retrieval_order.size() < total_containers) {\n        auto reachable_containers = get_reachable_containers();\n        \n        // Find the container with minimum number among reachable ones\n        int min_num = INT_MAX;\n        pair<int, int> best_container = {-1, -1};\n        \n        for (auto& pos : reachable_containers) {\n            int num = container_number[pos.first][pos.second];\n            if (num < min_num) {\n                min_num = num;\n                best_container = pos;\n            }\n        }\n        \n        // Remove this container and add to retrieval order\n        has_container[best_container.first][best_container.second] = false;\n        retrieval_order.push_back(best_container);\n    }\n    \n    // Output retrieval order\n    for (auto& pos : retrieval_order) {\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n = 50, m = 100;\nint input_grid[N][N];\nint output_grid[N][N];\n\n// Adjacency information\nvector<set<int>> adj_list(M + 1);\nvector<vector<bool>> is_adj(M + 1, vector<bool>(M + 1, false));\n\n// Position information for each color\nvector<vector<pair<int, int>>> color_positions(M + 1);\n\n// Find connected components and adjacencies\nvoid analyze_input() {\n    // Collect positions for each color\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            color_positions[color].push_back({i, j});\n        }\n    }\n    \n    // Find adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            // Check 4 directions\n            int dx[] = {-1, 1, 0, 0};\n            int dy[] = {0, 0, -1, 1};\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int neighbor_color = input_grid[ni][nj];\n                    if (color != neighbor_color) {\n                        is_adj[color][neighbor_color] = true;\n                        is_adj[neighbor_color][color] = true;\n                        adj_list[color].insert(neighbor_color);\n                        adj_list[neighbor_color].insert(color);\n                    }\n                } else {\n                    // Boundary - adjacent to outside (color 0)\n                    is_adj[color][0] = true;\n                    is_adj[0][color] = true;\n                    adj_list[color].insert(0);\n                    adj_list[0].insert(color);\n                }\n            }\n        }\n    }\n}\n\n// Simple greedy approach: place colors in a compact way\nvoid generate_output() {\n    // Initialize output grid with 0s\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output_grid[i][j] = 0;\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from center\n    int center_x = N / 2;\n    int center_y = N / 2;\n    \n    // Place color 0 (outside) everywhere first\n    // Then we'll overwrite with other colors\n    \n    vector<bool> placed(M + 1, false);\n    placed[0] = true;\n    \n    // Place colors in order, trying to make them adjacent as required\n    queue<int> to_place;\n    set<int> remaining;\n    \n    for (int i = 1; i <= m; i++) {\n        remaining.insert(i);\n    }\n    \n    // Start with color 1 at center\n    output_grid[center_x][center_y] = 1;\n    placed[1] = true;\n    remaining.erase(1);\n    to_place.push(1);\n    \n    // BFS-like placement to maintain adjacencies\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    while (!to_place.empty() && !remaining.empty()) {\n        int current_color = to_place.front();\n        to_place.pop();\n        \n        // Find adjacent positions that are still 0\n        vector<pair<int, int>> adjacent_empty;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (output_grid[i][j] == current_color) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dx[k];\n                        int nj = j + dy[k];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            if (output_grid[ni][nj] == 0) {\n                                adjacent_empty.push_back({ni, nj});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Place adjacent colors\n        for (int adj_color : adj_list[current_color]) {\n            if (!placed[adj_color] && !remaining.empty() && find(remaining.begin(), remaining.end(), adj_color) != remaining.end()) {\n                if (!adjacent_empty.empty()) {\n                    auto pos = adjacent_empty.back();\n                    adjacent_empty.pop_back();\n                    output_grid[pos.first][pos.second] = adj_color;\n                    placed[adj_color] = true;\n                    remaining.erase(adj_color);\n                    to_place.push(adj_color);\n                }\n            }\n        }\n    }\n    \n    // Place any remaining colors\n    for (int color : remaining) {\n        // Find any empty spot\n        bool placed_color = false;\n        for (int i = 0; i < N && !placed_color; i++) {\n            for (int j = 0; j < N && !placed_color; j++) {\n                if (output_grid[i][j] == 0) {\n                    output_grid[i][j] = color;\n                    placed_color = true;\n                }\n            }\n        }\n    }\n    \n    // Expand each color to make connected regions\n    for (int color = 1; color <= m; color++) {\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_grid[i][j] == color) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.empty()) continue;\n        \n        // Use BFS to expand this color to make it more connected\n        queue<pair<int, int>> q;\n        set<pair<int, int>> visited;\n        \n        for (auto pos : positions) {\n            q.push(pos);\n            visited.insert(pos);\n        }\n        \n        int expansions = min(3, 20 - (int)positions.size()); // Limit expansion\n        int expanded = 0;\n        \n        while (!q.empty() && expanded < expansions) {\n            auto current = q.front();\n            q.pop();\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = current.first + dx[k];\n                int nj = current.second + dy[k];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (output_grid[ni][nj] == 0 && visited.find({ni, nj}) == visited.end()) {\n                        output_grid[ni][nj] = color;\n                        visited.insert({ni, nj});\n                        q.push({ni, nj});\n                        expanded++;\n                        if (expanded >= expansions) break;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input_grid[i][j];\n        }\n    }\n    \n    // Analyze the input to understand adjacencies\n    analyze_input();\n    \n    // Generate optimized output\n    generate_output();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << output_grid[i][j];\n            if (j < N - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 105;\nconst double EPS = 1e-12;\n\nint N, D, Q;\nvector<vector<int>> win_count, total_count;\nvector<double> weight_estimates;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to query the balance\nstring query(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 result;\n    cin >> result;\n    return result;\n}\n\n// Weight estimation - simpler and more robust\nvoid estimate_weights() {\n    // Initialize comparison matrices\n    win_count.assign(N, vector<int>(N, 0));\n    total_count.assign(N, vector<int>(N, 0));\n    \n    int queries_used = 0;\n    \n    // Generate all pairs\n    vector<pair<int, int>> all_pairs;\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            all_pairs.push_back({i, j});\n        }\n    }\n    \n    // Shuffle pairs\n    shuffle(all_pairs.begin(), all_pairs.end(), rng);\n    \n    // Make pairwise comparisons\n    int pairwise_limit = min(Q, (int)all_pairs.size());\n    \n    for (int i = 0; i < pairwise_limit && queries_used < Q; i++) {\n        int a = all_pairs[i].first;\n        int b = all_pairs[i].second;\n        \n        vector<int> left = {a};\n        vector<int> right = {b};\n        string result = query(left, right);\n        queries_used++;\n        \n        total_count[a][b]++;\n        total_count[b][a]++;\n        \n        if (result == \">\") {\n            win_count[a][b]++;\n        } else if (result == \"<\") {\n            win_count[b][a]++;\n        } else { // '='\n            win_count[a][b]++;\n            win_count[b][a]++;\n        }\n    }\n    \n    // Simple scoring: items that win more are heavier\n    weight_estimates.assign(N, 0.0);\n    \n    for (int i = 0; i < N; i++) {\n        int total_wins = 0;\n        int total_comparisons = 0;\n        \n        for (int j = 0; j < N; j++) {\n            if (i != j && total_count[i][j] > 0) {\n                total_wins += win_count[i][j];\n                total_comparisons += total_count[i][j];\n            }\n        }\n        \n        if (total_comparisons > 0) {\n            weight_estimates[i] = (double)total_wins / total_comparisons;\n        } else {\n            weight_estimates[i] = 0.5; // Default\n        }\n    }\n}\n\n// Multi-way partitioning - LPT algorithm\nvector<int> multi_way_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Create list of items sorted by weight (descending)\n    vector<pair<double, int>> sorted_items;\n    for (int i = 0; i < N; i++) {\n        sorted_items.push_back({weight_estimates[i], i});\n    }\n    sort(sorted_items.rbegin(), sorted_items.rend());\n    \n    // Assign each item to the group with minimum current sum\n    for (const auto& item : sorted_items) {\n        double weight = item.first;\n        int item_id = item.second;\n        \n        int best_group = 0;\n        double min_sum = group_sums[0];\n        \n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    return assignment;\n}\n\n// Local search improvement\nvector<int> local_search(vector<int> initial_assignment) {\n    vector<int> assignment = initial_assignment;\n    vector<double> group_sums(D, 0.0);\n    \n    // Calculate initial group sums\n    for (int i = 0; i < N; i++) {\n        group_sums[assignment[i]] += weight_estimates[i];\n    }\n    \n    // Local search\n    bool improved = true;\n    int stagnation = 0;\n    const int MAX_STAGNATION = 50;\n    \n    while (improved && stagnation < MAX_STAGNATION) {\n        improved = false;\n        \n        // Try moving each item to a different group\n        for (int i = 0; i < N; i++) {\n            int current_group = assignment[i];\n            double item_weight = weight_estimates[i];\n            \n            for (int new_group = 0; new_group < D; new_group++) {\n                if (new_group == current_group) continue;\n                \n                // Calculate current variance\n                double current_mean = 0;\n                for (int g = 0; g < D; g++) current_mean += group_sums[g];\n                current_mean /= D;\n                \n                double current_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    double diff = group_sums[g] - current_mean;\n                    current_variance += diff * diff;\n                }\n                current_variance /= D;\n                \n                // Simulate move\n                group_sums[current_group] -= item_weight;\n                group_sums[new_group] += item_weight;\n                \n                // Calculate new variance\n                double new_mean = 0;\n                for (int g = 0; g < D; g++) new_mean += group_sums[g];\n                new_mean /= D;\n                \n                double new_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    double diff = group_sums[g] - new_mean;\n                    new_variance += diff * diff;\n                }\n                new_variance /= D;\n                \n                // Accept improving move\n                if (new_variance < current_variance - EPS) {\n                    assignment[i] = new_group;\n                    improved = true;\n                    stagnation = 0;\n                    break;\n                } else {\n                    // Revert move\n                    group_sums[current_group] += item_weight;\n                    group_sums[new_group] -= item_weight;\n                }\n            }\n            \n            if (improved) break;\n        }\n        \n        if (!improved) {\n            stagnation++;\n        }\n    }\n    \n    return assignment;\n}\n\n// Simple greedy as alternative\nvector<int> simple_greedy() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Assign items in order of estimated weight (heaviest first)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.push_back({weight_estimates[i], i});\n    }\n    sort(items.rbegin(), items.rend());\n    \n    for (const auto& item : items) {\n        int item_id = item.second;\n        \n        // Find group with minimum sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight_estimates[item_id];\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Estimate weights\n    estimate_weights();\n    \n    // Generate multiple solutions and pick the best\n    vector<int> solution1 = multi_way_partition();\n    vector<int> solution2 = local_search(solution1);\n    vector<int> solution3 = simple_greedy();\n    \n    // Evaluate solutions\n    auto evaluate_variance = [&](const vector<int>& assignment) -> double {\n        vector<double> sums(D, 0.0);\n        for (int i = 0; i < N; i++) {\n            sums[assignment[i]] += weight_estimates[i];\n        }\n        \n        double mean = 0;\n        for (int g = 0; g < D; g++) mean += sums[g];\n        mean /= D;\n        \n        double variance = 0;\n        for (int g = 0; g < D; g++) {\n            double diff = sums[g] - mean;\n            variance += diff * diff;\n        }\n        variance /= D;\n        \n        return variance;\n    };\n    \n    double var1 = evaluate_variance(solution1);\n    double var2 = evaluate_variance(solution2);\n    double var3 = evaluate_variance(solution3);\n    \n    // Output best solution\n    vector<int> best_solution;\n    if (var1 <= var2 && var1 <= var3) {\n        best_solution = solution1;\n    } else if (var2 <= var3) {\n        best_solution = solution2;\n    } else {\n        best_solution = solution3;\n    }\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        cout << best_solution[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 200;\nconst int M = 10;\nconst int STACK_SIZE = N / M;\n\nstruct State {\n    vector<deque<int>> stacks;\n    vector<pair<int, int>> box_positions; // {stack_idx, position_in_stack}\n    vector<bool> removed;\n    int total_energy = 0;\n    vector<pair<int, int>> operations;\n    \n    State() : stacks(M), box_positions(N + 1), removed(N + 1, false) {}\n    \n    void initialize() {\n        for (int i = 0; i < M; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                int box = stacks[i][j];\n                box_positions[box] = {i, j};\n            }\n        }\n    }\n    \n    bool is_top(int box) {\n        auto [stack_idx, pos] = box_positions[box];\n        return pos == (int)stacks[stack_idx].size() - 1;\n    }\n    \n    int stack_height(int stack_idx) {\n        return stacks[stack_idx].size();\n    }\n    \n    pair<int, int> find_box_position(int box) {\n        return box_positions[box];\n    }\n};\n\nclass Solver {\nprivate:\n    State state;\n    \npublic:\n    Solver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Move target box to top if not already there\n            while (!state.is_top(target)) {\n                auto [stack_idx, pos] = state.find_box_position(target);\n                int boxes_above = state.stack_height(stack_idx) - pos - 1;\n                \n                // Find best destination stack\n                int best_dest = -1;\n                int min_cost = INT_MAX;\n                \n                for (int dest = 0; dest < M; dest++) {\n                    if (dest == stack_idx) continue;\n                    \n                    // Cost is number of boxes moved + 1\n                    int cost = boxes_above + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_dest = dest;\n                    }\n                }\n                \n                if (best_dest == -1) {\n                    // Fallback: pick any different stack\n                    best_dest = (stack_idx + 1) % M;\n                }\n                \n                // Execute move\n                execute_move(target, best_dest);\n            }\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\n// Improved solver with better heuristics\nclass ImprovedSolver {\nprivate:\n    State state;\n    \npublic:\n    ImprovedSolver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Bring target to top with optimized strategy\n            bring_to_top(target);\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void bring_to_top(int target) {\n        while (!state.is_top(target)) {\n            auto [source_stack, pos] = state.find_box_position(target);\n            int boxes_above = state.stack_height(source_stack) - pos - 1;\n            \n            // Smart destination selection\n            int best_dest = find_best_destination(source_stack, boxes_above);\n            \n            // Execute move\n            execute_move(target, best_dest);\n        }\n    }\n    \n    int find_best_destination(int source_stack, int boxes_above) {\n        // Prefer stacks with fewer boxes to minimize future conflicts\n        int best_dest = -1;\n        int min_height = INT_MAX;\n        \n        for (int dest = 0; dest < M; dest++) {\n            if (dest == source_stack) continue;\n            \n            int height = state.stack_height(dest);\n            if (height < min_height) {\n                min_height = height;\n                best_dest = dest;\n            }\n        }\n        \n        // If all stacks are full, pick one that's not the source\n        if (best_dest == -1) {\n            best_dest = (source_stack + 1) % M;\n        }\n        \n        return best_dest;\n    }\n    \n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    ImprovedSolver solver(stacks);\n    vector<pair<int, int>> operations = solver.solve();\n    \n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\nbool visited[MAXN][MAXN];\n\n// Directions: Right, Down, Left, Up\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\n// Check if we can move from (i,j) to direction dir\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check for walls\n    if (dir == 0 || dir == 2) { // Horizontal move\n        return v[i][min(j, nj)] == '0';\n    } else { // Vertical move\n        return h[min(i, ni)][j] == '0';\n    }\n}\n\n// DFS with priority to high dirtiness squares\nvoid dfs_priority(int i, int j, string& path) {\n    visited[i][j] = true;\n    \n    // Create list of valid unvisited neighbors\n    vector<pair<int, int>> neighbors;\n    for (int dir = 0; dir < 4; dir++) {\n        if (!can_move(i, j, dir)) continue;\n        \n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj]) {\n            neighbors.push_back({d[ni][nj], dir});\n        }\n    }\n    \n    // Sort by dirtiness (descending)\n    sort(neighbors.begin(), neighbors.end(), greater<pair<int, int>>());\n    \n    for (auto& neighbor : neighbors) {\n        int dir = neighbor.second;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        path += dir_char[dir];\n        dfs_priority(ni, nj, path);\n        path += dir_char[(dir + 2) % 4]; // Return move\n    }\n}\n\n// Create a more sophisticated path by doing multiple DFS passes\nvoid create_path(string& path) {\n    // First, do a basic DFS to ensure all squares are visited\n    memset(visited, false, sizeof(visited));\n    dfs_priority(0, 0, path);\n    \n    // If we have space, add more visits to high-value squares\n    if (path.length() < 80000) {\n        // Add a second pass, but be more selective\n        // We could implement a more complex strategy here\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    // Read dirtiness values\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    string path = \"\";\n    create_path(path);\n    \n    // Make sure path isn't too long\n    if (path.length() > 100000) {\n        path = path.substr(0, 100000);\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\nint n, m;\nint start_i, start_j;\nchar grid[N][N];\nvector<string> targets;\nvector<pair<int,int>> char_positions[26];\n\n// Preprocessing\nvoid preprocess() {\n    for (int i = 0; i < 26; i++) {\n        char_positions[i].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// Find position with better lookahead\npair<int, int> find_better_position(char c, int cur_i, int cur_j) {\n    int best_cost = 1e9;\n    pair<int, int> best_pos = {cur_i, cur_j};\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int cost = abs(pos.first - cur_i) + abs(pos.second - cur_j) + 1;\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Calculate overlap efficiently\nint calculate_overlap(const string& a, const string& b) {\n    int max_overlap = 0;\n    for (int i = 1; i <= min((int)a.length(), (int)b.length()); i++) {\n        if (a.substr(a.length() - i) == b.substr(0, i)) {\n            max_overlap = i;\n        }\n    }\n    return max_overlap;\n}\n\n// Advanced greedy superstring\nstring construct_superstring() {\n    vector<string> strings = targets;\n    random_shuffle(strings.begin(), strings.end());\n    \n    // Greedy merging with larger search\n    while (strings.size() > 1) {\n        int max_overlap = -1;\n        int best_i = -1, best_j = -1;\n        string best_merged;\n        \n        int limit = min(50, (int)strings.size());\n        \n        // Find best pair to merge\n        for (int i = 0; i < limit; i++) {\n            for (int j = i + 1; j < limit; j++) {\n                // Try a + b\n                int overlap1 = calculate_overlap(strings[i], strings[j]);\n                string merged1 = strings[i] + strings[j].substr(overlap1);\n                \n                // Try b + a\n                int overlap2 = calculate_overlap(strings[j], strings[i]);\n                string merged2 = strings[j] + strings[i].substr(overlap2);\n                \n                if (overlap1 > max_overlap) {\n                    max_overlap = overlap1;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged1;\n                }\n                \n                if (overlap2 > max_overlap) {\n                    max_overlap = overlap2;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged2;\n                }\n            }\n        }\n        \n        // If no good overlap found, merge first two\n        if (best_i == -1 && strings.size() >= 2) {\n            best_merged = strings[0] + strings[1];\n            best_i = 0;\n            best_j = 1;\n        } else if (best_i == -1) {\n            break;\n        }\n        \n        // Update strings\n        if (best_i > best_j) swap(best_i, best_j);\n        strings.erase(strings.begin() + best_j);\n        strings.erase(strings.begin() + best_i);\n        strings.push_back(best_merged);\n    }\n    \n    // Combine remaining\n    string result;\n    for (const string& s : strings) {\n        result += s;\n    }\n    \n    return result;\n}\n\n// Generate optimized path\nvector<pair<int, int>> generate_path(const string& s) {\n    vector<pair<int, int>> path;\n    int cur_i = start_i, cur_j = start_j;\n    \n    for (int i = 0; i < (int)s.length(); i++) {\n        auto pos = find_better_position(s[i], cur_i, cur_j);\n        path.push_back(pos);\n        cur_i = pos.first;\n        cur_j = pos.second;\n    }\n    \n    return path;\n}\n\n// Count covered targets\nint count_targets(const string& s) {\n    int count = 0;\n    for (const string& target : targets) {\n        if (s.find(target) != string::npos) {\n            count++;\n        }\n    }\n    return count;\n}\n\n// Ensure complete coverage with smarter approach\nstring ensure_complete_coverage(const string& s) {\n    string result = s;\n    vector<bool> covered(m, false);\n    \n    // Check what's already covered\n    for (int i = 0; i < m; i++) {\n        if (result.find(targets[i]) != string::npos) {\n            covered[i] = true;\n        }\n    }\n    \n    // Add missing targets efficiently\n    for (int i = 0; i < m; i++) {\n        if (!covered[i]) {\n            // Try to merge with existing string\n            bool merged = false;\n            \n            // Look for overlap at the end\n            for (int overlap = min(4, (int)result.length()); overlap >= 1; overlap--) {\n                string suffix = result.substr(result.length() - overlap);\n                if (targets[i].length() >= overlap && targets[i].substr(0, overlap) == suffix) {\n                    result += targets[i].substr(overlap);\n                    merged = true;\n                    break;\n                }\n            }\n            \n            // Simple append if needed and possible\n            if (!merged && result.length() + 5 <= 3200) {\n                result += targets[i];\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Get optimal construction\nstring get_optimal_construction() {\n    string best_string;\n    int best_coverage = -1;\n    \n    // Multiple trials\n    for (int trial = 0; trial < 8; trial++) {\n        string candidate = construct_superstring();\n        int coverage = count_targets(candidate);\n        \n        if (coverage > best_coverage || (coverage == best_coverage && candidate.length() < best_string.length())) {\n            best_coverage = coverage;\n            best_string = candidate;\n        }\n    }\n    \n    // Alternative approach: first N targets\n    string alternative;\n    for (int i = 0; i < min(75, m); i++) {\n        alternative += targets[i];\n    }\n    int alt_coverage = count_targets(alternative);\n    \n    if (alt_coverage > best_coverage || (alt_coverage == best_coverage && alternative.length() < best_string.length())) {\n        best_string = alternative;\n        best_coverage = alt_coverage;\n    }\n    \n    // Ensure all targets\n    best_string = ensure_complete_coverage(best_string);\n    \n    return best_string;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    cin >> start_i >> start_j;\n    \n    for (int i = 0; i < n; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < n; j++) {\n            grid[i][j] = line[j];\n        }\n    }\n    \n    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i];\n    }\n    \n    preprocess();\n    \n    // Get construction\n    string final_string = get_optimal_construction();\n    \n    // Generate path\n    auto path = generate_path(final_string);\n    \n    // Limit operations\n    if (path.size() > MAX_OPS) {\n        path.resize(MAX_OPS);\n    }\n    \n    // Output\n    for (const auto& pos : path) {\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\n\nusing namespace std;\n\nconst int MAX_N = 20;\n\nint N, M;\ndouble epsilon;\nvector<vector<pair<int,int>>> oil_fields;\nvector<vector<bool>> has_oil;\nvector<vector<bool>> queried;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    cin >> N >> M >> epsilon;\n    oil_fields.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        int d;\n        cin >> d;\n        oil_fields[i].resize(d);\n        for (int j = 0; j < d; j++) {\n            cin >> oil_fields[i][j].first >> oil_fields[i][j].second;\n        }\n    }\n    \n    // Initialize tracking arrays\n    has_oil.assign(N, vector<bool>(N, false));\n    queried.assign(N, vector<bool>(N, false));\n    \n    // Simple strategy: query all squares individually\n    // This is the baseline from the sample solution but more robust\n    vector<pair<int,int>> oil_squares;\n    \n    int max_queries = 2 * N * N - N * N / 2; // Leave some buffer for the answer\n    int query_count = 0;\n    \n    // Query squares in a systematic way\n    for (int i = 0; i < N && query_count < max_queries; i++) {\n        for (int j = 0; j < N && query_count < max_queries; j++) {\n            // Query this square\n            cout << \"q 1 \" << i << \" \" << j << \"\\n\";\n            cout.flush();\n            query_count++;\n            \n            int result;\n            cin >> result;\n            \n            if (result > 0) {\n                has_oil[i][j] = true;\n                oil_squares.push_back({i, j});\n            }\n            queried[i][j] = true;\n        }\n    }\n    \n    // Collect all squares that have oil\n    vector<pair<int,int>> result_squares;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (has_oil[i][j]) {\n                result_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    // Submit answer\n    cout << \"a \" << result_squares.size();\n    for (const auto& sq : result_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << \"\\n\";\n    cout.flush();\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int W = 1000;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int _i0, int _j0, int _i1, int _j1) : i0(_i0), j0(_j0), i1(_i1), j1(_j1) {}\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// Simple, safe, and working packing approach\nvector<Rectangle> simpleSafePack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Use grid-based approach\n    int grid_dim = max(1, (int)ceil(sqrt(n)));\n    int cell_size = W / grid_dim;\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Grid position\n        int row = k / grid_dim;\n        int col = k % grid_dim;\n        \n        // Cell boundaries\n        int cell_top = row * cell_size;\n        int cell_left = col * cell_size;\n        int cell_bottom = min(W, (row + 1) * cell_size);\n        int cell_right = min(W, (col + 1) * cell_size);\n        \n        // Available space\n        int h_avail = max(1, cell_bottom - cell_top);\n        int w_avail = max(1, cell_right - cell_left);\n        \n        // Calculate dimensions for required area\n        int height = max(1, min(h_avail, (int)sqrt(required)));\n        int width = max(1, (required + height - 1) / height); // ceil division\n        \n        // Adjust if too large\n        if (width > w_avail) {\n            width = w_avail;\n            height = max(1, (required + width - 1) / width);\n            height = min(height, h_avail);\n        }\n        \n        // Final bounds enforcement\n        height = max(1, min(height, h_avail));\n        width = max(1, min(width, w_avail));\n        \n        // Position in cell (centered-ish)\n        int top = cell_top + max(0, (h_avail - height) / 2);\n        int left = cell_left + max(0, (w_avail - width) / 2);\n        \n        // Final safety check\n        height = min(height, W - top);\n        width = min(width, W - left);\n        height = max(1, height);\n        width = max(1, width);\n        \n        result.emplace_back(top, left, top + height, left + width);\n    }\n    \n    return result;\n}\n\n// Slightly improved version that tries harder to satisfy area requirements\nvector<Rectangle> improvedPack(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Grid approach\n    int grid_rows = max(1, (int)sqrt(n));\n    int grid_cols = (n + grid_rows - 1) / grid_rows;\n    \n    int cell_height = W / max(1, grid_rows);\n    int cell_width = W / max(1, grid_cols);\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Grid position\n        int row = k / grid_cols;\n        int col = k % grid_cols;\n        \n        // Cell boundaries\n        int cell_top = row * cell_height;\n        int cell_left = col * cell_width;\n        int cell_bottom = min(W, (row + 1) * cell_height);\n        int cell_right = min(W, (col + 1) * cell_width);\n        \n        // Available space\n        int h_avail = max(1, cell_bottom - cell_top);\n        int w_avail = max(1, cell_right - cell_left);\n        \n        // Try to get closer to required area\n        long long target = required;\n        long long best_diff = 1e18;\n        int best_h = max(1, min(h_avail, (int)sqrt(required)));\n        int best_w = max(1, (required + best_h - 1) / best_h);\n        \n        // Try a few variations to get closer to target area\n        for (int scale = -2; scale <= 2; scale++) {\n            int try_h = max(1, min(h_avail, best_h + scale));\n            int try_w = max(1, min(w_avail, (required + try_h - 1) / try_h));\n            \n            long long area = (long long)try_h * try_w;\n            long long diff = llabs(area - target);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_h = try_h;\n                best_w = try_w;\n            }\n            \n            // Also try fixing width and computing height\n            int try_w2 = max(1, min(w_avail, best_w + scale));\n            int try_h2 = max(1, min(h_avail, (required + try_w2 - 1) / try_w2));\n            \n            area = (long long)try_h2 * try_w2;\n            diff = llabs(area - target);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_h = try_h2;\n                best_w = try_w2;\n            }\n        }\n        \n        // Final bounds check\n        int height = max(1, min(best_h, h_avail));\n        int width = max(1, min(best_w, w_avail));\n        \n        // Position in cell\n        int top = cell_top + max(0, (h_avail - height) / 2);\n        int left = cell_left + max(0, (w_avail - width) / 2);\n        \n        // Final safety bounds\n        height = min(height, W - top);\n        width = min(width, W - left);\n        height = max(1, height);\n        width = max(1, width);\n        \n        result.emplace_back(top, left, top + height, left + width);\n    }\n    \n    return result;\n}\n\nvector<vector<Rectangle>> solve(const vector<vector<int>>& all_areas) {\n    int D = all_areas.size();\n    vector<vector<Rectangle>> result(D);\n    \n    for (int d = 0; d < D; d++) {\n        result[d] = improvedPack(all_areas[d]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    \n    vector<vector<int>> all_areas(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> all_areas[d][k];\n        }\n    }\n    \n    // Solve\n    auto solution = solve(all_areas);\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << solution[d][k].i0 << \" \" << solution[d][k].j0 << \" \" \n                 << solution[d][k].i1 << \" \" << solution[d][k].j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint N = 9, M = 20, K = 81;\nlong long a[9][9];\nlong long s[20][3][3];\n\nstruct Operation {\n    int stamp, row, col;\n};\n\n// Calculate the gain in sum of remainders from applying a stamp at position (r,c)\nlong long calculate_gain(long long board[9][9], int stamp, int r, int c) {\n    long long gain = 0;\n    \n    // Calculate sum of remainders for affected cells before and after\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = r + i, col = c + j;\n            long long original_remainder = board[row][col] % MOD;\n            long long new_value = board[row][col] + s[stamp][i][j];\n            long long new_remainder = new_value % MOD;\n            gain += (long long)new_remainder - (long long)original_remainder;\n        }\n    }\n    \n    return gain;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> K;\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 (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n    \n    // Keep track of actual values (not modded yet)\n    long long board[9][9];\n    for (int i = 0; i < 9; i++) {\n        for (int j = 0; j < 9; j++) {\n            board[i][j] = a[i][j];\n        }\n    }\n    \n    vector<Operation> operations;\n    \n    // More sophisticated approach: \n    // 1. First, cover the board systematically\n    // 2. Then, apply additional operations greedily on high-impact areas\n    \n    // Phase 1: Systematic coverage (use about half the operations)\n    int phase1_ops = min(K / 2, 9);  // At most 9 non-overlapping operations\n    for (int base_r = 0; base_r < 9; base_r += 3) {\n        for (int base_c = 0; base_c < 9; base_c += 3) {\n            if ((int)operations.size() >= phase1_ops) break;\n            \n            // Find the best stamp for this region\n            long long best_increase = -1;\n            int best_stamp = 0;\n            \n            for (int stamp = 0; stamp < M; stamp++) {\n                long long gain = calculate_gain(board, stamp, base_r, base_c);\n                if (gain > best_increase) {\n                    best_increase = gain;\n                    best_stamp = stamp;\n                }\n            }\n            \n            // Apply the best stamp\n            operations.push_back({best_stamp, base_r, base_c});\n            \n            // Update board values\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[base_r + i][base_c + j] += s[best_stamp][i][j];\n                }\n            }\n        }\n        if ((int)operations.size() >= phase1_ops) break;\n    }\n    \n    // Phase 2: Greedy optimization with remaining operations\n    int remaining_ops = K - operations.size();\n    for (int op = 0; op < remaining_ops; op++) {\n        long long best_gain = -1;\n        int best_stamp = -1, best_row = -1, best_col = -1;\n        \n        // Try all possible stamp placements, but prioritize high-impact ones\n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int r = 0; r <= 6; r++) {\n                for (int c = 0; c <= 6; c++) {\n                    long long gain = calculate_gain(board, stamp, r, c);\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_stamp = stamp;\n                        best_row = r;\n                        best_col = c;\n                    }\n                }\n            }\n        }\n        \n        // If no positive gain, stop early\n        if (best_gain <= 0) {\n            break;\n        }\n        \n        // Apply the best operation\n        operations.push_back({best_stamp, best_row, best_col});\n        \n        // Update board values\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_row + i][best_col + j] += s[best_stamp][i][j];\n            }\n        }\n    }\n    \n    // Output result\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << op.stamp << \" \" << op.row << \" \" << op.col << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid solve() {\n    // Read input\n    int n;\n    cin >> n;\n    vector<vector<int>> A(5, vector<int>(5));\n    for (int i = 0; i < 5; i++) {\n        for (int j = 0; j < 5; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Create a very simple, safe strategy\n    vector<string> actions(5);\n    \n    // Strategy: All cranes just do nothing for a while to avoid any conflicts\n    // This is not optimal but should be valid\n    \n    int total_turns = 500;\n    \n    for (int turn = 0; turn < total_turns; turn++) {\n        for (int crane = 0; crane < 5; crane++) {\n            // Extremely conservative approach - mostly do nothing\n            if (turn < 50) {\n                // First do some safe movements\n                if (turn % 10 == crane) {\n                    actions[crane] += 'R';\n                } else if (turn % 10 == (crane + 5)) {\n                    actions[crane] += 'L';\n                } else {\n                    actions[crane] += '.';\n                }\n            } else {\n                actions[crane] += '.';\n            }\n        }\n    }\n    \n    // Ensure all strings have same length\n    int max_len = 0;\n    for (int i = 0; i < 5; i++) {\n        max_len = max(max_len, (int)actions[i].length());\n    }\n    \n    for (int i = 0; i < 5; i++) {\n        while ((int)actions[i].length() < max_len) {\n            actions[i] += '.';\n        }\n        if (actions[i].empty()) actions[i] = \".\";\n        cout << actions[i] << \"\\n\";\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    solve();\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\n// Manhattan distance\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Get moves to go from (x1,y1) to (x2,y2)\nvector<string> get_path(int x1, int y1, int x2, int y2) {\n    vector<string> moves;\n    while (x1 < x2) {\n        moves.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        moves.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        moves.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        moves.push_back(\"L\");\n        y1--;\n    }\n    return moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<int>> grid(n, vector<int>(n));\n    vector<pair<int, int>> positives, negatives;\n    vector<int> pos_amounts, neg_amounts;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n            if (grid[i][j] > 0) {\n                positives.push_back({i, j});\n                pos_amounts.push_back(grid[i][j]);\n            } else if (grid[i][j] < 0) {\n                negatives.push_back({i, j});\n                neg_amounts.push_back(-grid[i][j]);\n            }\n        }\n    }\n    \n    vector<string> result;\n    int curr_x = 0, curr_y = 0;\n    \n    // Improved greedy approach: prioritize cells closer to current position\n    vector<int> pos_remaining = pos_amounts;\n    vector<int> neg_remaining = neg_amounts;\n    vector<bool> pos_done(positives.size(), false);\n    \n    // Continue until all positive cells are processed\n    while (true) {\n        // Find the nearest positive cell with remaining soil\n        int best_pos = -1;\n        int best_dist = 1e9;\n        \n        for (int i = 0; i < positives.size(); i++) {\n            if (pos_remaining[i] > 0 && !pos_done[i]) {\n                int px = positives[i].first;\n                int py = positives[i].second;\n                int dist = manhattan(curr_x, curr_y, px, py);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pos = i;\n                }\n            }\n        }\n        \n        if (best_pos == -1) break; // No more positive cells\n        \n        int i = best_pos;\n        pos_done[i] = true;\n        \n        int px = positives[i].first;\n        int py = positives[i].second;\n        int amount_to_distribute = pos_remaining[i];\n        \n        // Create list of negative cells with distances from THIS positive cell\n        vector<pair<int, int>> neg_cells_with_dist; // {distance, index}\n        for (int j = 0; j < negatives.size(); j++) {\n            if (neg_remaining[j] > 0) {\n                int nx = negatives[j].first;\n                int ny = negatives[j].second;\n                int dist = manhattan(px, py, nx, ny);\n                neg_cells_with_dist.push_back({dist, j});\n            }\n        }\n        \n        // Sort by distance (nearest first)\n        sort(neg_cells_with_dist.begin(), neg_cells_with_dist.end());\n        \n        // Distribute to nearest negatives\n        for (auto& [dist, j] : neg_cells_with_dist) {\n            if (amount_to_distribute <= 0) break;\n            if (neg_remaining[j] <= 0) continue;\n            \n            int transfer_amount = min(amount_to_distribute, neg_remaining[j]);\n            \n            // Go to positive cell (if not already there)\n            if (curr_x != px || curr_y != py) {\n                auto moves = get_path(curr_x, curr_y, px, py);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = px;\n                curr_y = py;\n            }\n            \n            // Load\n            result.push_back(\"+\" + to_string(transfer_amount));\n            \n            // Go to negative cell\n            int nx = negatives[j].first;\n            int ny = negatives[j].second;\n            if (curr_x != nx || curr_y != ny) {\n                auto moves = get_path(curr_x, curr_y, nx, ny);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = nx;\n                curr_y = ny;\n            }\n            \n            // Unload\n            result.push_back(\"-\" + to_string(transfer_amount));\n            \n            amount_to_distribute -= transfer_amount;\n            neg_remaining[j] -= transfer_amount;\n        }\n        \n        pos_remaining[i] = amount_to_distribute;\n    }\n    \n    // Output results\n    for (const string& s : result) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int SEED_COUNT = 2 * N * (N - 1); // 72\n\n// Structure to hold seed information\nstruct Seed {\n    int id;\n    vector<int> values;\n    int total_value;\n    \n    Seed() : id(0), values(M, 0), total_value(0) {}\n    \n    Seed(int _id, const vector<int>& _values) : id(_id), values(_values) {\n        total_value = accumulate(values.begin(), values.end(), 0);\n    }\n};\n\n// Calculate how much a seed contributes to potential trait maxima\nint calculatePotentialScore(const Seed& seed, const vector<int>& current_max_traits) {\n    int score = seed.total_value;\n    int bonus = 0;\n    \n    // Bonus for seeds that have high values in traits\n    for (int i = 0; i < M; i++) {\n        if (seed.values[i] >= current_max_traits[i] * 0.8) {\n            bonus += 5; // Bonus for being close to trait maximum\n        }\n        if (seed.values[i] >= current_max_traits[i] * 0.95) {\n            bonus += 10; // Extra bonus for being very close to maximum\n        }\n    }\n    \n    return score + bonus;\n}\n\n// Select best seeds considering both total value and trait contributions\nvector<Seed> selectOptimalSeeds(vector<Seed>& all_seeds) {\n    // Calculate current maximum for each trait\n    vector<int> trait_max(M, 0);\n    for (const auto& seed : all_seeds) {\n        for (int i = 0; i < M; i++) {\n            trait_max[i] = max(trait_max[i], seed.values[i]);\n        }\n    }\n    \n    // Score each seed\n    vector<pair<int, int>> seed_scores; // {score, id}\n    for (int i = 0; i < SEED_COUNT; i++) {\n        int score = calculatePotentialScore(all_seeds[i], trait_max);\n        seed_scores.push_back({score, i});\n    }\n    \n    // Sort by score descending\n    sort(seed_scores.begin(), seed_scores.end(), greater<pair<int, int>>());\n    \n    // Select top N*N seeds\n    vector<Seed> selected;\n    for (int i = 0; i < N * N; i++) {\n        selected.push_back(all_seeds[seed_scores[i].second]);\n    }\n    \n    return selected;\n}\n\n// Generate placement positions with spiral pattern from center outward\nvector<pair<int, int>> generateSpiralCenterOrder() {\n    vector<pair<int, int>> positions;\n    \n    // Create all 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    // Sort by a combination of distance to center and strategic value\n    int center_i = N / 2;\n    int center_j = N / 2;\n    \n    sort(positions.begin(), positions.end(), \n         [center_i, center_j](const pair<int, int>& a, const pair<int, int>& b) {\n             // Distance to center\n             int dist_a = abs(a.first - center_i) + abs(a.second - center_j);\n             int dist_b = abs(b.first - center_i) + abs(b.second - center_j);\n             \n             // Prefer center positions, but also consider corners and edges strategically\n             // Center is most valuable (4 neighbors), then edge centers, then corners\n             if (dist_a != dist_b) {\n                 return dist_a < dist_b;\n             }\n             \n             // For same distance, prefer positions that are more \"central\"\n             int central_a = abs(abs(a.first - center_i) - abs(a.second - center_j));\n             int central_b = abs(abs(b.first - center_i) - abs(b.second - center_j));\n             \n             return central_a < central_b;\n         });\n    \n    return positions;\n}\n\n// Advanced placement considering seed compatibility\nvector<vector<int>> placeSeedsAdvanced(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending) as primary strategy\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Get positions ordered by strategic priority\n    vector<pair<int, int>> positions = generateSpiralCenterOrder();\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = seeds[i].id;\n    }\n    \n    return grid;\n}\n\n// Simple but effective placement (fallback)\nvector<vector<int>> placeSeedsSimple(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Simple row-major order with best seeds in center area\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    // Prioritize center positions\n    int center_i = N / 2;\n    int center_j = N / 2;\n    \n    sort(positions.begin(), positions.end(), \n         [center_i, center_j](const pair<int, int>& a, const pair<int, int>& b) {\n             int dist_a = abs(a.first - center_i) + abs(a.second - center_j);\n             int dist_b = abs(b.first - center_i) + abs(b.second - center_j);\n             return dist_a < dist_b;\n         });\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = seeds[i].id;\n    }\n    \n    return grid;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N_input, M_input, T;\n    cin >> N_input >> M_input >> T;\n    \n    vector<Seed> seeds(SEED_COUNT);\n    \n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; i++) {\n        vector<int> values(M);\n        for (int j = 0; j < M; j++) {\n            cin >> values[j];\n        }\n        seeds[i] = Seed(i, values);\n    }\n    \n    // Process each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Select and place seeds\n        vector<Seed> selected_seeds = selectOptimalSeeds(seeds);\n        vector<vector<int>> grid = placeSeedsSimple(selected_seeds);\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            vector<int> values(M);\n            for (int j = 0; j < M; j++) {\n                cin >> values[j];\n            }\n            seeds[i] = Seed(i, values);\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 30;\nconst int dx[4] = {0, 1, 0, -1}; // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dir_char[4] = {'R', 'D', 'L', 'U'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nstruct Edge {\n    int parent, length;\n    Edge() : parent(0), length(0) {}\n    Edge(int p, int l) : parent(p), length(l) {}\n};\n\nclass Solution {\npublic:\n    int N, M, V;\n    vector<vector<int>> source, target;\n    \n    Solution(int n, int m, int v) : N(n), M(m), V(v) {\n        source.assign(N, vector<int>(N, 0));\n        target.assign(N, vector<int>(N, 0));\n    }\n    \n    void read_input() {\n        string line;\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                source[i][j] = line[j] - '0';\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> line;\n            for (int j = 0; j < N; j++) {\n                target[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    void design_arm() {\n        // Create a star-like tree with root at center\n        int num_edges = min(V - 1, 8);\n        \n        cout << num_edges + 1 << endl; // Number of vertices\n        \n        // Create edges from root (0) to fingertips\n        for (int i = 1; i <= num_edges; i++) {\n            cout << 0 << \" \" << 1 << endl; // parent, length\n        }\n        \n        // Initial root position\n        cout << N/2 << \" \" << N/2 << endl;\n    }\n    \n    int manhattan_distance(int x1, int y1, int x2, int y2) {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    vector<pair<int, int>> get_positions_to_visit() {\n        vector<pair<int, int>> positions;\n        \n        // Collect source positions (where takoyaki are)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        return positions;\n    }\n    \n    void solve() {\n        read_input();\n        design_arm();\n        \n        // Simple greedy approach\n        vector<pair<int, int>> sources, targets;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (source[i][j] == 1 && target[i][j] == 0) {\n                    sources.push_back({i, j});\n                }\n                if (target[i][j] == 1 && source[i][j] == 0) {\n                    targets.push_back({i, j});\n                }\n            }\n        }\n        \n        // For demonstration, just do random moves\n        int root_x = N/2, root_y = N/2;\n        vector<bool> held(min(V, 9), false);\n        \n        for (int turn = 0; turn < 2000; turn++) {\n            string command(2 * min(V, 9), '.');\n            \n            // Move root randomly but stay in bounds\n            int dir = rand() % 5;\n            if (dir < 4) {\n                int nx = root_x + dx[dir];\n                int ny = root_y + dy[dir];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                    root_x = nx;\n                    root_y = ny;\n                    command[0] = dir_char[dir];\n                }\n            }\n            \n            // Check if we can pick up or drop takoyaki\n            for (int finger = 1; finger < min(V, 9); finger++) {\n                int fx = root_x;\n                int fy = root_y + finger; // Simple positioning\n                \n                if (fx >= 0 && fx < N && fy >= 0 && fy < N) {\n                    // Try to pick up\n                    if (!held[finger] && source[fx][fy] == 1 && target[fx][fy] == 0) {\n                        source[fx][fy] = 0;\n                        held[finger] = true;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                    // Try to drop\n                    else if (held[finger] && source[fx][fy] == 0 && target[fx][fy] == 1) {\n                        source[fx][fy] = 1;\n                        held[finger] = false;\n                        command[min(V, 9) + finger] = 'P';\n                    }\n                }\n            }\n            \n            cout << command << endl;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(time(nullptr));\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    Solution solution(N, M, V);\n    solution.solve();\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 5000;\nconst int MAX_COORD = 100000;\nconst int MAX_VERTICES = 1000;\nconst long long MAX_PERIMETER = 400000LL;\n\nstruct Point {\n    int x, y;\n    bool is_mackerel;\n    \n    Point() : x(0), y(0), is_mackerel(false) {}\n    Point(int _x, int _y, bool _is_mackerel) : x(_x), y(_y), is_mackerel(_is_mackerel) {}\n};\n\nstruct Rectangle {\n    int x1, y1, x2, y2;\n    \n    Rectangle() : x1(0), y1(0), x2(0), y2(0) {}\n    Rectangle(int _x1, int _y1, int _x2, int _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {}\n    \n    long long perimeter() const {\n        return 2LL * (abs(x2 - x1) + abs(y2 - y1));\n    }\n    \n    bool isValid() const {\n        return x1 >= 0 && x2 <= MAX_COORD && y1 >= 0 && y2 <= MAX_COORD && \n               x1 <= x2 && y1 <= y2;\n    }\n};\n\nvector<Point> points;\nvector<Point> mackerels, sardines;\n\n// Fast counting with early termination\npair<int, int> countPointsInRect(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    for (const auto& p : points) {\n        if (p.x >= rect.x1 && p.x <= rect.x2 && p.y >= rect.y1 && p.y <= rect.y2) {\n            if (p.is_mackerel) {\n                mackerel_count++;\n            } else {\n                sardine_count++;\n            }\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\nint calculateScore(const Rectangle& rect) {\n    if (!rect.isValid()) return 0;\n    \n    auto [m, s] = countPointsInRect(rect);\n    return max(0, m - s + 1);\n}\n\n// Smart sampling of potential rectangle centers\nvector<pair<int, int>> sampleCenters() {\n    vector<pair<int, int>> centers;\n    \n    // Add all mackerels as potential centers\n    for (int i = 0; i < (int)mackerels.size(); i += max(1, (int)mackerels.size() / 100)) {\n        centers.push_back({mackerels[i].x, mackerels[i].y});\n    }\n    \n    // Add some strategic points\n    if (!mackerels.empty()) {\n        // Bounding box center\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        centers.push_back({(min_x + max_x) / 2, (min_y + max_y) / 2});\n        \n        // Add some grid points in the mackerel region\n        int grid_size = 5;\n        for (int i = 0; i <= grid_size; i++) {\n            for (int j = 0; j <= grid_size; j++) {\n                int x = min_x + (max_x - min_x) * i / grid_size;\n                int y = min_y + (max_y - min_y) * j / grid_size;\n                centers.push_back({x, y});\n            }\n        }\n    }\n    \n    return centers;\n}\n\n// Comprehensive rectangle search\nRectangle findBestRectangle() {\n    Rectangle best_rect;\n    int best_score = 0;\n    \n    // Sample centers\n    auto centers = sampleCenters();\n    \n    // Different aspect ratios and sizes\n    vector<pair<int, int>> dimensions = {\n        {1000, 1000}, {2000, 2000}, {3000, 3000}, {4000, 4000}, {5000, 5000},\n        {6000, 6000}, {8000, 8000}, {10000, 10000}, {12000, 12000}, {15000, 15000},\n        {20000, 20000}, {25000, 25000}, {30000, 30000},\n        // Some rectangular shapes\n        {2000, 8000}, {8000, 2000}, {3000, 12000}, {12000, 3000},\n        {4000, 15000}, {15000, 4000}, {5000, 20000}, {20000, 5000}\n    };\n    \n    for (const auto& center : centers) {\n        int cx = center.first;\n        int cy = center.second;\n        \n        for (const auto& dim : dimensions) {\n            int w = dim.first;\n            int h = dim.second;\n            \n            // Try different positions around the center\n            for (int dx = -1; dx <= 1; dx++) {\n                for (int dy = -1; dy <= 1; dy++) {\n                    int offset_x = dx * w / 4;\n                    int offset_y = dy * h / 4;\n                    \n                    int x1 = max(0, cx + offset_x - w/2);\n                    int y1 = max(0, cy + offset_y - h/2);\n                    int x2 = min(MAX_COORD, cx + offset_x + w/2);\n                    int y2 = min(MAX_COORD, cy + offset_y + h/2);\n                    \n                    if (x2 > x1 && y2 > y1) {\n                        Rectangle rect(x1, y1, x2, y2);\n                        if (rect.perimeter() <= MAX_PERIMETER) {\n                            int score = calculateScore(rect);\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\n// Aggressive local optimization\nRectangle optimizeRectangle(Rectangle rect) {\n    Rectangle best_rect = rect;\n    int best_score = calculateScore(rect);\n    \n    // Try various perturbations\n    vector<int> steps = {2000, 1000, 500, 200, 100, 50};\n    \n    for (int step : steps) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            \n            // Try moving each boundary\n            int boundaries[4][2] = {{0, -1}, {2, 1}, {1, -1}, {3, 1}}; // x1, x2, y1, y2\n            \n            for (int i = 0; i < 4; i++) {\n                int* coord;\n                if (i == 0) coord = &rect.x1;\n                else if (i == 1) coord = &rect.y1;\n                else if (i == 2) coord = &rect.x2;\n                else coord = &rect.y2;\n                \n                int direction = boundaries[i][1];\n                int original_value = *coord;\n                \n                // Try moving in positive direction\n                *coord += direction * step;\n                if (rect.isValid() && rect.perimeter() <= MAX_PERIMETER) {\n                    int score = calculateScore(rect);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_rect = rect;\n                        improved = true;\n                    } else {\n                        *coord = original_value; // revert\n                    }\n                } else {\n                    *coord = original_value; // revert\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\n// Try multiple optimization strategies\nRectangle advancedOptimize(const Rectangle& initial_rect) {\n    Rectangle best_rect = initial_rect;\n    int best_score = calculateScore(initial_rect);\n    \n    // Strategy 1: Expand aggressively first\n    Rectangle rect1 = initial_rect;\n    vector<pair<int*, int>> boundaries = {\n        {&rect1.x1, -1}, {&rect1.x2, 1}, {&rect1.y1, -1}, {&rect1.y2, 1}\n    };\n    \n    for (auto& boundary : boundaries) {\n        int* coord = boundary.first;\n        int direction = boundary.second;\n        int original_value = *coord;\n        \n        // Expand until we hit limits or score doesn't improve significantly\n        for (int expansion = 500; expansion <= 5000; expansion += 500) {\n            *coord += direction * expansion;\n            if (rect1.isValid() && rect1.perimeter() <= MAX_PERIMETER) {\n                int score = calculateScore(rect1);\n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = rect1;\n                }\n            } else {\n                *coord = original_value;\n                break;\n            }\n        }\n    }\n    \n    // Apply local optimization\n    best_rect = optimizeRectangle(best_rect);\n    \n    return best_rect;\n}\n\nvector<pair<int, int>> rectangleToPolygon(const Rectangle& rect) {\n    vector<pair<int, int>> polygon;\n    polygon.push_back({rect.x1, rect.y1});\n    polygon.push_back({rect.x2, rect.y1});\n    polygon.push_back({rect.x2, rect.y2});\n    polygon.push_back({rect.x1, rect.y2});\n    return polygon;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    points.reserve(2 * N);\n    mackerels.reserve(N);\n    sardines.reserve(N);\n    \n    // Read mackerels\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, true);\n        points.push_back(p);\n        mackerels.push_back(p);\n    }\n    \n    // Read sardines\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, false);\n        points.push_back(p);\n        sardines.push_back(p);\n    }\n    \n    // Find best rectangle using comprehensive search\n    Rectangle best_rect = findBestRectangle();\n    \n    // Apply advanced optimization\n    if (best_rect.isValid()) {\n        Rectangle optimized = advancedOptimize(best_rect);\n        if (calculateScore(optimized) > calculateScore(best_rect)) {\n            best_rect = optimized;\n        }\n    }\n    \n    // Fallback strategies\n    if (calculateScore(best_rect) == 0 && !mackerels.empty()) {\n        // Bounding box approach with smart padding\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        int width = max_x - min_x;\n        int height = max_y - min_y;\n        \n        int pad_x = min(10000, max(1000, width / 2 + 2000));\n        int pad_y = min(10000, max(1000, height / 2 + 2000));\n        \n        Rectangle fallback_rect(\n            max(0, min_x - pad_x),\n            max(0, min_y - pad_y),\n            min(MAX_COORD, max_x + pad_x),\n            min(MAX_COORD, max_y + pad_y)\n        );\n        \n        if (calculateScore(fallback_rect) > calculateScore(best_rect)) {\n            best_rect = fallback_rect;\n        }\n    }\n    \n    // Final optimization pass\n    if (best_rect.isValid()) {\n        Rectangle final_optimized = optimizeRectangle(best_rect);\n        if (calculateScore(final_optimized) > calculateScore(best_rect)) {\n            best_rect = final_optimized;\n        }\n    }\n    \n    // Convert to polygon\n    auto polygon = rectangleToPolygon(best_rect);\n    \n    // Output result\n    cout << polygon.size() << \"\\n\";\n    for (const auto& vertex : polygon) {\n        cout << vertex.first << \" \" << vertex.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random number generator\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Utility functions\ninline double random_double() {\n    return uniform_real_distribution<double>(0, 1)(rng);\n}\n\ninline int random_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rectangle {\n    int w, h;\n    int idx;\n    \n    Rectangle() : w(0), h(0), idx(0) {}\n    Rectangle(int _w, int _h, int _idx) : w(_w), h(_h), idx(_idx) {}\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n    \n    Placement(int _p, int _r, char _d, int _b) : p(_p), r(_r), d(_d), b(_b) {}\n};\n\nclass Packer {\nprivate:\n    int N, T, sigma;\n    vector<Rectangle> rectangles;\n    \npublic:\n    Packer() {\n        cin >> N >> T >> sigma;\n        rectangles.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            int w, h;\n            cin >> w >> h;\n            rectangles[i] = Rectangle(w, h, i);\n        }\n    }\n    \n    // Select first k rectangles\n    vector<int> selectFirst(int count) {\n        vector<int> selected;\n        count = min(count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(i);\n        }\n        return selected;\n    }\n    \n    // Simple placement strategy with slight improvements\n    vector<Placement> simplePacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle at origin\n        placements.emplace_back(selected_indices[0], random_int(0, 1), 'U', -1);\n        \n        // For remaining rectangles\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            char dir = (random_int(0, 1) == 0) ? 'U' : 'L';\n            int base = random_int(-1, i - 1);\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Slightly smarter placement\n    vector<Placement> improvedPacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle\n        placements.emplace_back(selected_indices[0], random_int(0, 1), 'U', -1);\n        \n        // Try to build more structured placement\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            \n            // Slight bias toward vertical placement (often works better)\n            char dir = (random_double() < 0.6) ? 'U' : 'L';\n            \n            // Prefer recent bases but allow wall attachment\n            int base;\n            if (random_double() < 0.25) {\n                base = -1; // Wall attachment\n            } else {\n                base = random_int(0, i - 1); // Rectangle attachment\n            }\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    void run() {\n        for (int t = 0; t < T; t++) {\n            vector<Placement> best_placement;\n            \n            // Simple strategy cycling - similar to original but with better distribution\n            int strategy = t % 4;\n            \n            switch (strategy) {\n                case 0: {\n                    // Use first half of rectangles with simple packing\n                    int count = max(N/2, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = simplePacking(selected);\n                    break;\n                }\n                case 1: {\n                    // Use 3/4 of rectangles with improved packing\n                    int count = max(3*N/4, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = improvedPacking(selected);\n                    break;\n                }\n                case 2: {\n                    // Use all rectangles with simple packing\n                    vector<int> selected = selectFirst(N);\n                    best_placement = simplePacking(selected);\n                    break;\n                }\n                case 3: {\n                    // Use first 1/3 with improved packing\n                    int count = max(N/3, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = improvedPacking(selected);\n                    break;\n                }\n            }\n            \n            // Safety fallback\n            if (best_placement.empty()) {\n                vector<int> single = {0};\n                best_placement = simplePacking(single);\n            }\n            \n            // Output placement\n            cout << best_placement.size() << \"\\n\";\n            for (const auto& p : best_placement) {\n                cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n            }\n            cout.flush();\n            \n            // Read measurement result\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.run();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int MAXH = 10;\n\nint N, M, H;\nvector<int> beauty;\nvector<vector<int>> adj;\nvector<pair<int, int>> coords;\nvector<int> parent;\n\n// Strategy 1: High beauty first with smart expansion\nvoid solve_strategy1() {\n    vector<int> temp_parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Create priority queue with beauty values\n    priority_queue<pair<int, int>> pq;\n    for (int i = 0; i < N; i++) {\n        pq.push({beauty[i], i});\n    }\n    \n    while (!pq.empty()) {\n        int root = -1;\n        while (!pq.empty()) {\n            auto [b, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        temp_parent[root] = -1;\n        \n        // Build tree level by level\n        vector<vector<int>> levels(H + 1);\n        levels[0].push_back(root);\n        \n        for (int level = 0; level < H; level++) {\n            // Collect candidates with scoring function\n            vector<tuple<double, int, int>> candidates;\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Scoring: beauty divided by level penalty, plus connectivity bonus\n                        double score = (double)beauty[v] / sqrt(level + 2.0);\n                        // Bonus for vertices with more connections to unassigned nodes\n                        int unassigned_neighbors = 0;\n                        for (int w : adj[v]) {\n                            if (!assigned[w]) unassigned_neighbors++;\n                        }\n                        score += unassigned_neighbors * 0.5; // Connectivity bonus\n                        \n                        candidates.push_back({score, v, u});\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), greater<tuple<double, int, int>>());\n            \n            // Add top candidates with adaptive width\n            int max_add = min(35, max(15, 50 - level * 3)); // Wider trees early, narrower later\n            \n            int added = 0;\n            for (const auto& [score, vertex, parent_vertex] : candidates) {\n                if (added >= max_add) break;\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    temp_parent[vertex] = parent_vertex;\n                    levels[level + 1].push_back(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n    \n    parent = temp_parent;\n}\n\n// Strategy 2: Degree-based approach\nvoid solve_strategy2() {\n    vector<int> temp_parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Calculate combined score: beauty * degree\n    priority_queue<pair<long long, int>> pq; // {beauty * degree, vertex}\n    for (int i = 0; i < N; i++) {\n        long long score = (long long)beauty[i] * adj[i].size();\n        pq.push({score, i});\n    }\n    \n    while (!pq.empty()) {\n        int root = -1;\n        while (!pq.empty()) {\n            auto [score, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        temp_parent[root] = -1;\n        \n        // Build tree with level-aware expansion\n        vector<vector<int>> levels(H + 1);\n        levels[0].push_back(root);\n        \n        for (int level = 0; level < H; level++) {\n            vector<tuple<long long, int, int>> candidates; // {score, vertex, parent}\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Comprehensive scoring function\n                        long long base_score = (long long)beauty[v] * 1000LL;\n                        \n                        // Level preference (earlier levels preferred)\n                        base_score += (long long)(H - level) * 20LL;\n                        \n                        // Expansion potential bonus\n                        int expand_potential = 0;\n                        for (int w : adj[v]) {\n                            if (!assigned[w]) expand_potential++;\n                        }\n                        base_score += expand_potential * 15LL;\n                        \n                        // Degree bonus\n                        base_score += adj[v].size() * 5LL;\n                        \n                        candidates.push_back({base_score, v, u});\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), greater<tuple<long long, int, int>>());\n            \n            // Adaptive selection based on level\n            int quota = 0;\n            if (level == 0) quota = 40;\n            else if (level == 1) quota = 30;\n            else if (level == 2) quota = 25;\n            else quota = 20;\n            \n            int added = 0;\n            for (const auto& [score, vertex, parent_vertex] : candidates) {\n                if (added >= quota) break;\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    temp_parent[vertex] = parent_vertex;\n                    levels[level + 1].push_back(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n    \n    // Adopt this solution if it's better\n    vector<int> level_current(N, -1);\n    for (int i = 0; i < N; i++) {\n        if (parent[i] == -1) level_current[i] = 0;\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (level_current[i] == 0) q.push(i);\n    }\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (parent[v] == u && level_current[v] == -1 && level_current[u] < H) {\n                level_current[v] = level_current[u] + 1;\n                q.push(v);\n            }\n        }\n    }\n    \n    long long current_score = 0;\n    for (int i = 0; i < N; i++) {\n        if (level_current[i] != -1) {\n            current_score += (long long)(level_current[i] + 1) * beauty[i];\n        }\n    }\n    \n    // Score new solution\n    vector<int> level_new(N, -1);\n    for (int i = 0; i < N; i++) {\n        if (temp_parent[i] == -1) level_new[i] = 0;\n    }\n    \n    queue<int> q2;\n    for (int i = 0; i < N; i++) {\n        if (level_new[i] == 0) q2.push(i);\n    }\n    \n    while (!q2.empty()) {\n        int u = q2.front(); q2.pop();\n        for (int v : adj[u]) {\n            if (temp_parent[v] == u && level_new[v] == -1 && level_new[u] < H) {\n                level_new[v] = level_new[u] + 1;\n                q2.push(v);\n            }\n        }\n    }\n    \n    long long new_score = 0;\n    for (int i = 0; i < N; i++) {\n        if (level_new[i] != -1) {\n            new_score += (long long)(level_new[i] + 1) * beauty[i];\n        }\n    }\n    \n    if (new_score > current_score) {\n        parent = temp_parent;\n    }\n}\n\n// Simple local improvement: try swapping parents for better vertices\nvoid simple_local_improvement() {\n    // For each vertex, see if moving it to a better parent helps\n    for (int v = 0; v < N; v++) {\n        if (parent[v] == -1) continue; // Skip roots\n        \n        int current_parent = parent[v];\n        long long current_contribution = 0;\n        \n        // Calculate current contribution through BFS\n        vector<int> current_level(N, -1);\n        for (int i = 0; i < N; i++) {\n            if (parent[i] == -1) current_level[i] = 0;\n        }\n        \n        queue<int> q;\n        for (int i = 0; i < N; i++) {\n            if (current_level[i] == 0) q.push(i);\n        }\n        \n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int w : adj[u]) {\n                if (parent[w] == u && current_level[w] == -1 && current_level[u] < H) {\n                    current_level[w] = current_level[u] + 1;\n                    q.push(w);\n                }\n            }\n        }\n        \n        current_contribution = (long long)(current_level[v] + 1) * beauty[v];\n        \n        // Try each neighbor as a new parent\n        for (int new_parent : adj[v]) {\n            if (new_parent == current_parent) continue;\n            \n            parent[v] = new_parent;\n            \n            // Check validity quickly\n            vector<int> new_level(N, -1);\n            vector<int> in_degree(N, 0);\n            for (int i = 0; i < N; i++) {\n                if (parent[i] != -1) {\n                    in_degree[parent[i]]++;\n                }\n            }\n            \n            // Simple cycle check would be complex, so just revert for now\n            parent[v] = current_parent;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> H;\n    \n    beauty.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> beauty[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Start with strategy 1\n    solve_strategy1();\n    \n    // Try strategy 2 and keep better solution\n    solve_strategy2();\n    \n    // Apply simple local improvement\n    simple_local_improvement();\n    \n    for (int i = 0; i < N; i++) {\n        cout << parent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\n// Check if column j has any Fukunokami above row i\nbool hasFukuAbove(const vector<vector<char>>& board, int i, int j) {\n    for (int r = 0; r < i; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if column j has any Fukunokami below row i\nbool hasFukuBelow(const vector<vector<char>>& board, int i, int j) {\n    for (int r = i + 1; r < N; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the left of column j\nbool hasFukuLeft(const vector<vector<char>>& board, int i, int j) {\n    for (int c = 0; c < j; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the right of column j\nbool hasFukuRight(const vector<vector<char>>& board, int i, int j) {\n    for (int c = j + 1; c < N; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<char>> board(N, vector<char>(N));\n    vector<pair<int, int>> oniPositions;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            board[i][j] = line[j];\n            if (line[j] == 'x') {\n                oniPositions.push_back({i, j});\n            }\n        }\n    }\n    \n    vector<pair<char, int>> moves;\n    \n    // Strategy: Alternate between processing rows and columns based on efficiency\n    // Keep track of which Oni we've \"handled\"\n    vector<bool> handled(oniPositions.size(), false);\n    \n    // Group Oni by row and column\n    vector<vector<int>> oniInRow(N);\n    vector<vector<int>> oniInCol(N);\n    \n    for (int idx = 0; idx < (int)oniPositions.size(); idx++) {\n        int i = oniPositions[idx].first;\n        int j = oniPositions[idx].second;\n        oniInRow[i].push_back(idx);\n        oniInCol[j].push_back(idx);\n    }\n    \n    // Process in rounds - alternate between rows and columns\n    bool processRows = true;\n    int rounds = 0;\n    \n    while (rounds < 40) { // Safety limit\n        bool didSomething = false;\n        \n        if (processRows) {\n            // Process rows\n            for (int i = 0; i < N; i++) {\n                if (oniInRow[i].empty()) continue;\n                \n                // Check if there are unhandled Oni in this row\n                vector<int> unhandledOni;\n                for (int idx : oniInRow[i]) {\n                    if (!handled[idx]) {\n                        unhandledOni.push_back(idx);\n                    }\n                }\n                \n                if (unhandledOni.empty()) continue;\n                \n                // Get column positions of unhandled Oni\n                vector<int> cols;\n                for (int idx : unhandledOni) {\n                    cols.push_back(oniPositions[idx].second);\n                }\n                \n                // Check safety for shifting left or right\n                bool canShiftLeft = true, canShiftRight = true;\n                \n                for (int idx : unhandledOni) {\n                    int col = oniPositions[idx].second;\n                    if (hasFukuLeft(board, i, col)) {\n                        canShiftLeft = false;\n                    }\n                    if (hasFukuRight(board, i, col)) {\n                        canShiftRight = false;\n                    }\n                }\n                \n                if (canShiftLeft || canShiftRight) {\n                    if (canShiftLeft && canShiftRight) {\n                        int maxLeft = *max_element(cols.begin(), cols.end());\n                        int maxRight = N - 1 - *min_element(cols.begin(), cols.end());\n                        \n                        if (maxLeft <= maxRight) {\n                            // Shift left\n                            for (int k = 0; k < maxLeft; k++) {\n                                moves.push_back({'L', i});\n                            }\n                            for (int k = 0; k < maxLeft; k++) {\n                                moves.push_back({'R', i});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInRow[i].clear();\n                        } else {\n                            // Shift right\n                            for (int k = 0; k < maxRight; k++) {\n                                moves.push_back({'R', i});\n                            }\n                            for (int k = 0; k < maxRight; k++) {\n                                moves.push_back({'L', i});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInRow[i].clear();\n                        }\n                    } else if (canShiftLeft) {\n                        int maxLeft = *max_element(cols.begin(), cols.end());\n                        for (int k = 0; k < maxLeft; k++) {\n                            moves.push_back({'L', i});\n                        }\n                        for (int k = 0; k < maxLeft; k++) {\n                            moves.push_back({'R', i});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInRow[i].clear();\n                    } else if (canShiftRight) {\n                        int maxRight = N - 1 - *min_element(cols.begin(), cols.end());\n                        for (int k = 0; k < maxRight; k++) {\n                            moves.push_back({'R', i});\n                        }\n                        for (int k = 0; k < maxRight; k++) {\n                            moves.push_back({'L', i});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInRow[i].clear();\n                    }\n                    \n                    didSomething = true;\n                }\n            }\n        } else {\n            // Process columns\n            for (int j = 0; j < N; j++) {\n                if (oniInCol[j].empty()) continue;\n                \n                // Check if there are unhandled Oni in this column\n                vector<int> unhandledOni;\n                for (int idx : oniInCol[j]) {\n                    if (!handled[idx]) {\n                        unhandledOni.push_back(idx);\n                    }\n                }\n                \n                if (unhandledOni.empty()) continue;\n                \n                // Get row positions of unhandled Oni\n                vector<int> rows;\n                for (int idx : unhandledOni) {\n                    rows.push_back(oniPositions[idx].first);\n                }\n                \n                // Check safety for shifting up or down\n                bool canShiftUp = true, canShiftDown = true;\n                \n                for (int idx : unhandledOni) {\n                    int row = oniPositions[idx].first;\n                    if (hasFukuAbove(board, row, j)) {\n                        canShiftUp = false;\n                    }\n                    if (hasFukuBelow(board, row, j)) {\n                        canShiftDown = false;\n                    }\n                }\n                \n                if (canShiftUp || canShiftDown) {\n                    if (canShiftUp && canShiftDown) {\n                        int maxUp = *max_element(rows.begin(), rows.end());\n                        int maxDown = N - 1 - *min_element(rows.begin(), rows.end());\n                        \n                        if (maxUp <= maxDown) {\n                            // Shift up\n                            for (int k = 0; k < maxUp; k++) {\n                                moves.push_back({'U', j});\n                            }\n                            for (int k = 0; k < maxUp; k++) {\n                                moves.push_back({'D', j});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInCol[j].clear();\n                        } else {\n                            // Shift down\n                            for (int k = 0; k < maxDown; k++) {\n                                moves.push_back({'D', j});\n                            }\n                            for (int k = 0; k < maxDown; k++) {\n                                moves.push_back({'U', j});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInCol[j].clear();\n                        }\n                    } else if (canShiftUp) {\n                        int maxUp = *max_element(rows.begin(), rows.end());\n                        for (int k = 0; k < maxUp; k++) {\n                            moves.push_back({'U', j});\n                        }\n                        for (int k = 0; k < maxUp; k++) {\n                            moves.push_back({'D', j});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInCol[j].clear();\n                    } else if (canShiftDown) {\n                        int maxDown = N - 1 - *min_element(rows.begin(), rows.end());\n                        for (int k = 0; k < maxDown; k++) {\n                            moves.push_back({'D', j});\n                        }\n                        for (int k = 0; k < maxDown; k++) {\n                            moves.push_back({'U', j});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInCol[j].clear();\n                    }\n                    \n                    didSomething = true;\n                }\n            }\n        }\n        \n        if (!didSomething) {\n            // Try the other approach\n            processRows = !processRows;\n            rounds++;\n            if (rounds > 40) break;\n        } else {\n            processRows = !processRows; // Switch between rows and columns\n            rounds++;\n        }\n        \n        // Check if all Oni are handled\n        bool allHandled = true;\n        for (bool h : handled) {\n            if (!h) {\n                allHandled = false;\n                break;\n            }\n        }\n        if (allHandled) break;\n    }\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint target[N];\nint a[N], b[N];\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(42);\n    \n    int dummy_L, L;\n    cin >> dummy_L >> L;\n    for (int i = 0; i < N; i++) {\n        cin >> target[i];\n    }\n    \n    // Simple ring structure - proven to work reasonably well\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    \n    // Very conservative adjustments - only make a few strategic ones\n    vector<pair<int, int>> targets;\n    for (int i = 0; i < N; i++) {\n        targets.push_back({target[i], i});\n    }\n    sort(targets.begin(), targets.end(), greater<pair<int, int>>());\n    \n    // Only adjust the top 10 employees, and do it minimally\n    for (int i = 0; i < min(10, N/10); i++) {\n        int favored_emp = targets[i].second;\n        int favored_target = targets[i].first;\n        \n        // Very conservative - only 2-3 adjustments\n        int adjustments = min(3, max(1, favored_target / 2000));\n        \n        for (int j = 0; j < adjustments; j++) {\n            int from_emp = rand() % N;\n            // Always adjust 'a' for more predictable behavior\n            a[from_emp] = favored_emp;\n        }\n    }\n    \n    // Output result\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\nconst int N = 800;\nconst int MAX_Q = 400;\nconst int MAX_L = 15;\n\nint n, m, q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<pair<long long, long long>> centers;\nvector<vector<int>> groups;\nint queries_used = 0;\n\n// Query function with proper count tracking\nvector<pair<int, int>> query(const vector<int>& cities) {\n    if (queries_used >= q) {\n        return {}; // Don't make more queries than allowed\n    }\n    \n    if (cities.size() < 2 || cities.size() > L) {\n        return {};\n    }\n    \n    cout << \"? \" << cities.size();\n    for (int city : cities) {\n        cout << \" \" << city;\n    }\n    cout << endl;\n    cout.flush();\n    \n    queries_used++;\n    \n    vector<pair<int, int>> result;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        if (u > v) swap(u, v);\n        result.push_back({u, v});\n    }\n    \n    return result;\n}\n\n// Calculate squared distance between centers (to avoid floating point)\nlong long calc_center_distance_sq(int i, int j) {\n    long long cx1 = lx[i] + rx[i]; // Using sum to avoid division\n    long long cy1 = ly[i] + ry[i];\n    long long cx2 = lx[j] + rx[j];\n    long long cy2 = ly[j] + ry[j];\n    return (cx1 - cx2) * (cx1 - cx2) + (cy1 - cy2) * (cy1 - cy2);\n}\n\n// Spatial clustering using a greedy approach\nvoid spatial_clustering() {\n    // Calculate centers\n    centers.clear();\n    for (int i = 0; i < n; i++) {\n        long long cx = (long long)(lx[i] + rx[i]);\n        long long cy = (long long)(ly[i] + ry[i]);\n        centers.push_back({cx, cy});\n    }\n    \n    // Initialize groups\n    groups.clear();\n    groups.resize(m);\n    \n    // Create list of all cities with their indices\n    vector<int> cities(n);\n    iota(cities.begin(), cities.end(), 0);\n    \n    // Shuffle cities to avoid bias\n    random_shuffle(cities.begin(), cities.end());\n    \n    // Assign first M cities, one to each group\n    for (int i = 0; i < min(m, n); i++) {\n        groups[i].push_back(cities[i]);\n    }\n    \n    // Assign remaining cities to the group whose current members are closest on average\n    for (int i = m; i < n; i++) {\n        int city_idx = cities[i];\n        int best_group = 0;\n        long long best_score = 1e18;\n        \n        // Find the group that minimizes average distance to this city\n        for (int g = 0; g < m; g++) {\n            if (groups[g].empty()) {\n                best_group = g;\n                break;\n            }\n            \n            long long total_dist = 0;\n            for (int member : groups[g]) {\n                total_dist += calc_center_distance_sq(city_idx, member);\n            }\n            long long avg_dist = total_dist / groups[g].size();\n            \n            if (avg_dist < best_score) {\n                best_score = avg_dist;\n                best_group = g;\n            }\n        }\n        \n        // Check if this group still needs more members\n        if ((int)groups[best_group].size() < G[best_group]) {\n            groups[best_group].push_back(city_idx);\n        } else {\n            // Find a group that still needs members\n            for (int g = 0; g < m; g++) {\n                if ((int)groups[g].size() < G[g]) {\n                    groups[g].push_back(city_idx);\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Fix any groups that don't have the right size (shouldn't happen with correct logic)\n    // This is a safety net\n    vector<int> unassigned;\n    for (int g = 0; g < m; g++) {\n        while ((int)groups[g].size() > G[g]) {\n            unassigned.push_back(groups[g].back());\n            groups[g].pop_back();\n        }\n    }\n    \n    for (int g = 0; g < m && !unassigned.empty(); g++) {\n        while ((int)groups[g].size() < G[g] && !unassigned.empty()) {\n            groups[g].push_back(unassigned.back());\n            unassigned.pop_back();\n        }\n    }\n}\n\n// Use queries strategically\nvoid strategic_querying() {\n    // First, query small groups entirely if possible\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= 1) continue;\n        \n        // If group size is small enough, query the whole group\n        if (G[i] <= L) {\n            query(groups[i]);\n            if (queries_used >= q) return;\n        }\n    }\n    \n    // For larger groups, do strategic querying\n    for (int i = 0; i < m && queries_used < q; i++) {\n        if (G[i] <= L) continue; // Already handled above\n        if (G[i] <= 1) continue;\n        \n        // Query overlapping windows to build better connectivity information\n        int window_size = min(L, G[i]);\n        int step = max(1, window_size - 1);\n        \n        for (int start = 0; start < G[i] - 1 && queries_used < q; start += step) {\n            int end = min(start + window_size, G[i]);\n            vector<int> subset;\n            for (int j = start; j < end; j++) {\n                subset.push_back(groups[i][j]);\n            }\n            \n            if (subset.size() >= 2) {\n                query(subset);\n            }\n            \n            if (queries_used >= q) break;\n        }\n        \n        if (queries_used >= q) break;\n    }\n    \n    // Use remaining queries for cross-validation or boundary detection\n    // Query triplets at boundaries of groups to improve connectivity\n    for (int i = 0; i < m && queries_used < q - 2; i++) {\n        if (G[i] <= 2) continue;\n        \n        // Query first few cities\n        vector<int> start_subset;\n        int end_start = min(3, G[i]);\n        for (int j = 0; j < end_start; j++) {\n            start_subset.push_back(groups[i][j]);\n        }\n        if (start_subset.size() >= 2) {\n            query(start_subset);\n        }\n        if (queries_used >= q) break;\n        \n        // Query last few cities\n        vector<int> end_subset;\n        int start_end = max(0, G[i] - 3);\n        for (int j = start_end; j < G[i]; j++) {\n            end_subset.push_back(groups[i][j]);\n        }\n        if (end_subset.size() >= 2) {\n            query(end_subset);\n        }\n        if (queries_used >= q) break;\n    }\n}\n\n// Improved MST building using Union-Find for better approximation\nclass UnionFind {\nprivate:\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]); // Path compression\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int root_x = find(x);\n        int root_y = find(y);\n        \n        if (root_x == root_y) return false;\n        \n        // Union by rank\n        if (rank[root_x] < rank[root_y]) {\n            swap(root_x, root_y);\n        }\n        parent[root_y] = root_x;\n        if (rank[root_x] == rank[root_y]) {\n            rank[root_x]++;\n        }\n        return true;\n    }\n};\n\n// Build MST for group with better approximation\nvector<pair<int, int>> build_group_mst(const vector<int>& group) {\n    if (group.size() <= 1) return {};\n    \n    // If we can query the entire group and still have queries left\n    if ((int)group.size() <= L && queries_used < q) {\n        return query(group);\n    }\n    \n    // Otherwise, build approximate MST using center distances\n    vector<tuple<long long, int, int>> edges;\n    \n    // Generate all possible edges with their approximate weights\n    for (int i = 0; i < (int)group.size(); i++) {\n        for (int j = i + 1; j < (int)group.size(); j++) {\n            long long dist = calc_center_distance_sq(group[i], group[j]);\n            edges.push_back({dist, group[i], group[j]});\n        }\n    }\n    \n    // Sort edges by weight\n    sort(edges.begin(), edges.end());\n    \n    // Kruskal's algorithm\n    UnionFind uf(n);\n    vector<pair<int, int>> mst;\n    \n    for (const auto& edge : edges) {\n        long long weight;\n        int u, v;\n        tie(weight, u, v) = edge;\n        \n        if (uf.unite(u, v)) {\n            mst.push_back({min(u, v), max(u, v)});\n            if ((int)mst.size() == (int)group.size() - 1) break;\n        }\n    }\n    \n    return mst;\n}\n\n// Build MSTs for all groups\nvector<vector<pair<int, int>>> build_all_msts() {\n    vector<vector<pair<int, int>>> result(m);\n    \n    for (int i = 0; i < m; i++) {\n        result[i] = build_group_mst(groups[i]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // For reproducibility\n    srand(42);\n    \n    // Read input\n    cin >> n >> m >> q >> L >> W;\n    G.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> G[i];\n    }\n    \n    lx.resize(n);\n    rx.resize(n);\n    ly.resize(n);\n    ry.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Perform spatial clustering\n    spatial_clustering();\n    \n    // Strategic querying\n    strategic_querying();\n    \n    // Build MSTs for final answer\n    vector<vector<pair<int, int>>> msts = build_all_msts();\n    \n    // Output final answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            cout << groups[i][j];\n            if (j < (int)groups[i].size() - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n        \n        for (const auto& edge : msts[i]) {\n            cout << edge.first << \" \" << edge.second << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int _x, int _y) : x(_x), y(_y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass SkatingSolver {\nprivate:\n    int grid[N][N]; // 0 = empty, 1 = block\n    Point pos;\n    vector<Point> targets;\n    vector<string> actions;\n    \npublic:\n    SkatingSolver() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        int n, m;\n        cin >> n >> m;\n        int x, y;\n        cin >> x >> y;\n        pos = Point(x, y);\n        \n        targets.resize(m);\n        for (int i = 0; i < m; i++) {\n            cin >> targets[i].x >> targets[i].y;\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void add_action(char action, char direction) {\n        actions.push_back(string(1, action) + \" \" + string(1, direction));\n    }\n    \n    // Move one step in given direction\n    bool move(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (!is_valid(nx, ny) || grid[nx][ny] == 1) {\n            return false;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('M', dir_chars[dir]);\n        return true;\n    }\n    \n    // Slide until hitting a block or boundary\n    void slide(int dir) {\n        int nx = pos.x, ny = pos.y;\n        \n        while (true) {\n            int tx = nx + dx[dir];\n            int ty = ny + dy[dir];\n            \n            if (!is_valid(tx, ty) || grid[tx][ty] == 1) {\n                break;\n            }\n            \n            nx = tx;\n            ny = ty;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('S', dir_chars[dir]);\n    }\n    \n    // Place or remove block\n    void alter(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            grid[nx][ny] = 1 - grid[nx][ny];\n        }\n        \n        add_action('A', dir_chars[dir]);\n    }\n    \n    // Find direction from point a to point b\n    int get_direction(Point a, Point b) {\n        if (a.x > b.x) return 0; // U\n        if (a.x < b.x) return 1; // D\n        if (a.y > b.y) return 2; // L\n        if (a.y < b.y) return 3; // R\n        return -1; // Same position\n    }\n    \n    // Manhattan distance\n    int manhattan_distance(Point a, Point b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Simple path finding using moves only\n    void move_to_target(Point target) {\n        // Use greedy approach - move in the direction that reduces distance\n        for (int step = 0; step < 1000 && !(pos == target); step++) {\n            int best_dir = -1;\n            int min_dist = manhattan_distance(pos, target);\n            \n            // Try all directions\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = pos.x + dx[dir];\n                int ny = pos.y + dy[dir];\n                \n                if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                    int dist = abs(nx - target.x) + abs(ny - target.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_dir = dir;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                move(best_dir);\n            } else {\n                // If stuck, try any valid move\n                bool moved = false;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (move(dir)) {\n                        moved = true;\n                        break;\n                    }\n                }\n                if (!moved) break;\n            }\n        }\n    }\n    \n    // Enhanced strategy using slides when possible\n    void smart_move_to_target(Point target) {\n        if (pos == target) return;\n        \n        // If in same row or column, consider sliding\n        if (pos.x == target.x || pos.y == target.y) {\n            int dir = get_direction(pos, target);\n            if (dir != -1) {\n                // Check if we can slide directly\n                bool can_slide_directly = true;\n                Point temp_pos = pos;\n                \n                while (!(temp_pos == target)) {\n                    int nx = temp_pos.x + dx[dir];\n                    int ny = temp_pos.y + dy[dir];\n                    \n                    if (!is_valid(nx, ny)) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    if (grid[nx][ny] == 1) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    temp_pos.x = nx;\n                    temp_pos.y = ny;\n                }\n                \n                if (can_slide_directly) {\n                    slide(dir);\n                    return;\n                }\n            }\n        }\n        \n        // Otherwise use regular move-to-target\n        move_to_target(target);\n    }\n    \n    void solve() {\n        // Visit each target in order\n        for (int i = 1; i < (int)targets.size(); i++) {\n            // If target has a block, remove it first\n            if (grid[targets[i].x][targets[i].y] == 1) {\n                // Find adjacent empty spot to remove block\n                for (int dir = 0; dir < 4; dir++) {\n                    int nx = targets[i].x + dx[dir];\n                    int ny = targets[i].y + dy[dir];\n                    \n                    if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                        // Move to adjacent position and remove block\n                        Point adj_pos(nx, ny);\n                        \n                        // Move to adjacent position\n                        move_to_target(adj_pos);\n                        \n                        // Remove block (opposite direction)\n                        int opposite_dir = (dir == 0) ? 1 : (dir == 1) ? 0 : (dir == 2) ? 3 : 2;\n                        alter(opposite_dir);\n                        break;\n                    }\n                }\n            }\n            \n            // Move to target\n            smart_move_to_target(targets[i]);\n        }\n    }\n    \n    void print_solution() {\n        for (const string& action : actions) {\n            cout << action << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    SkatingSolver solver;\n    solver.read_input();\n    solver.solve();\n    solver.print_solution();\n    \n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Company {\n    int id, x, y, r;\n};\n\nstruct Rectangle {\n    int a, b, c, d; // (a,b) to (c,d) where a<c and b<d\n};\n\nconst int SIZE = 10000;\nvector<Rectangle> rectangles;\nvector<Company> companies;\n\n// Check if two rectangles overlap (touching edges is OK)\nbool overlap(int a1, int b1, int c1, int d1, int a2, int b2, int c2, int d2) {\n    return !(c1 <= a2 || c2 <= a1 || d1 <= b2 || d2 <= b1);\n}\n\n// Check if rectangle overlaps with existing rectangles\nbool has_overlap(int a, int b, int c, int d) {\n    for (const auto& rect : rectangles) {\n        if (rect.a != -1) {\n            if (overlap(a, b, c, d, rect.a, rect.b, rect.c, rect.d)) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n// Find reasonable factors of area\nvector<pair<int, int>> get_factors(int area) {\n    vector<pair<int, int>> factors;\n    \n    int limit = min(130, (int)sqrt(area) + 45);\n    \n    for (int w = 1; w <= min(limit, area); w++) {\n        if (area % w == 0) {\n            int h = area / w;\n            if (h <= SIZE) {\n                factors.push_back({w, h});\n                if (w != h && h <= limit && w <= SIZE) {\n                    factors.push_back({h, w});\n                }\n            }\n        }\n    }\n    \n    // Keep unique factors and limit\n    sort(factors.begin(), factors.end());\n    factors.erase(unique(factors.begin(), factors.end()), factors.end());\n    \n    if (factors.size() > 40) {\n        factors.resize(40);\n    }\n    \n    return factors;\n}\n\n// Try to place rectangle for company\nbool place_company(const Company& comp) {\n    int target_x = comp.x;\n    int target_y = comp.y;\n    int area = comp.r;\n    \n    auto factors = get_factors(area);\n    \n    // Try exact area with improved search\n    for (auto& factor : factors) {\n        int w = factor.first;\n        int h = factor.second;\n        \n        // Adaptive search window\n        int search_limit = min(30, max(8, min(w, h) / 3));\n        \n        int center_a = target_x - w/2;\n        int center_b = target_y - h/2;\n        \n        // Priority search: check center first\n        if (center_a >= 0 && center_b >= 0 && center_a + w <= SIZE && center_b + h <= SIZE) {\n            if (center_a <= target_x && target_x < center_a + w && \n                center_b <= target_y && target_y < center_b + h) {\n                if (!has_overlap(center_a, center_b, center_a + w, center_b + h)) {\n                    rectangles[comp.id] = {center_a, center_b, center_a + w, center_b + h};\n                    return true;\n                }\n            }\n        }\n        \n        // Then expand search in layers (more systematic)\n        for (int radius = 1; radius <= search_limit; radius++) {\n            // Check perimeter of square with given radius\n            for (int dx = -radius; dx <= radius; dx++) {\n                int dy_vals[2] = {-radius, radius};\n                if (radius == 0) dy_vals[1] = 0;\n                \n                for (int j = 0; j < (radius == 0 ? 1 : 2); j++) {\n                    int dy = dy_vals[j];\n                    int a = center_a + dx;\n                    int b = center_b + dy;\n                    int c = a + w;\n                    int d = b + h;\n                    \n                    if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                        if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                            if (!has_overlap(a, b, c, d)) {\n                                rectangles[comp.id] = {a, b, c, d};\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Check vertical sides\n            if (radius > 0) {\n                for (int dy = -radius + 1; dy < radius; dy++) {\n                    int dx_vals[2] = {-radius, radius};\n                    for (int k = 0; k < 2; k++) {\n                        int dx = dx_vals[k];\n                        int a = center_a + dx;\n                        int b = center_b + dy;\n                        int c = a + w;\n                        int d = b + h;\n                        \n                        if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                            if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                if (!has_overlap(a, b, c, d)) {\n                                    rectangles[comp.id] = {a, b, c, d};\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Try approximate areas\n    for (int delta = 1; delta <= min(35, area/100); delta++) {\n        vector<int> test_areas;\n        if (area + delta <= SIZE * SIZE) test_areas.push_back(area + delta);\n        if (area - delta > 0) test_areas.push_back(area - delta);\n        \n        for (int test_area : test_areas) {\n            auto test_factors = get_factors(test_area);\n            for (auto& factor : test_factors) {\n                int w = factor.first;\n                int h = factor.second;\n                \n                int search_limit = min(22, max(6, min(w, h) / 4));\n                int center_a = target_x - w/2;\n                int center_b = target_y - h/2;\n                \n                // Priority center check\n                if (center_a >= 0 && center_b >= 0 && center_a + w <= SIZE && center_b + h <= SIZE) {\n                    if (center_a <= target_x && target_x < center_a + w && \n                        center_b <= target_y && target_y < center_b + h) {\n                        if (!has_overlap(center_a, center_b, center_a + w, center_b + h)) {\n                            rectangles[comp.id] = {center_a, center_b, center_a + w, center_b + h};\n                            return true;\n                        }\n                    }\n                }\n                \n                // Layered search\n                for (int radius = 1; radius <= search_limit; radius++) {\n                    for (int dx = -radius; dx <= radius; dx++) {\n                        int dy_vals[2] = {-radius, radius};\n                        if (radius == 0) dy_vals[1] = 0;\n                        \n                        for (int j = 0; j < (radius == 0 ? 1 : 2); j++) {\n                            int dy = dy_vals[j];\n                            int a = center_a + dx;\n                            int b = center_b + dy;\n                            int c = a + w;\n                            int d = b + h;\n                            \n                            if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                    if (!has_overlap(a, b, c, d)) {\n                                        rectangles[comp.id] = {a, b, c, d};\n                                        return true;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (radius > 0) {\n                        for (int dy = -radius + 1; dy < radius; dy++) {\n                            int dx_vals[2] = {-radius, radius};\n                            for (int k = 0; k < 2; k++) {\n                                int dx = dx_vals[k];\n                                int a = center_a + dx;\n                                int b = center_b + dy;\n                                int c = a + w;\n                                int d = b + h;\n                                \n                                if (a >= 0 && b >= 0 && c <= SIZE && d <= SIZE) {\n                                    if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                        if (!has_overlap(a, b, c, d)) {\n                                            rectangles[comp.id] = {a, b, c, d};\n                                            return true;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Enhanced fallback - local placement with more variations\n    for (int size_factor = 1; size_factor <= 5; size_factor++) {\n        for (int w = 1; w <= min(80, max(1, area / (25 * size_factor))); w++) {\n            if (area % w == 0 || w <= area) {\n                int h = (area + w - 1) / w;\n                if (h > SIZE) {\n                    h = min(SIZE, area);\n                    w = (area + h - 1) / h;\n                }\n                \n                if (w <= SIZE && h <= SIZE) {\n                    for (int dx = -8; dx <= 8; dx++) {\n                        for (int dy = -8; dy <= 8; dy++) {\n                            int a = max(0, min(SIZE - w, target_x + dx));\n                            int b = max(0, min(SIZE - h, target_y + dy));\n                            int c = a + w;\n                            int d = b + h;\n                            \n                            if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                                if (!has_overlap(a, b, c, d)) {\n                                    rectangles[comp.id] = {a, b, c, d};\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Final fallback - place anywhere valid\n    for (int attempt = 0; attempt < 200; attempt++) {\n        int w = min(80, max(1, area / 10));\n        int h = (area + w - 1) / w;\n        if (h > SIZE) {\n            h = min(SIZE, area);\n            w = (area + h - 1) / h;\n        }\n        \n        if (w <= SIZE && h <= SIZE && w * h >= area) {\n            while (w * h > area && w > 1) w--;\n            while (w * h > area && h > 1) h--;\n            \n            int a = max(0, min(SIZE - w, target_x));\n            int b = max(0, min(SIZE - h, target_y));\n            int c = a + w;\n            int d = b + h;\n            \n            if (c <= SIZE && d <= SIZE) {\n                if (a <= target_x && target_x < c && b <= target_y && target_y < d) {\n                    if (!has_overlap(a, b, c, d)) {\n                        rectangles[comp.id] = {a, b, c, d};\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Absolute last resort\n    rectangles[comp.id] = {0, 0, 1, 1};\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    companies.resize(n);\n    rectangles.assign(n, {-1, -1, -1, -1});\n    \n    vector<pair<int, int>> areas_indices;\n    \n    for (int i = 0; i < n; i++) {\n        companies[i].id = i;\n        cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        areas_indices.push_back({companies[i].r, i});\n    }\n    \n    // Sort by area descending\n    sort(areas_indices.rbegin(), areas_indices.rend());\n    \n    // Place each company\n    for (const auto& area_idx : areas_indices) {\n        int idx = area_idx.second;\n        place_company(companies[idx]);\n    }\n    \n    // Output results\n    for (const auto& rect : rectangles) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int SIZE = 50;\nint si, sj;\nint tile_id[SIZE][SIZE];\nint points[SIZE][SIZE];\nvector<pair<int,int>> tile_cells[2500];\nint tile_values[2500];\nbool tile_visited[2500];\n\n// Directions: U, D, L, R\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nvoid preprocess_tiles() {\n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            int tid = tile_id[i][j];\n            tile_cells[tid].push_back({i, j});\n        }\n    }\n    \n    // Precompute tile values\n    for (int tile = 0; tile < 2500; tile++) {\n        tile_values[tile] = 0;\n        for (auto& cell : tile_cells[tile]) {\n            tile_values[tile] += points[cell.first][cell.second];\n        }\n    }\n}\n\nbool is_valid_position(int x, int y) {\n    return x >= 0 && x < SIZE && y >= 0 && y < SIZE;\n}\n\n// Strategy 0: Pure greedy by tile value\nstring strategy_pure_greedy() {\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int x = si, y = sj;\n    int current_tile = tile_id[x][y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    for (int step = 0; step < 2500; step++) {\n        int best_value = -1;\n        int best_dir = -1;\n        int best_nx = -1, best_ny = -1;\n        int best_next_tile = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (is_valid_position(nx, ny)) {\n                int next_tile = tile_id[nx][ny];\n                if (!tile_visited[next_tile]) {\n                    int tile_value = tile_values[next_tile];\n                    if (tile_value > best_value) {\n                        best_value = tile_value;\n                        best_dir = d;\n                        best_nx = nx;\n                        best_ny = ny;\n                        best_next_tile = next_tile;\n                    }\n                }\n            }\n        }\n        \n        if (best_dir == -1) {\n            break;\n        }\n        \n        path += dir_char[best_dir];\n        x = best_nx;\n        y = best_ny;\n        tile_visited[best_next_tile] = true;\n        current_tile = best_next_tile;\n    }\n    \n    return path;\n}\n\n// Strategy 1: Greedy with future options consideration\nstring strategy_future_aware() {\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int x = si, y = sj;\n    int current_tile = tile_id[x][y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    for (int step = 0; step < 2500; step++) {\n        int best_score = -1;\n        int best_dir = -1;\n        int best_nx = -1, best_ny = -1;\n        int best_next_tile = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (is_valid_position(nx, ny)) {\n                int next_tile = tile_id[nx][ny];\n                if (!tile_visited[next_tile]) {\n                    int tile_value = tile_values[next_tile];\n                    \n                    // Count future accessible tiles\n                    int future_count = 0;\n                    tile_visited[next_tile] = true;\n                    \n                    for (auto& cell : tile_cells[next_tile]) {\n                        for (int fd = 0; fd < 4; fd++) {\n                            int fnx = cell.first + dx[fd];\n                            int fny = cell.second + dy[fd];\n                            if (is_valid_position(fnx, fny)) {\n                                int future_tile = tile_id[fnx][fny];\n                                if (!tile_visited[future_tile]) {\n                                    future_count++;\n                                }\n                            }\n                        }\n                    }\n                    \n                    tile_visited[next_tile] = false;\n                    \n                    // Combined score\n                    int score = tile_value + future_count * 3;\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = d;\n                        best_nx = nx;\n                        best_ny = ny;\n                        best_next_tile = next_tile;\n                    }\n                }\n            }\n        }\n        \n        if (best_dir == -1) {\n            break;\n        }\n        \n        path += dir_char[best_dir];\n        x = best_nx;\n        y = best_ny;\n        tile_visited[best_next_tile] = true;\n        current_tile = best_next_tile;\n    }\n    \n    return path;\n}\n\n// Strategy 2: Prefer tiles with more future options (exploration)\nstring strategy_exploration() {\n    memset(tile_visited, false, sizeof(tile_visited));\n    \n    int x = si, y = sj;\n    int current_tile = tile_id[x][y];\n    tile_visited[current_tile] = true;\n    \n    string path = \"\";\n    \n    for (int step = 0; step < 2500; step++) {\n        int best_score = -1;\n        int best_dir = -1;\n        int best_nx = -1, best_ny = -1;\n        int best_next_tile = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (is_valid_position(nx, ny)) {\n                int next_tile = tile_id[nx][ny];\n                if (!tile_visited[next_tile]) {\n                    int tile_value = tile_values[next_tile];\n                    \n                    // Count future accessible tiles\n                    int future_count = 0;\n                    tile_visited[next_tile] = true;\n                    \n                    for (auto& cell : tile_cells[next_tile]) {\n                        for (int fd = 0; fd < 4; fd++) {\n                            int fnx = cell.first + dx[fd];\n                            int fny = cell.second + dy[fd];\n                            if (is_valid_position(fnx, fny)) {\n                                int future_tile = tile_id[fnx][fny];\n                                if (!tile_visited[future_tile]) {\n                                    future_count++;\n                                }\n                            }\n                        }\n                    }\n                    \n                    tile_visited[next_tile] = false;\n                    \n                    // Prioritize future options more heavily\n                    int score = future_count * 10 + tile_value;\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = d;\n                        best_nx = nx;\n                        best_ny = ny;\n                        best_next_tile = next_tile;\n                    }\n                }\n            }\n        }\n        \n        if (best_dir == -1) {\n            break;\n        }\n        \n        path += dir_char[best_dir];\n        x = best_nx;\n        y = best_ny;\n        tile_visited[best_next_tile] = true;\n        current_tile = best_next_tile;\n    }\n    \n    return path;\n}\n\nstring solve() {\n    // Generate multiple strategies and pick the best\n    vector<string> strategies;\n    \n    strategies.push_back(strategy_pure_greedy());\n    strategies.push_back(strategy_future_aware());\n    strategies.push_back(strategy_exploration());\n    \n    // Pick the strategy that gives the longest path (more tiles visited = more points)\n    string best_result = \"\";\n    int best_length = 0;\n    \n    for (const auto& result : strategies) {\n        if ((int)result.length() > best_length) {\n            best_length = result.length();\n            best_result = result;\n        }\n    }\n    \n    return best_result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> tile_id[i][j];\n        }\n    }\n    \n    for (int i = 0; i < SIZE; i++) {\n        for (int j = 0; j < SIZE; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess_tiles();\n    \n    string result = solve();\n    cout << result << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int QUERY_COUNT = 1000;\n\n// Edge weight estimates with confidence\nvector<vector<double>> h_edges; // horizontal edges (i,j) to (i,j+1)\nvector<vector<double>> v_edges; // vertical edges (i,j) to (i+1,j)\nvector<vector<double>> h_confidence; // confidence in h_edge estimates\nvector<vector<double>> v_confidence; // confidence in v_edge estimates\n\n// Count of times each edge has been used\nvector<vector<int>> h_usage_count;\nvector<vector<int>> v_usage_count;\n\n// Initialize edge weights\nvoid initialize_weights() {\n    // Better initial estimate based on problem parameters\n    h_edges.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 5000.0));\n    v_edges.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 5000.0));\n    \n    // Initialize confidence (lower means less certain)\n    h_confidence.assign(GRID_SIZE, vector<double>(GRID_SIZE - 1, 1.0));\n    v_confidence.assign(GRID_SIZE - 1, vector<double>(GRID_SIZE, 1.0));\n    \n    // Usage counts\n    h_usage_count.assign(GRID_SIZE, vector<int>(GRID_SIZE - 1, 0));\n    v_usage_count.assign(GRID_SIZE - 1, vector<int>(GRID_SIZE, 0));\n}\n\n// Calculate path length using current estimates\ndouble calculate_estimated_length(const vector<pair<int,int>>& path) {\n    double length = 0.0;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) {\n            length += h_edges[r1][c1];\n        } else if (r1 == r2 && c2 == c1 - 1) {\n            length += h_edges[r1][c2];\n        } else if (c1 == c2 && r2 == r1 + 1) {\n            length += v_edges[r1][c1];\n        } else if (c1 == c2 && r2 == r1 - 1) {\n            length += v_edges[r2][c1];\n        }\n    }\n    return length;\n}\n\n// Get actual length from the last query\nint get_actual_length() {\n    int actual_length;\n    cin >> actual_length;\n    return actual_length;\n}\n\n// Find shortest path using A* with current estimates and some exploration\nvector<pair<int,int>> find_shortest_path(int start_r, int start_c, int end_r, int end_c, int query_num) {\n    // For very short distances, just use Manhattan path\n    int manhattan_dist = abs(start_r - end_r) + abs(start_c - end_c);\n    if (manhattan_dist <= 10 && query_num > 100) {\n        vector<pair<int,int>> path;\n        path.push_back({start_r, start_c});\n        int r = start_r, c = start_c;\n        \n        // Move vertically first\n        while (r < end_r) {\n            r++;\n            path.push_back({r, c});\n        }\n        while (r > end_r) {\n            r--;\n            path.push_back({r, c});\n        }\n        \n        // Then horizontally\n        while (c < end_c) {\n            c++;\n            path.push_back({r, c});\n        }\n        while (c > end_c) {\n            c--;\n            path.push_back({r, c});\n        }\n        return path;\n    }\n    \n    // Priority queue: {f_score, g_score, row, col}\n    priority_queue<tuple<double, double, int, int>, vector<tuple<double, double, int, int>>, greater<>> pq;\n    \n    // Distance and parent tracking\n    vector<vector<double>> dist(GRID_SIZE, vector<double>(GRID_SIZE, 1e18));\n    vector<vector<pair<int,int>>> parent(GRID_SIZE, vector<pair<int,int>>(GRID_SIZE, {-1, -1}));\n    \n    auto heuristic = [&](int r, int c) {\n        return abs(r - end_r) + abs(c - end_c); // Manhattan distance\n    };\n    \n    dist[start_r][start_c] = 0;\n    pq.push({heuristic(start_r, start_c), 0.0, start_r, start_c});\n    \n    vector<pair<int,int>> directions = {{-1,0}, {1,0}, {0,-1}, {0,1}}; // U, D, L, R\n    \n    while (!pq.empty()) {\n        auto [f_score, g_score, r, c] = pq.top();\n        pq.pop();\n        \n        if (g_score > dist[r][c]) continue;\n        \n        if (r == end_r && c == end_c) break;\n        \n        // Explore neighbors\n        for (int dir = 0; dir < 4; dir++) {\n            int dr = directions[dir].first;\n            int dc = directions[dir].second;\n            int nr = r + dr;\n            int nc = c + dc;\n            \n            // Check bounds\n            if (nr < 0 || nr >= GRID_SIZE || nc < 0 || nc >= GRID_SIZE) continue;\n            \n            double edge_cost = 0;\n            if (dr == 0 && dc == 1) { // Right\n                edge_cost = h_edges[r][c];\n            } else if (dr == 0 && dc == -1) { // Left\n                edge_cost = h_edges[r][nc];\n            } else if (dr == 1 && dc == 0) { // Down\n                edge_cost = v_edges[r][c];\n            } else if (dr == -1 && dc == 0) { // Up\n                edge_cost = v_edges[nr][c];\n            }\n            \n            // Add exploration bonus for less confident edges (early queries)\n            if (query_num < 200) {\n                double exploration_bonus = 0;\n                if (dr == 0 && dc == 1) { // Right\n                    exploration_bonus = (1.0 / (h_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 0 && dc == -1) { // Left\n                    exploration_bonus = (1.0 / (h_confidence[r][nc] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == 1 && dc == 0) { // Down\n                    exploration_bonus = (1.0 / (v_confidence[r][c] + 1e-6)) * (200 - query_num) * 0.1;\n                } else if (dr == -1 && dc == 0) { // Up\n                    exploration_bonus = (1.0 / (v_confidence[nr][c] + 1e-6)) * (200 - query_num) * 0.1;\n                }\n                edge_cost += exploration_bonus;\n            }\n            \n            double new_g_score = g_score + edge_cost;\n            if (new_g_score < dist[nr][nc]) {\n                dist[nr][nc] = new_g_score;\n                parent[nr][nc] = {r, c};\n                double f_score = new_g_score + heuristic(nr, nc);\n                pq.push({f_score, new_g_score, nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int r = end_r, c = end_c;\n    while (r != -1 && c != -1) {\n        path.push_back({r, c});\n        auto p = parent[r][c];\n        r = p.first;\n        c = p.second;\n    }\n    reverse(path.begin(), path.end());\n    \n    return path;\n}\n\n// Convert path to direction string\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r2 == r1 - 1) result += 'U';\n        else if (r2 == r1 + 1) result += 'D';\n        else if (c2 == c1 - 1) result += 'L';\n        else if (c2 == c1 + 1) result += 'R';\n    }\n    return result;\n}\n\n// Update edge weights based on actual path performance with confidence tracking\nvoid update_weights(const vector<pair<int,int>>& path, int actual_length, int query_num) {\n    if (path.size() < 2) return;\n    \n    double estimated_length = calculate_estimated_length(path);\n    double error = actual_length - estimated_length;\n    \n    // Adaptive learning rate based on query number and path length\n    double base_learning_rate = 0.3;\n    double learning_rate = base_learning_rate * exp(-0.001 * query_num);\n    \n    // Update each edge in the path\n    for (size_t i = 0; i < path.size() - 1; i++) {\n        int r1 = path[i].first, c1 = path[i].second;\n        int r2 = path[i+1].first, c2 = path[i+1].second;\n        \n        if (r1 == r2 && c2 == c1 + 1) { // Right\n            h_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c1] += learning_rate * edge_error;\n            h_edges[r1][c1] = max(100.0, min(10000.0, h_edges[r1][c1]));\n            // Update confidence - more usage means higher confidence\n            h_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (r1 == r2 && c2 == c1 - 1) { // Left\n            h_usage_count[r1][c2]++;\n            double edge_error = error / (path.size() - 1);\n            h_edges[r1][c2] += learning_rate * edge_error;\n            h_edges[r1][c2] = max(100.0, min(10000.0, h_edges[r1][c2]));\n            h_confidence[r1][c2] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 + 1) { // Down\n            v_usage_count[r1][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r1][c1] += learning_rate * edge_error;\n            v_edges[r1][c1] = max(100.0, min(10000.0, v_edges[r1][c1]));\n            v_confidence[r1][c1] += learning_rate * 10.0;\n        } else if (c1 == c2 && r2 == r1 - 1) { // Up\n            v_usage_count[r2][c1]++;\n            double edge_error = error / (path.size() - 1);\n            v_edges[r2][c1] += learning_rate * edge_error;\n            v_edges[r2][c1] = max(100.0, min(10000.0, v_edges[r2][c1]));\n            v_confidence[r2][c1] += learning_rate * 10.0;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initialize_weights();\n    \n    for (int query = 0; query < QUERY_COUNT; query++) {\n        int start_r, start_c, end_r, end_c;\n        cin >> start_r >> start_c >> end_r >> end_c;\n        \n        vector<pair<int,int>> path = find_shortest_path(start_r, start_c, end_r, end_c, query);\n        \n        string path_str = path_to_string(path);\n        cout << path_str << endl;\n        cout.flush();\n        \n        // Get actual length and update weights\n        int actual_length = get_actual_length();\n        update_weights(path, actual_length, query);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst string ALPHABET = \"ABCDEFGH\";\n\nvector<string> matrix(N, string(N, '.'));\nvector<string> strings;\nint M;\n\n// Check if string can be placed at position (r,c) in given direction\nbool canPlace(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        \n        if (matrix[nr][nc] != '.' && matrix[nr][nc] != s[i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Place string at position (r,c) in given direction\nvoid placeString(const string& s, int r, int c, bool horizontal) {\n    for (int i = 0; i < (int)s.length(); i++) {\n        int nr = r, nc = c;\n        if (horizontal) {\n            nc = (c + i) % N;\n        } else {\n            nr = (r + i) % N;\n        }\n        matrix[nr][nc] = s[i];\n    }\n}\n\n// Count how many strings are currently matched\nint countMatches() {\n    int count = 0;\n    for (const string& s : strings) {\n        bool found = false;\n        \n        // Check horizontal placements\n        for (int r = 0; r < N && !found; r++) {\n            for (int c = 0; c < N && !found; c++) {\n                bool match = true;\n                for (int i = 0; i < (int)s.length(); i++) {\n                    int nc = (c + i) % N;\n                    if (matrix[r][nc] != s[i]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) {\n                    found = true;\n                }\n            }\n        }\n        \n        // Check vertical placements\n        if (!found) {\n            for (int c = 0; c < N && !found; c++) {\n                for (int r = 0; r < N && !found; r++) {\n                    bool match = true;\n                    for (int i = 0; i < (int)s.length(); i++) {\n                        int nr = (r + i) % N;\n                        if (matrix[nr][c] != s[i]) {\n                            match = false;\n                            break;\n                        }\n                    }\n                    if (match) {\n                        found = true;\n                    }\n                }\n            }\n        }\n        \n        if (found) count++;\n    }\n    return count;\n}\n\n// Try to place as many strings as possible\nvoid greedyPlacement() {\n    // Sort strings by length (longer first)\n    vector<pair<int, int>> str_lengths;\n    for (int i = 0; i < M; i++) {\n        str_lengths.push_back({(int)strings[i].length(), i});\n    }\n    sort(str_lengths.rbegin(), str_lengths.rend());\n    \n    for (const auto& p : str_lengths) {\n        int idx = p.second;\n        const string& s = strings[idx];\n        \n        // Try to place this string\n        bool placed = false;\n        \n        // Try horizontal placements first\n        for (int r = 0; r < N && !placed; r++) {\n            for (int c = 0; c < N && !placed; c++) {\n                if (canPlace(s, r, c, true)) {\n                    placeString(s, r, c, true);\n                    placed = true;\n                }\n            }\n        }\n        \n        // Try vertical placements if horizontal didn't work\n        if (!placed) {\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    if (canPlace(s, r, c, false)) {\n                        placeString(s, r, c, false);\n                        placed = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Fill empty spots with random valid characters\nvoid fillEmptySpots() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matrix[r][c] == '.') {\n                matrix[r][c] = ALPHABET[gen() % ALPHABET.length()];\n            }\n        }\n    }\n}\n\n// Conservative random improvement - only accept strict improvements\nvoid conservativeImprovement() {\n    random_device rd;\n    mt19937 gen(rd());\n    \n    int current_matches = countMatches();\n    \n    // Try random changes - reduced iterations for efficiency\n    for (int iter = 0; iter < 400; iter++) {\n        // Pick a random cell\n        int r = gen() % N;\n        int c = gen() % N;\n        char original = matrix[r][c];\n        \n        // Try a random character\n        char new_char = ALPHABET[gen() % ALPHABET.length()];\n        matrix[r][c] = new_char;\n        \n        int new_matches = countMatches();\n        // Only accept strict improvements\n        if (new_matches <= current_matches) {\n            matrix[r][c] = original; // Revert\n        } else {\n            current_matches = new_matches;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> M;\n    strings.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    // Initialize matrix\n    for (int i = 0; i < N; i++) {\n        matrix[i] = string(N, '.');\n    }\n    \n    // Greedy placement\n    greedyPlacement();\n    \n    // Fill empty spots\n    fillEmptySpots();\n    \n    // Conservative improvement\n    conservativeImprovement();\n    \n    // Ensure all characters are valid\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (matrix[i][j] == '.' || ALPHABET.find(matrix[i][j]) == string::npos) {\n                matrix[i][j] = 'A';\n            }\n        }\n    }\n    \n    // Output result\n    for (const string& row : matrix) {\n        cout << row << \"\\n\";\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 70;\nint N, si, sj;\nchar grid[MAX_N][MAX_N];\nbool is_road[MAX_N][MAX_N];\nint cost[MAX_N][MAX_N];\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\n// Calculate visible squares from a given position\nset<pair<int,int>> get_visible_squares(int x, int y) {\n    set<pair<int,int>> visible;\n    \n    // Horizontal visibility (same row)\n    // Left direction\n    for (int j = y; j >= 0; j--) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    // Right direction\n    for (int j = y; j < N; j++) {\n        if (!is_road[x][j]) break;\n        visible.insert({x, j});\n    }\n    \n    // Vertical visibility (same column)\n    // Up direction\n    for (int i = x; i >= 0; i--) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    // Down direction\n    for (int i = x; i < N; i++) {\n        if (!is_road[i][y]) break;\n        visible.insert({i, y});\n    }\n    \n    return visible;\n}\n\n// Check if position is valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N && is_road[x][y];\n}\n\n// BFS to find shortest path between two points\nvector<char> bfs_path(int start_x, int start_y, int end_x, int end_y) {\n    if (start_x == end_x && start_y == end_y) return {};\n    \n    queue<pair<int,int>> q;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    \n    q.push({start_x, start_y});\n    visited[start_x][start_y] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = x + dx[dir];\n            int ny = y + dy[dir];\n            \n            if (is_valid(nx, ny) && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                parent[nx][ny] = {x, y};\n                q.push({nx, ny});\n                \n                if (nx == end_x && ny == end_y) {\n                    // Reconstruct path\n                    vector<char> path;\n                    int cx = end_x, cy = end_y;\n                    \n                    while (parent[cx][cy].first != -1) {\n                        auto [px, py] = parent[cx][cy];\n                        // Determine direction from parent to current\n                        if (cx == px - 1 && cy == py) path.push_back('U');\n                        else if (cx == px + 1 && cy == py) path.push_back('D');\n                        else if (cx == px && cy == py - 1) path.push_back('L');\n                        else if (cx == px && cy == py + 1) path.push_back('R');\n                        \n                        cx = px;\n                        cy = py;\n                    }\n                    \n                    reverse(path.begin(), path.end());\n                    return path;\n                }\n            }\n        }\n    }\n    \n    return {}; // No path found\n}\n\n// Get all road positions\nvector<pair<int,int>> get_all_roads() {\n    vector<pair<int,int>> roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road[i][j]) {\n                roads.push_back({i, j});\n            }\n        }\n    }\n    return roads;\n}\n\n// Generate path using safe, proven approach\nvector<char> generate_safe_path() {\n    vector<char> path;\n    int current_x = si, current_y = sj;\n    \n    // Get all roads\n    auto all_roads = get_all_roads();\n    if (all_roads.empty()) return path;\n    \n    // Track covered roads\n    set<pair<int,int>> covered;\n    auto initial_visible = get_visible_squares(current_x, current_y);\n    covered.insert(initial_visible.begin(), initial_visible.end());\n    \n    // Conservative approach that worked well\n    int max_iterations = min(600, N * N);\n    \n    for (int iter = 0; iter < max_iterations && path.size() < 2800; iter++) {\n        // Find the position that maximizes new coverage\n        pair<int,int> best_pos = {-1, -1};\n        int best_new_coverage = -1;\n        vector<char> best_segment;\n        \n        // Generate candidate set\n        vector<pair<int,int>> candidates;\n        \n        // Include strategic sampling\n        int sample_size = min(120, (int)all_roads.size());\n        for (int k = 0; k < sample_size && k < (int)all_roads.size(); k++) {\n            int idx = (iter * 29 + k * 23) % all_roads.size();\n            candidates.push_back(all_roads[idx]);\n        }\n        \n        // Add systematic grid positions\n        for (int i = 0; i < N && (int)candidates.size() < sample_size + 30; i += max(1, N/6)) {\n            for (int j = 0; j < N && (int)candidates.size() < sample_size + 30; j += max(1, N/6)) {\n                if (is_road[i][j]) {\n                    candidates.push_back({i, j});\n                }\n            }\n        }\n        \n        // Evaluate candidates\n        for (const auto& pos : candidates) {\n            int target_x = pos.first;\n            int target_y = pos.second;\n            \n            // Skip if already at this position\n            if (target_x == current_x && target_y == current_y) continue;\n            \n            // Get path to this position\n            auto segment = bfs_path(current_x, current_y, target_x, target_y);\n            if (segment.empty() || segment.size() > 120) continue;\n            \n            // Calculate new coverage from this position\n            auto visible = get_visible_squares(target_x, target_y);\n            int new_coverage = 0;\n            for (const auto& p : visible) {\n                if (covered.find(p) == covered.end()) {\n                    new_coverage++;\n                }\n            }\n            \n            // Prefer positions with better coverage efficiency\n            double efficiency = (double)new_coverage / (segment.size() + 1);\n            if (new_coverage > best_new_coverage || \n                (new_coverage == best_new_coverage && efficiency > (double)best_new_coverage / (best_segment.size() + 1))) {\n                best_new_coverage = new_coverage;\n                best_pos = {target_x, target_y};\n                best_segment = segment;\n            }\n        }\n        \n        // Simple fallback\n        if (best_pos.first == -1) {\n            // If we have excellent coverage, prepare to finish\n            if (covered.size() >= 0.97 * all_roads.size()) {\n                break;\n            }\n            \n            // Try simple adjacent moves\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = current_x + dx[dir];\n                int ny = current_y + dy[dir];\n                if (is_valid(nx, ny)) {\n                    best_segment = {dir_char[dir]};\n                    best_pos = {nx, ny};\n                    break;\n                }\n            }\n            \n            if (best_pos.first == -1) break;\n        }\n        \n        // Add segment safely\n        if (path.size() + best_segment.size() <= 2800) {\n            path.insert(path.end(), best_segment.begin(), best_segment.end());\n            current_x = best_pos.first;\n            current_y = best_pos.second;\n            \n            // Update coverage\n            auto new_visible = get_visible_squares(current_x, current_y);\n            covered.insert(new_visible.begin(), new_visible.end());\n        } else {\n            break;\n        }\n        \n        // Smart early termination\n        if (covered.size() >= 0.99 * all_roads.size() && path.size() > 1500) {\n            break;\n        }\n    }\n    \n    // Final coverage attempt - simple and safe\n    vector<pair<int,int>> uncovered_roads;\n    for (const auto& road : all_roads) {\n        if (covered.find(road) == covered.end()) {\n            uncovered_roads.push_back(road);\n        }\n    }\n    \n    // Visit some uncovered roads if possible\n    if (!uncovered_roads.empty() && path.size() < 2700) {\n        // Sort by distance\n        sort(uncovered_roads.begin(), uncovered_roads.end(), \n             [&](const pair<int,int>& a, const pair<int,int>& b) {\n                 int dist_a = abs(a.first - current_x) + abs(a.second - current_y);\n                 int dist_b = abs(b.first - current_x) + abs(b.second - current_y);\n                 return dist_a < dist_b;\n             });\n        \n        // Visit up to 30 nearest uncovered roads\n        int visit_limit = min(30, (int)uncovered_roads.size());\n        for (int i = 0; i < visit_limit && path.size() < 2700; i++) {\n            auto target = uncovered_roads[i];\n            auto segment = bfs_path(current_x, current_y, target.first, target.second);\n            if (!segment.empty() && path.size() + segment.size() <= 2700) {\n                path.insert(path.end(), segment.begin(), segment.end());\n                current_x = target.first;\n                current_y = target.second;\n                auto vis = get_visible_squares(current_x, current_y);\n                covered.insert(vis.begin(), vis.end());\n            }\n        }\n    }\n    \n    // Final return to start - simple and reliable\n    if (current_x != si || current_y != sj) {\n        auto return_segment = bfs_path(current_x, current_y, si, sj);\n        if (path.size() + return_segment.size() <= 2999) {\n            path.insert(path.end(), return_segment.begin(), return_segment.end());\n        }\n    }\n    \n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j];\n            if (line[j] == '#') {\n                is_road[i][j] = false;\n            } else {\n                is_road[i][j] = true;\n                cost[i][j] = line[j] - '0';\n            }\n        }\n    }\n    \n    // Generate path using safe approach\n    vector<char> path = generate_safe_path();\n    \n    // Final safety check\n    if (path.size() > 2999) {\n        path.resize(2999);\n    }\n    \n    // Output result\n    for (char c : path) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nconst int MAX_N = 1000;\nconst int MAX_M = 20;\nconst int MAX_K = 20;\nconst int MAX_DAYS = 2000;\n\n// Global variables\nint N, M, K, R;\nvector<vector<int>> task_skills;  // [task][skill] = required level\nvector<vector<int>> member_skills; // [member][skill] = estimated level\nvector<vector<int>> task_times;    // [task][member] = observed time\nvector<vector<int>> dependencies;  // [task] = list of prerequisite tasks\nvector<vector<int>> reverse_dependencies; // [task] = list of dependent tasks\nvector<int> task_status;           // -1:not started, 0:in progress, 1:completed\nvector<int> member_status;         // -1:free, task_id:working on task\nvector<int> task_completion_day;   // when each task was completed\nvector<set<int>> completed_tasks_by_member; // track what each member completed\n\n// For skill estimation\nvector<int> task_start_day;\nvector<vector<pair<int,int>>> member_task_history; // {task_id, completion_time}\n\n// Topological sorting helper\nvector<int> in_degree;\nqueue<int> ready_tasks;\n\nvoid read_input() {\n    cin >> N >> M >> K >> R;\n    \n    task_skills.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_skills[i][j];\n        }\n    }\n    \n    dependencies.resize(N);\n    reverse_dependencies.resize(N);\n    in_degree.assign(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--; // Convert to 0-indexed\n        dependencies[v].push_back(u);\n        reverse_dependencies[u].push_back(v);\n        in_degree[v]++;\n    }\n}\n\n// Initialize data structures\nvoid initialize() {\n    task_status.assign(N, -1);\n    member_status.assign(M, -1);\n    task_completion_day.assign(N, -1);\n    task_start_day.assign(N, -1);\n    completed_tasks_by_member.resize(M);\n    member_task_history.resize(M);\n    \n    // Initialize skill estimates with reasonable defaults\n    member_skills.resize(M, vector<int>(K, 10)); // Start with moderate skills\n    task_times.resize(N, vector<int>(M, 1));     // Default time estimate\n    \n    // Find initially ready tasks (no dependencies)\n    for (int i = 0; i < N; i++) {\n        if (in_degree[i] == 0) {\n            ready_tasks.push(i);\n        }\n    }\n}\n\n// Estimate member skills based on history\nvoid update_skill_estimates() {\n    // Simple approach: for each member, look at tasks they completed quickly\n    for (int member = 0; member < M; member++) {\n        if (member_task_history[member].size() == 0) continue;\n        \n        // Look at recent successful completions (time = 1 day usually means skill >= difficulty)\n        map<int, vector<int>> skill_samples; // skill_index -> list of observed levels\n        \n        for (auto& [task_id, completion_time] : member_task_history[member]) {\n            if (completion_time <= 2) { // Completed quickly\n                for (int k = 0; k < K; k++) {\n                    // If completed quickly, member's skill is likely >= task requirement\n                    skill_samples[k].push_back(task_skills[task_id][k]);\n                }\n            }\n        }\n        \n        // Update skill estimates\n        for (int k = 0; k < K; k++) {\n            if (!skill_samples[k].empty()) {\n                // Take maximum observed requirement they handled well\n                sort(skill_samples[k].begin(), skill_samples[k].end());\n                member_skills[member][k] = max(member_skills[member][k], \n                                             skill_samples[k].back());\n            }\n        }\n    }\n}\n\n// Calculate estimated time for a member to complete a task\nint estimate_time(int task_id, int member_id) {\n    int w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0, task_skills[task_id][k] - member_skills[member_id][k]);\n    }\n    \n    if (w == 0) return 1;\n    else return max(1, w); // Simplified - ignoring randomness for planning\n}\n\n// Get best available member for a task\nint get_best_member(int task_id) {\n    int best_member = 0;\n    int min_time = estimate_time(task_id, 0);\n    \n    for (int member = 1; member < M; member++) {\n        int time = estimate_time(task_id, member);\n        if (time < min_time) {\n            min_time = time;\n            best_member = member;\n        }\n    }\n    \n    return best_member;\n}\n\n// Update ready tasks based on completed tasks\nvoid update_ready_tasks(int completed_task) {\n    for (int dependent : reverse_dependencies[completed_task]) {\n        in_degree[dependent]--;\n        if (in_degree[dependent] == 0) {\n            ready_tasks.push(dependent);\n        }\n    }\n}\n\n// Main assignment logic\nvector<pair<int, int>> assign_tasks(int current_day) {\n    vector<pair<int, int>> assignments;\n    \n    // Find free members\n    vector<int> free_members;\n    for (int member = 0; member < M; member++) {\n        if (member_status[member] == -1) {\n            free_members.push_back(member);\n        }\n    }\n    \n    if (free_members.empty() || ready_tasks.empty()) {\n        return assignments;\n    }\n    \n    // Create list of ready tasks with priorities\n    vector<pair<int, int>> task_priority; // {priority, task_id}\n    queue<int> temp_queue = ready_tasks; // Copy to avoid modifying original\n    \n    while (!temp_queue.empty()) {\n        int task_id = temp_queue.front();\n        temp_queue.pop();\n        \n        // Priority: tasks with more dependents first, then lower ID\n        int priority = -reverse_dependencies[task_id].size() * 1000 - task_id;\n        task_priority.push_back({priority, task_id});\n    }\n    \n    sort(task_priority.begin(), task_priority.end());\n    \n    // Assign tasks to free members\n    int task_count = min((int)free_members.size(), (int)task_priority.size());\n    \n    for (int i = 0; i < task_count; i++) {\n        int member_id = free_members[i];\n        int task_id = task_priority[i].second;\n        \n        // Remove this task from ready queue (we'll re-add if not assigned)\n        // Actually, let's handle this more carefully in the main loop\n        \n        assignments.push_back({member_id, task_id});\n        task_status[task_id] = 0; // Mark as in progress\n        member_status[member_id] = task_id;\n        task_start_day[task_id] = current_day;\n    }\n    \n    return assignments;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    read_input();\n    initialize();\n    \n    int day = 0;\n    \n    while (day < MAX_DAYS) {\n        day++;\n        \n        // Process completed tasks from previous day\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) {\n            break; // Done\n        }\n        \n        vector<int> completed_members(n_completed);\n        for (int i = 0; i < n_completed; i++) {\n            cin >> completed_members[i];\n            completed_members[i]--; // Convert to 0-indexed\n        }\n        \n        // Update based on completed tasks\n        for (int member_idx : completed_members) {\n            int task_id = member_status[member_idx];\n            if (task_id != -1) {\n                task_status[task_id] = 1;\n                task_completion_day[task_id] = day;\n                member_status[member_idx] = -1;\n                completed_tasks_by_member[member_idx].insert(task_id);\n                \n                // Record completion for skill estimation\n                int duration = day - task_start_day[task_id];\n                member_task_history[member_idx].push_back({task_id, duration});\n                \n                // Update ready tasks\n                update_ready_tasks(task_id);\n            }\n        }\n        \n        // Update skill estimates periodically\n        if (day % 10 == 0) {\n            update_skill_estimates();\n        }\n        \n        // Make new assignments\n        vector<pair<int, int>> assignments = assign_tasks(day);\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto& [member, task] : assignments) {\n            cout << \" \" << (member + 1) << \" \" << (task + 1);\n        }\n        cout << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int DEPOT_X = 400;\nconst int DEPOT_Y = 400;\nconst int NUM_ORDERS = 1000;\nconst int SELECT_COUNT = 50;\n\nstruct Order {\n    int id, a, b, c, d;\n};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n};\n\nint manhattan_distance(const Point& p1, const Point& p2) {\n    return abs(p1.x - p2.x) + abs(p1.y - p2.y);\n}\n\nint manhattan_distance(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Simple greedy route construction\nvector<Point> build_route(const vector<Order>& selected_orders) {\n    vector<Point> route;\n    route.emplace_back(DEPOT_X, DEPOT_Y);\n    \n    // Create list of all points with their type and order id\n    vector<pair<Point, pair<int, bool>>> all_points; // point, {order_id, is_pickup}\n    \n    for (const auto& order : selected_orders) {\n        all_points.emplace_back(Point(order.a, order.b), make_pair(order.id, true));   // pickup\n        all_points.emplace_back(Point(order.c, order.d), make_pair(order.id, false));  // delivery\n    }\n    \n    vector<bool> picked_up(NUM_ORDERS + 1, false);\n    \n    // Greedy construction: at each step, pick the nearest valid point\n    while (!all_points.empty()) {\n        Point current = route.back();\n        int best_idx = -1;\n        int best_dist = 1e9;\n        \n        // Find the best next point to visit\n        for (size_t i = 0; i < all_points.size(); i++) {\n            const Point& point = all_points[i].first;\n            int order_id = all_points[i].second.first;\n            bool is_pickup = all_points[i].second.second;\n            \n            if (is_pickup) {\n                // Always valid to pick up\n                int dist = manhattan_distance(current, point);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_idx = i;\n                }\n            } else {\n                // Can only deliver if picked up\n                if (picked_up[order_id]) {\n                    int dist = manhattan_distance(current, point);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        // If no valid delivery found, pick the closest pickup\n        if (best_idx == -1) {\n            for (size_t i = 0; i < all_points.size(); i++) {\n                const Point& point = all_points[i].first;\n                bool is_pickup = all_points[i].second.second;\n                if (is_pickup) {\n                    int dist = manhattan_distance(current, point);\n                    if (dist < best_dist) {\n                        best_dist = dist;\n                        best_idx = i;\n                    }\n                }\n            }\n        }\n        \n        // If still no point found, take the first one\n        if (best_idx == -1) {\n            best_idx = 0;\n        }\n        \n        // Add the selected point to route\n        const Point& selected_point = all_points[best_idx].first;\n        int order_id = all_points[best_idx].second.first;\n        bool is_pickup = all_points[best_idx].second.second;\n        \n        route.push_back(selected_point);\n        \n        if (is_pickup) {\n            picked_up[order_id] = true;\n        }\n        \n        // Remove the selected point\n        all_points.erase(all_points.begin() + best_idx);\n    }\n    \n    // Return to depot\n    route.emplace_back(DEPOT_X, DEPOT_Y);\n    \n    return route;\n}\n\n// Select orders based on efficiency\nvector<Order> select_orders(vector<Order>& orders) {\n    // Calculate efficiency score: direct distance + average distance to depot\n    vector<pair<int, int>> scores; // {score, order_id}\n    \n    for (int i = 0; i < NUM_ORDERS; i++) {\n        int direct_dist = manhattan_distance(orders[i].a, orders[i].b, orders[i].c, orders[i].d);\n        int pickup_dist = manhattan_distance(DEPOT_X, DEPOT_Y, orders[i].a, orders[i].b);\n        int delivery_dist = manhattan_distance(DEPOT_X, DEPOT_Y, orders[i].c, orders[i].d);\n        int score = direct_dist + (pickup_dist + delivery_dist) / 2;\n        scores.emplace_back(score, i);\n    }\n    \n    // Sort by score (lower is better)\n    sort(scores.begin(), scores.end());\n    \n    // Select best orders\n    vector<Order> selected_orders;\n    for (int i = 0; i < SELECT_COUNT; i++) {\n        selected_orders.push_back(orders[scores[i].second]);\n    }\n    \n    return selected_orders;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<Order> orders(NUM_ORDERS);\n    \n    // Read input\n    for (int i = 0; i < NUM_ORDERS; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i + 1;\n    }\n    \n    // Select orders\n    vector<Order> selected_orders = select_orders(orders);\n    \n    // Build route\n    vector<Point> route = build_route(selected_orders);\n    \n    // Output selected orders\n    cout << SELECT_COUNT;\n    for (const auto& order : selected_orders) {\n        cout << \" \" << order.id;\n    }\n    cout << \"\\n\";\n    \n    // Output route\n    cout << route.size();\n    for (const auto& point : route) {\n        cout << \" \" << point.x << \" \" << point.y;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 400;\n\nvector<int> parent(N);\nint edges_taken = 0;\n\nvoid init_uf() {\n    for (int i = 0; i < N; i++) {\n        parent[i] = i;\n    }\n}\n\nint find_root(int x) {\n    if (parent[x] != x) {\n        parent[x] = find_root(parent[x]);\n    }\n    return parent[x];\n}\n\nbool join(int x, int y) {\n    x = find_root(x);\n    y = find_root(y);\n    if (x == y) return false;\n    parent[x] = y;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Read coordinates\n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Read all edges first\n    vector<tuple<int, int, int>> all_edges(1995);\n    for (int i = 0; i < 1995; i++) {\n        int u, v;\n        cin >> u >> v;\n        \n        long long dx = (long long)(points[u].first - points[v].first);\n        long long dy = (long long)(points[u].second - points[v].second);\n        int dist = (int)round(sqrt(dx * dx + dy * dy));\n        \n        all_edges[i] = {u, v, dist};\n    }\n    \n    init_uf();\n    \n    // Process edges online\n    for (int i = 0; i < 1995; i++) {\n        int length;\n        cin >> length;\n        \n        auto [u, v, d] = all_edges[i];\n        double ratio = (double)length / d;\n        \n        bool connects = (find_root(u) != find_root(v));\n        \n        bool take = false;\n        \n        // Take connecting edges while building spanning tree\n        if (connects && edges_taken < N - 1) {\n            take = true;\n            edges_taken++;\n        }\n        // Take very cheap edges for improvement\n        else if (ratio <= 1.1) {\n            take = true;\n        }\n        // Take reasonably priced connecting edges even after basic connectivity\n        else if (connects && ratio <= 1.4) {\n            take = true;\n            edges_taken++;\n        }\n        \n        if (take) {\n            join(u, v);\n            cout << \"1\" << endl;\n        } else {\n            cout << \"0\" << endl;\n        }\n        \n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int H = 30, W = 30;\nconst int INF = 100000000;\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int x, int y) : x(x), y(y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct Pet {\n    Point pos;\n    int type;\n    Pet() : pos(Point(0, 0)), type(0) {}\n    Pet(Point p, int t) : pos(p), type(t) {}\n};\n\nstruct Human {\n    Point pos;\n    Human() : pos(Point(0, 0)) {}\n    Human(Point p) : pos(p) {}\n};\n\n// Directions: up, down, left, right\nconst vector<Point> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"UDLR\";\nconst string BLOCK_CHARS = \"udlr\";\n\nint N, M;\nvector<Pet> pets;\nvector<Human> humans;\nvector<vector<int>> grid; // 0 = passable, 1 = blocked\n\n// Check if position is valid\nbool valid(int x, int y) {\n    return x >= 1 && x <= H && y >= 1 && y <= W;\n}\n\nbool valid_point(Point p) {\n    return valid(p.x, p.y);\n}\n\n// Check if a square is adjacent to any pet\nbool is_adjacent_to_pet(Point p) {\n    for (auto& pet : pets) {\n        if (abs(pet.pos.x - p.x) + abs(pet.pos.y - p.y) <= 1) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a square contains any pet\nbool contains_pet(Point p) {\n    for (auto& pet : pets) {\n        if (pet.pos == p) {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Check if a square will contain any human after moves\nbool will_contain_human(Point p, const vector<Point>& intended_moves, int exclude_index) {\n    for (int i = 0; i < M; i++) {\n        if (i != exclude_index && intended_moves[i] == p) {\n            return true;\n        }\n    }\n    return false;\n}\n\nstring decide_actions(int turn) {\n    string actions(M, '.');\n    \n    // Determine intended moves first\n    vector<Point> intended_moves(M);\n    for (int i = 0; i < M; i++) {\n        intended_moves[i] = humans[i].pos; // default to staying\n    }\n    \n    // Simple strategy: early game move away from pets, later game block strategically\n    for (int i = 0; i < M; i++) {\n        Point cur = humans[i].pos;\n        \n        if (turn < 100) {\n            // Early game: move away from nearby pets\n            int best_dist = -1;\n            int best_dir = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                Point next = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(next) && grid[next.x][next.y] == 0) {\n                    // Calculate minimum distance to any pet\n                    int min_dist = INF;\n                    for (auto& pet : pets) {\n                        int dist = abs(pet.pos.x - next.x) + abs(pet.pos.y - next.y);\n                        min_dist = min(min_dist, dist);\n                    }\n                    int cur_dist = INF;\n                    for (auto& pet : pets) {\n                        int dist = abs(pet.pos.x - cur.x) + abs(pet.pos.y - cur.y);\n                        cur_dist = min(cur_dist, dist);\n                    }\n                    \n                    if (min_dist > cur_dist && min_dist > best_dist) {\n                        best_dist = min_dist;\n                        best_dir = d;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                actions[i] = DIR_CHARS[best_dir];\n                intended_moves[i] = {cur.x + DIRS[best_dir].x, cur.y + DIRS[best_dir].y};\n            }\n        } else {\n            // Later game: try to block strategically\n            int best_score = -1;\n            int best_dir = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                Point block_pos = {cur.x + DIRS[d].x, cur.y + DIRS[d].y};\n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                    !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos)) {\n                    \n                    // Simple scoring\n                    int score = 0;\n                    // Prefer edge positions\n                    if (block_pos.x == 1 || block_pos.x == H || block_pos.y == 1 || block_pos.y == W) {\n                        score += 10;\n                    }\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = d;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                actions[i] = BLOCK_CHARS[best_dir];\n            }\n        }\n    }\n    \n    // Second pass: validate all actions to avoid conflicts\n    vector<vector<int>> will_be_blocked(H + 1, vector<int>(W + 1, 0));\n    \n    // Mark all blocking actions first\n    for (int i = 0; i < M; i++) {\n        char action = actions[i];\n        if (action >= 'a' && action <= 'z') { // Blocking action\n            size_t dir_idx = BLOCK_CHARS.find(action);\n            if (dir_idx != string::npos) {\n                Point cur = humans[i].pos;\n                Point block_pos = {cur.x + DIRS[dir_idx].x, cur.y + DIRS[dir_idx].y};\n                \n                // Validate block - check if any human will be in this square\n                bool conflict = false;\n                for (int j = 0; j < M; j++) {\n                    if (i != j && intended_moves[j] == block_pos) {\n                        conflict = true;\n                        break;\n                    }\n                }\n                \n                if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                    !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos) && !conflict) {\n                    will_be_blocked[block_pos.x][block_pos.y] = 1;\n                } else {\n                    actions[i] = '.'; // Invalid block, cancel it\n                }\n            }\n        }\n    }\n    \n    // Validate all movement actions\n    for (int i = 0; i < M; i++) {\n        char action = actions[i];\n        if (action >= 'A' && action <= 'Z') { // Movement action\n            size_t dir_idx = DIR_CHARS.find(action);\n            if (dir_idx != string::npos) {\n                Point cur = humans[i].pos;\n                Point next = {cur.x + DIRS[dir_idx].x, cur.y + DIRS[dir_idx].y};\n                \n                if (!valid_point(next) || grid[next.x][next.y] == 1 || \n                    will_be_blocked[next.x][next.y]) {\n                    actions[i] = '.'; // Invalid move, cancel it\n                }\n            }\n        }\n    }\n    \n    return actions;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Initialize grid\n    grid.assign(H + 1, vector<int>(W + 1, 0));\n    \n    // Read initial positions\n    cin >> N;\n    pets.resize(N);\n    for (int i = 0; i < N; i++) {\n        int x, y, t;\n        cin >> x >> y >> t;\n        pets[i] = Pet(Point(x, y), t);\n    }\n    \n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        humans[i] = Human(Point(x, y));\n    }\n    \n    // Main game loop\n    for (int turn = 0; turn < 300; turn++) {\n        // Decide actions\n        string actions = decide_actions(turn);\n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pet movements\n        string pet_moves;\n        getline(cin, pet_moves);\n        if (pet_moves.empty()) {\n            getline(cin, pet_moves);\n        }\n        \n        stringstream ss(pet_moves);\n        string move;\n        for (int i = 0; i < N && ss >> move; i++) {\n            // Update pet position based on movement\n            for (char c : move) {\n                switch (c) {\n                    case 'U': pets[i].pos.x--; break;\n                    case 'D': pets[i].pos.x++; break;\n                    case 'L': pets[i].pos.y--; break;\n                    case 'R': pets[i].pos.y++; break;\n                }\n            }\n        }\n        \n        // Update human positions and grid based on actions\n        vector<vector<int>> will_be_blocked(H + 1, vector<int>(W + 1, 0));\n        vector<Point> new_positions = vector<Point>(M);\n        for (int i = 0; i < M; i++) {\n            new_positions[i] = humans[i].pos; // default to staying\n        }\n        \n        // First, mark all blocking actions\n        for (int i = 0; i < M; i++) {\n            char action = actions[i];\n            if (action >= 'a' && action <= 'z') { // Blocking\n                size_t dir_idx = BLOCK_CHARS.find(action);\n                if (dir_idx != string::npos) {\n                    Point block_pos = {humans[i].pos.x + DIRS[dir_idx].x, \n                                     humans[i].pos.y + DIRS[dir_idx].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                        !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos)) {\n                        will_be_blocked[block_pos.x][block_pos.y] = 1;\n                    }\n                }\n            }\n        }\n        \n        // Then, process movements\n        for (int i = 0; i < M; i++) {\n            char action = actions[i];\n            if (action >= 'A' && action <= 'Z') { // Movement\n                size_t dir_idx = DIR_CHARS.find(action);\n                if (dir_idx != string::npos) {\n                    Point next = {humans[i].pos.x + DIRS[dir_idx].x, \n                                humans[i].pos.y + DIRS[dir_idx].y};\n                    if (valid_point(next) && grid[next.x][next.y] == 0 && \n                        !will_be_blocked[next.x][next.y]) {\n                        new_positions[i] = next;\n                    }\n                }\n            }\n        }\n        \n        // Apply movements\n        for (int i = 0; i < M; i++) {\n            humans[i].pos = new_positions[i];\n        }\n        \n        // Apply blocking\n        for (int i = 0; i < M; i++) {\n            char action = actions[i];\n            if (action >= 'a' && action <= 'z') { // Blocking\n                size_t dir_idx = BLOCK_CHARS.find(action);\n                if (dir_idx != string::npos) {\n                    Point block_pos = {humans[i].pos.x + DIRS[dir_idx].x, \n                                     humans[i].pos.y + DIRS[dir_idx].y};\n                    if (valid_point(block_pos) && grid[block_pos.x][block_pos.y] == 0 &&\n                        !contains_pet(block_pos) && !is_adjacent_to_pet(block_pos)) {\n                        grid[block_pos.x][block_pos.y] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint si, sj, ti, tj;\ndouble p;\nbool h_wall[N][N-1]; // horizontal walls\nbool v_wall[N-1][N]; // vertical walls\n\n// Direction mappings\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_char[4] = {'U', 'D', 'L', 'R'};\n\nbool can_move(int x, int y, int dir) {\n    if (dir == 0) { // Up\n        if (x == 0) return false;\n        return !v_wall[x-1][y];\n    } else if (dir == 1) { // Down\n        if (x == N-1) return false;\n        return !v_wall[x][y];\n    } else if (dir == 2) { // Left\n        if (y == 0) return false;\n        return !h_wall[x][y-1];\n    } else { // Right\n        if (y == N-1) return false;\n        return !h_wall[x][y];\n    }\n}\n\nstring generate_path() {\n    string path;\n    int x = si, y = sj;\n    \n    // Generate path with some redundancy for robustness\n    while ((x != ti || y != tj) && path.length() < 200) {\n        // Calculate best direction to move\n        int best_dir = -1;\n        int min_dist = abs(x - ti) + abs(y - tj);\n        \n        // Try all directions\n        for (int dir = 0; dir < 4; dir++) {\n            if (can_move(x, y, dir)) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                int dist = abs(nx - ti) + abs(ny - tj);\n                \n                // Prefer moves that reduce distance, with slight bias for R/D\n                if (dir == 1 || dir == 3) dist -= 1; // Slight preference for Down/Right\n                \n                if (dist < min_dist) {\n                    min_dist = dist;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            path += dir_char[best_dir];\n            x += dx[best_dir];\n            y += dy[best_dir];\n            \n            // Add some redundancy - repeat last move occasionally for robustness\n            if (path.length() < 195 && path.length() > 0 && path.length() % 7 == 6) {\n                path += path.back();\n            }\n        } else {\n            // If we can't move optimally, try any valid move\n            bool moved = false;\n            for (int dir = 0; dir < 4; dir++) {\n                if (can_move(x, y, dir)) {\n                    path += dir_char[dir];\n                    x += dx[dir];\n                    y += dy[dir];\n                    moved = true;\n                    break;\n                }\n            }\n            if (!moved) break;\n        }\n    }\n    \n    return path;\n}\n\nint main() {\n    // Read input\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N-1; j++) {\n            h_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N-1; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            v_wall[i][j] = (line[j] == '1');\n        }\n    }\n    \n    // Generate path\n    string result = generate_path();\n    \n    // Ensure we don't exceed 200 characters\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    // Make sure we have at least some path\n    if (result.empty()) {\n        // Emergency fallback\n        for (int dir = 0; dir < 4 && result.length() < 50; dir++) {\n            if (can_move(si, sj, dir)) {\n                result += string(min(50, 200 - (int)result.length()), dir_char[dir]);\n                break;\n            }\n        }\n    }\n    \n    if (result.empty()) {\n        result = \"RDRDRDRDRDRDRDRDRDRD\";\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction: 0=left, 1=up, 2=right, 3=down\nconst int di[4] = {0, -1, 0, 1};\nconst int dj[4] = {-1, 0, 1, 0};\n\n// Transition table: to[tile_type][entry_direction] = exit_direction (-1 if invalid)\nconst int to[8][4] = {\n    {1, 0, -1, -1},  // tile 0\n    {3, -1, -1, 0},  // tile 1\n    {-1, -1, 3, 2},  // tile 2\n    {-1, 2, 1, -1},  // tile 3\n    {1, 0, 3, 2},    // tile 4\n    {3, 2, 1, 0},    // tile 5\n    {2, -1, 0, -1},  // tile 6\n    {-1, 3, -1, 1}   // tile 7\n};\n\nconst int N = 30;\nint grid[N][N];\nint rotation[N][N];\n\n// Get actual tile type after rotation\nint get_rotated_tile(int base_tile, int rot) {\n    static const int rotation_map[8][4] = {\n        {0, 1, 2, 3},  // tile 0\n        {1, 2, 3, 0},  // tile 1\n        {2, 3, 0, 1},  // tile 2\n        {3, 0, 1, 2},  // tile 3\n        {4, 5, 4, 5},  // tile 4\n        {5, 4, 5, 4},  // tile 5\n        {6, 7, 6, 7},  // tile 6\n        {7, 6, 7, 6}   // tile 7\n    };\n    return rotation_map[base_tile][rot % 4];\n}\n\n// Check if coordinates are valid\nbool valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\n// Find loop length with reasonable limits\nint find_loop_length(int si, int sj, int sd) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        int tile_type = get_rotated_tile(grid[i][j], rotation[i][j]);\n        int d2 = to[tile_type][d];\n        \n        if (d2 == -1) return 0;  // Broken line\n        \n        i += di[d2];\n        j += dj[d2];\n        \n        if (!valid(i, j)) return 0;  // Out of bounds\n        \n        d = (d2 + 2) % 4;  // Reverse direction\n        length++;\n        \n        // Reasonable limit to prevent timeout\n        if (length > 250) return 0;\n        \n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\n// Find top loops more efficiently\npair<int, int> find_top_two_loops() {\n    int max1 = 0, max2 = 0;\n    \n    // Efficient sampling strategy\n    for (int i = 0; i < N; i += 2) {\n        for (int j = 0; j < N; j += 2) {\n            for (int d = 0; d < 4; d++) {\n                int length = find_loop_length(i, j, d);\n                if (length > 15) {\n                    if (length > max1) {\n                        max2 = max1;\n                        max1 = length;\n                    } else if (length > max2) {\n                        max2 = length;\n                    }\n                }\n            }\n        }\n    }\n    \n    return {max1, max2};\n}\n\n// Calculate score\nlong long calculate_score() {\n    auto result = find_top_two_loops();\n    if (result.second == 0) return 0;\n    return 1LL * result.first * result.second;\n}\n\n// Enhanced initialization with more variety\nvoid initialize_enhanced() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> rot_dis(0, 3);\n    \n    // Create more diverse starting patterns\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] >= 4 && grid[i][j] <= 5) {\n                // Double curves - try to create connectivity\n                rotation[i][j] = (i + j) % 4;\n            } else if (grid[i][j] >= 6 && grid[i][j] <= 7) {\n                // Straights - align with grid structure\n                rotation[i][j] = ((i / 2) + (j / 2)) % 4;\n            } else {\n                // Single curves - create varied patterns\n                rotation[i][j] = rot_dis(gen);\n            }\n        }\n    }\n}\n\n// Advanced local search with better exploration\nvoid advanced_local_search() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    \n    long long current_score = calculate_score();\n    \n    // More iterations for better exploration\n    for (int iter = 0; iter < 20000; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        \n        // Try a random new rotation\n        int new_rotation = (old_rotation + 1 + (gen() % 3)) % 4;\n        \n        rotation[i][j] = new_rotation;\n        long long new_score = calculate_score();\n        \n        // Better acceptance criteria\n        if (new_score > current_score) {\n            current_score = new_score;\n        } else if (new_score >= current_score * 0.8 || (iter % 50 == 0 && new_score > 0)) {\n            // Accept some non-improving moves to explore, especially early on\n            current_score = max(current_score, new_score);\n        } else {\n            rotation[i][j] = old_rotation;  // Revert\n        }\n    }\n}\n\n// Final optimization pass\nvoid final_optimization() {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<> pos_dis(0, N-1);\n    \n    long long current_score = calculate_score();\n    \n    // Focused final improvement\n    for (int iter = 0; iter < 5000; iter++) {\n        int i = pos_dis(gen);\n        int j = pos_dis(gen);\n        int old_rotation = rotation[i][j];\n        \n        // Try all rotations and pick the best\n        long long best_score = current_score;\n        int best_rotation = old_rotation;\n        \n        for (int r = 0; r < 4; r++) {\n            if (r == old_rotation) continue;\n            \n            rotation[i][j] = r;\n            long long score = calculate_score();\n            \n            if (score > best_score) {\n                best_score = score;\n                best_rotation = r;\n            }\n        }\n        \n        if (best_score > current_score) {\n            rotation[i][j] = best_rotation;\n            current_score = best_score;\n        } else {\n            rotation[i][j] = old_rotation;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Enhanced initialization\n    initialize_enhanced();\n    \n    // Advanced local search\n    advanced_local_search();\n    \n    // Final optimization\n    final_optimization();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << rotation[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 10;\nconst int dx[4] = {-1, 1, 0, 0}; // U, D, L, R\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\nconst char inv_dir_chars[4] = {'D', 'U', 'R', 'L'};\n\nint N, T;\nint board[MAX_N][MAX_N];\nint empty_x, empty_y;\n\n// Check if two adjacent tiles are connected\nbool isConnected(int x1, int y1, int x2, int y2) {\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) return false;\n    if (board[x1][y1] == 0 || board[x2][y2] == 0) return false;\n    \n    // Check if they connect\n    if (x1 == x2 && y1 == y2 - 1) { // Right connection\n        return (board[x1][y1] & 4) && (board[x2][y2] & 1);\n    }\n    if (x1 == x2 && y1 == y2 + 1) { // Left connection\n        return (board[x1][y1] & 1) && (board[x2][y2] & 4);\n    }\n    if (x1 == x2 - 1 && y1 == y2) { // Down connection\n        return (board[x1][y1] & 8) && (board[x2][y2] & 2);\n    }\n    if (x1 == x2 + 1 && y1 == y2) { // Up connection\n        return (board[x1][y1] & 2) && (board[x2][y2] & 8);\n    }\n    return false;\n}\n\n// Find all connected components\nvector<vector<int>> findComponents() {\n    vector<vector<int>> component_id(N, vector<int>(N, -1));\n    int current_component = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0 || component_id[i][j] != -1) continue;\n            \n            queue<pair<int, int>> q;\n            q.push({i, j});\n            component_id[i][j] = current_component;\n            \n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                \n                // Check 4 neighbors\n                for (int k = 0; k < 4; k++) {\n                    int nx = x + dx[k];\n                    int ny = y + dy[k];\n                    \n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && \n                        component_id[nx][ny] == -1 && board[nx][ny] != 0 && \n                        isConnected(x, y, nx, ny)) {\n                        component_id[nx][ny] = current_component;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n            \n            current_component++;\n        }\n    }\n    \n    return component_id;\n}\n\n// Count component sizes\nvector<int> getComponentSizes(const vector<vector<int>>& component_id) {\n    int max_id = -1;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (component_id[i][j] > max_id) max_id = component_id[i][j];\n        }\n    }\n    \n    vector<int> sizes(max_id + 1, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (component_id[i][j] != -1) {\n                sizes[component_id[i][j]]++;\n            }\n        }\n    }\n    \n    return sizes;\n}\n\n// Calculate how many components would be connected by a move\nint calculateConnectionGain(int from_x, int from_y) {\n    // Temporarily move the tile\n    int temp = board[from_x][from_y];\n    board[from_x][from_y] = 0;\n    board[empty_x][empty_y] = temp;\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    \n    // Find components after move\n    auto component_id = findComponents();\n    auto sizes = getComponentSizes(component_id);\n    \n    int max_component_size = 0;\n    if (!sizes.empty()) {\n        max_component_size = *max_element(sizes.begin(), sizes.end());\n    }\n    \n    // Count how many components would be reduced (meaning they got connected)\n    int unique_components = 0;\n    for (int size : sizes) {\n        if (size > 0) unique_components++;\n    }\n    \n    // Restore\n    swap(empty_x, from_x);\n    swap(empty_y, from_y);\n    board[empty_x][empty_y] = 0;\n    board[from_x][from_y] = temp;\n    \n    // Return a score that prioritizes larger components and fewer total components\n    return max_component_size * 1000 - unique_components;\n}\n\n// Try to make a move\nbool makeMove(char move, string& result) {\n    int dir = -1;\n    for (int i = 0; i < 4; i++) {\n        if (dir_chars[i] == move) {\n            dir = i;\n            break;\n        }\n    }\n    \n    int new_x = empty_x + dx[dir];\n    int new_y = empty_y + dy[dir];\n    \n    if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= N) {\n        return false;\n    }\n    \n    // Perform move\n    board[empty_x][empty_y] = board[new_x][new_y];\n    board[new_x][new_y] = 0;\n    empty_x = new_x;\n    empty_y = new_y;\n    result += move;\n    \n    return true;\n}\n\n// Get current largest tree size\nint getCurrentMaxComponentSize() {\n    auto component_id = findComponents();\n    auto sizes = getComponentSizes(component_id);\n    \n    if (sizes.empty()) return 0;\n    return *max_element(sizes.begin(), sizes.end());\n}\n\n// Check if we can form connections with neighbors of the empty cell\nint getNeighborConnectionPotential() {\n    int potential = 0;\n    for (int k = 0; k < 4; k++) {\n        int nx = empty_x + dx[k];\n        int ny = empty_y + dy[k];\n        if (nx >= 0 && nx < N && ny >= 0 && ny < N && board[nx][ny] != 0) {\n            potential++;\n        }\n    }\n    return potential;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T;\n    \n    // Read board\n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            char c = line[j];\n            if (c >= '0' && c <= '9') {\n                board[i][j] = c - '0';\n            } else {\n                board[i][j] = c - 'a' + 10;\n            }\n            if (board[i][j] == 0) {\n                empty_x = i;\n                empty_y = j;\n            }\n        }\n    }\n    \n    string result = \"\";\n    int last_dir = -1;\n    \n    // Enhanced approach with better component analysis\n    for (int step = 0; step < T && (int)result.length() < T; step++) {\n        int best_score = INT_MIN;\n        int best_dir = -1;\n        \n        // Try all 4 directions\n        for (int dir = 0; dir < 4; dir++) {\n            // Avoid immediate reversals unless necessary\n            if (step > 0 && dir == (last_dir ^ 1)) continue;\n            \n            int from_x = empty_x + dx[dir];\n            int from_y = empty_y + dy[dir];\n            \n            if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n            \n            int score = calculateConnectionGain(from_x, from_y);\n            \n            // Bonus for moves that could connect to multiple neighbors\n            if (step < T * 0.7) { // In early game, prioritize flexibility\n                // Temporarily make move to check neighbor potential\n                int temp = board[from_x][from_y];\n                board[from_x][from_y] = 0;\n                board[empty_x][empty_y] = temp;\n                swap(empty_x, from_x);\n                swap(empty_y, from_y);\n                \n                score += getNeighborConnectionPotential() * 10;\n                \n                // Restore\n                swap(empty_x, from_x);\n                swap(empty_y, from_y);\n                board[empty_x][empty_y] = 0;\n                board[from_x][from_y] = temp;\n            }\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        // If no good move found, relax constraints\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                \n                if (from_x < 0 || from_x >= N || from_y < 0 || from_y >= N) continue;\n                \n                int score = calculateConnectionGain(from_x, from_y);\n                if (score > best_score) {\n                    best_score = score;\n                    best_dir = dir;\n                }\n            }\n        }\n        \n        // If still no move, pick any valid move\n        if (best_dir == -1) {\n            for (int dir = 0; dir < 4; dir++) {\n                int from_x = empty_x + dx[dir];\n                int from_y = empty_y + dy[dir];\n                if (from_x >= 0 && from_x < N && from_y >= 0 && from_y < N) {\n                    best_dir = dir;\n                    break;\n                }\n            }\n        }\n        \n        if (best_dir != -1) {\n            makeMove(dir_chars[best_dir], result);\n            last_dir = best_dir;\n        } else {\n            break;\n        }\n        \n        // Early termination if we have a near-optimal solution\n        int current_max = getCurrentMaxComponentSize();\n        if (current_max >= N * N - 2 && result.length() < T * 0.7) {\n            // Try a few more moves to complete the tree\n            if (result.length() + 10 < T) {\n                continue;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nusing P = pair<int, int>;\n\nconst int MAX_N = 10000;\nconst int RADIUS = 10000;\nconst int BOUND = 1000000000;\n\nstruct Strawberry {\n    int x, y;\n    int id;\n};\n\nint N, K;\nint a[11]; // a[1] to a[10]\nvector<Strawberry> strawberries;\n\n// Generate line through two points\ntuple<ll, ll, ll, ll> line_through_points(ll x1, ll y1, ll x2, ll y2) {\n    if (x1 == x2 && y1 == y2) {\n        x2 += 1;\n    }\n    return {x1, y1, x2, y2};\n}\n\n// Calculate centroid of strawberries\npair<double, double> calculate_centroid() {\n    if (strawberries.empty()) return {0, 0};\n    \n    double sum_x = 0, sum_y = 0;\n    for (const auto& s : strawberries) {\n        sum_x += s.x;\n        sum_y += s.y;\n    }\n    return {sum_x / N, sum_y / N};\n}\n\n// Final proven effective strategy\nvoid final_effective_strategy(vector<tuple<ll, ll, ll, ll>>& lines) {\n    if (strawberries.empty()) return;\n    \n    // Calculate centroid\n    auto [centroid_x, centroid_y] = calculate_centroid();\n    \n    int used_lines = 0;\n    \n    // 1. Radial lines from centroid - proven most effective\n    int radial_count = min(28, K/3);\n    for (int i = 0; i < radial_count && used_lines < K; i++) {\n        double angle = 2.0 * M_PI * i / max(1, radial_count);\n        // Golden ratio offset for optimal distribution\n        double offset = (sqrt(5.0) - 1.0) / 2.0;\n        angle += (i * offset);\n        \n        ll px = (ll)(centroid_x + 200000 * cos(angle));\n        ll py = (ll)(centroid_y + 200000 * sin(angle));\n        ll qx = (ll)(centroid_x - 200000 * cos(angle));\n        ll qy = (ll)(centroid_y - 200000 * sin(angle));\n        lines.push_back({px, py, qx, qy});\n        used_lines++;\n    }\n    \n    // 2. Grid lines for structured partitioning\n    int grid_dim = min(9, (int)sqrt((K - used_lines)/2));\n    if (grid_dim > 0) {\n        // Horizontal lines with non-linear spacing\n        for (int i = 0; i <= grid_dim && used_lines < K; i++) {\n            double ratio = (double)i / max(1, grid_dim);\n            ratio = pow(ratio, 0.8); // Non-linear for better distribution\n            int y_pos = (int)(centroid_y - RADIUS + 2 * RADIUS * ratio);\n            lines.push_back(line_through_points(-BOUND, y_pos, BOUND, y_pos));\n            used_lines++;\n        }\n        \n        // Vertical lines with non-linear spacing\n        for (int i = 0; i <= grid_dim && used_lines < K; i++) {\n            double ratio = (double)i / max(1, grid_dim);\n            ratio = pow(ratio, 1.2); // Non-linear for better distribution\n            int x_pos = (int)(centroid_x - RADIUS + 2 * RADIUS * ratio);\n            lines.push_back(line_through_points(x_pos, -BOUND, x_pos, BOUND));\n            used_lines++;\n        }\n    }\n    \n    // 3. Strategic separators for nearby strawberry pairs\n    vector<pair<double, pair<int, int>>> distances;\n    for (int i = 0; i < min(N, 35); i++) {\n        for (int j = i + 1; j < min(N, 35); j++) {\n            double dist = sqrt(pow(strawberries[i].x - strawberries[j].x, 2) + \n                              pow(strawberries[i].y - strawberries[j].y, 2));\n            distances.push_back({dist, {i, j}});\n        }\n    }\n    \n    // Sort by distance and create separators for closest pairs\n    sort(distances.begin(), distances.end());\n    \n    for (int i = 0; i < min(18, (int)distances.size()) && used_lines < K - 2; i++) {\n        int idx1 = distances[i].second.first;\n        int idx2 = distances[i].second.second;\n        \n        if (idx1 != idx2) {\n            // Perpendicular bisector with strategic perturbation\n            double mid_x = (strawberries[idx1].x + strawberries[idx2].x) / 2.0;\n            double mid_y = (strawberries[idx1].y + strawberries[idx2].y) / 2.0;\n            int dx = strawberries[idx2].x - strawberries[idx1].x;\n            int dy = strawberries[idx2].y - strawberries[idx1].y;\n            \n            // Intelligent perturbation based on index for uniqueness\n            double perturb_x = (i % 7 - 3) * 2.5;\n            double perturb_y = (i % 5 - 2) * 2.5;\n            \n            lines.push_back({(ll)(mid_x - dy + perturb_x), \n                           (ll)(mid_y + dx + perturb_y),\n                           (ll)(mid_x + dy + perturb_x), \n                           (ll)(mid_y - dx + perturb_y)});\n            used_lines++;\n        }\n    }\n    \n    // 4. High-priority isolation for single strawberry demand (a_1)\n    int singles_to_isolate = min(a[1], 10);\n    for (int i = 0; i < singles_to_isolate && used_lines < K - 1; i++) {\n        if (i < N) {\n            int x = strawberries[i].x;\n            int y = strawberries[i].y;\n            \n            // Create cross pattern for effective isolation\n            int offset = 70 + (i % 30);\n            \n            if (used_lines < K) {\n                lines.push_back(line_through_points(x - offset, y, x + offset + (i%7), y + (i%5 - 2)));\n                used_lines++;\n            }\n            if (used_lines < K) {\n                lines.push_back(line_through_points(x, y - offset, x + (i%4 - 2), y + offset + (i%6)));\n                used_lines++;\n            }\n        }\n    }\n    \n    // 5. Diversified filling for remaining lines\n    while (used_lines < K) {\n        // Weighted strategy selection for maximum diversity\n        int choice = rand() % 100;\n        \n        if (choice < 30) {\n            // Radial lines with golden ratio distribution\n            double angle = 2.0 * M_PI * used_lines / max(1, K);\n            double phi = (1.0 + sqrt(5.0)) / 2.0;\n            angle += (used_lines / phi);\n            \n            ll px = (ll)(centroid_x + 150000 * cos(angle));\n            ll py = (ll)(centroid_y + 150000 * sin(angle));\n            ll qx = (ll)(centroid_x - 150000 * cos(angle));\n            ll qy = (ll)(centroid_y - 150000 * sin(angle));\n            lines.push_back({px, py, qx, qy});\n        }\n        else if (choice < 55) {\n            // Grid-based lines\n            int pos_x = (rand() % (2 * RADIUS)) - RADIUS + (int)centroid_x;\n            int pos_y = (rand() % (2 * RADIUS)) - RADIUS + (int)centroid_y;\n            \n            if (rand() % 2) {\n                lines.push_back(line_through_points(pos_x - 100000, pos_y, pos_x + 100000, pos_y));\n            } else {\n                lines.push_back(line_through_points(pos_x, pos_y - 100000, pos_x, pos_y + 100000));\n            }\n        }\n        else if (choice < 75) {\n            // Intelligent separators\n            if (N > 1) {\n                int idx1 = rand() % N;\n                int idx2 = (idx1 + 1 + rand() % min(12, max(1, N-1))) % N;\n                \n                if (idx1 != idx2) {\n                    double mid_x = (strawberries[idx1].x + strawberries[idx2].x) / 2.0;\n                    double mid_y = (strawberries[idx1].y + strawberries[idx2].y) / 2.0;\n                    int dx = strawberries[idx2].x - strawberries[idx1].x;\n                    int dy = strawberries[idx2].y - strawberries[idx1].y;\n                    \n                    lines.push_back({(ll)(mid_x - dy + (rand()%11 - 5)), \n                                   (ll)(mid_y + dx + (rand()%11 - 5)),\n                                   (ll)(mid_x + dy + (rand()%11 - 5)), \n                                   (ll)(mid_y - dx + (rand()%11 - 5))});\n                } else {\n                    goto random_line;\n                }\n            } else {\n                goto random_line;\n            }\n        }\n        else {\n            random_line:\n            // High-quality random lines\n            ll px = (ll)((rand() % (2 * BOUND)) - BOUND);\n            ll py = (ll)((rand() % (2 * BOUND)) - BOUND);\n            ll qx = (ll)((rand() % (2 * BOUND)) - BOUND);\n            ll qy = (ll)((rand() % (2 * BOUND)) - BOUND);\n            \n            // Ensure sufficient point separation\n            if (abs(px - qx) + abs(py - qy) < 100) {\n                qx += (rand() % 100) + 10;\n                qy += (rand() % 100) - 50;\n            }\n            \n            lines.push_back({px, py, qx, qy});\n        }\n        used_lines++;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // High quality random seeding for consistent performance\n    auto seed = time(nullptr) ^ (intptr_t)&cout ^ chrono::duration_cast<chrono::nanoseconds>(\n        chrono::high_resolution_clock::now().time_since_epoch()).count();\n    srand(seed);\n    \n    cin >> N >> K;\n    \n    int total_demand = 0;\n    for (int d = 1; d <= 10; d++) {\n        cin >> a[d];\n        total_demand += a[d];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n    }\n    \n    // Apply the final proven effective strategy\n    vector<tuple<ll, ll, ll, ll>> lines;\n    final_effective_strategy(lines);\n    \n    // Ensure we don't exceed K lines\n    if ((int)lines.size() > K) {\n        lines.resize(K);\n    }\n    \n    // Output the solution\n    cout << lines.size() << \"\\n\";\n    for (const auto& line : lines) {\n        auto [px, py, qx, qy] = line;\n        cout << px << \" \" << py << \" \" << qx << \" \" << qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace chrono;\n\nconst int MAX_N = 65;\nbool grid[MAX_N][MAX_N];\nint N, M;\nvector<pair<int, int>> initial_dots;\nvector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n// Store edges of drawn rectangles to prevent overlaps\nset<pair<pair<int, int>, pair<int, int>>> drawn_edges;\n\nauto start_time = high_resolution_clock::now();\nconst double TIME_LIMIT = 4.7;\n\n// Weight calculation\ninline long long weight(int x, int y) {\n    int c = (N - 1) / 2;\n    int dx = x - c;\n    int dy = y - c;\n    return (long long)dx * dx + (long long)dy * dy + 1;\n}\n\nbool time_limit_exceeded() {\n    auto now = high_resolution_clock::now();\n    auto duration = duration_cast<milliseconds>(now - start_time);\n    return duration.count() > TIME_LIMIT * 1000;\n}\n\n// Generate all points on a line segment\nvector<pair<int, int>> get_line_points(int x1, int y1, int x2, int y2) {\n    vector<pair<int, int>> points;\n    \n    if (x1 == x2 && y1 == y2) {\n        points.push_back({x1, y1});\n        return points;\n    }\n    \n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int steps = max(abs(dx), abs(dy));\n    \n    for (int i = 0; i <= steps; i++) {\n        int x = x1 + (dx * i) / steps;\n        int y = y1 + (dy * i) / steps;\n        points.push_back({x, y});\n    }\n    return points;\n}\n\n// Normalize edge to have consistent representation\npair<pair<int, int>, pair<int, int>> normalize_edge(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) {\n        return {{x2, y2}, {x1, y1}};\n    }\n    return {{x1, y1}, {x2, y2}};\n}\n\n// Get all edges of a rectangle\nvector<pair<pair<int, int>, pair<int, int>>> get_rectangle_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    vector<pair<pair<int, int>, pair<int, int>>> edges;\n    edges.push_back(normalize_edge(x1, y1, x2, y2));\n    edges.push_back(normalize_edge(x2, y2, x3, y3));\n    edges.push_back(normalize_edge(x3, y3, x4, y4));\n    edges.push_back(normalize_edge(x4, y4, x1, y1));\n    return edges;\n}\n\n// Check if rectangle edges overlap with existing edges\nbool has_edge_overlap(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto edges = get_rectangle_edges(x1, y1, x2, y2, x3, y3, x4, y4);\n    for (const auto& edge : edges) {\n        if (drawn_edges.count(edge)) return true;\n    }\n    return false;\n}\n\n// Add edges of a rectangle to the drawn set\nvoid add_rectangle_edges(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto edges = get_rectangle_edges(x1, y1, x2, y2, x3, y3, x4, y4);\n    for (const auto& edge : edges) {\n        drawn_edges.insert(edge);\n    }\n}\n\n// Check if four points form a valid rectangle (axis-parallel or 45-degree)\nbool is_valid_rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    // Check if diagonals bisect each other (parallelogram property)\n    if (x1 + x3 != x2 + x4 || y1 + y3 != y2 + y4) {\n        return false;\n    }\n    \n    // Check if all sides are valid directions (axis-parallel or 45-degree)\n    vector<pair<int, int>> points = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    for (int i = 0; i < 4; i++) {\n        int j = (i + 1) % 4;\n        int dx = points[j].first - points[i].first;\n        int dy = points[j].second - points[i].second;\n        \n        // Valid moves: horizontal, vertical, or diagonal (|dx| = |dy|)\n        if (dx == 0 && dy == 0) return false; // Same point\n        if (!(dx == 0 || dy == 0 || abs(dx) == abs(dy))) {\n            return false;\n        }\n    }\n    \n    // Check that it's actually a rectangle by verifying diagonals are equal\n    long long diag1_sq = (long long)(x3 - x1) * (x3 - x1) + (long long)(y3 - y1) * (y3 - y1);\n    long long diag2_sq = (long long)(x4 - x2) * (x4 - x2) + (long long)(y4 - y2) * (y4 - y2);\n    \n    if (diag1_sq != diag2_sq) return false;\n    \n    return true;\n}\n\n// Check if there are no dots on the perimeter except the 4 vertices\nbool no_dots_on_perimeter(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    set<pair<int, int>> vertices = {{x1, y1}, {x2, y2}, {x3, y3}, {x4, y4}};\n    \n    // Check each side\n    auto side1 = get_line_points(x1, y1, x2, y2);\n    auto side2 = get_line_points(x2, y2, x3, y3);\n    auto side3 = get_line_points(x3, y3, x4, y4);\n    auto side4 = get_line_points(x4, y4, x1, y1);\n    \n    for (const auto& p : side1) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side2) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side3) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    for (const auto& p : side4) {\n        if (!vertices.count(p) && grid[p.first][p.second]) return false;\n    }\n    \n    return true;\n}\n\nvoid solve() {\n    // Initialize with initial dots\n    vector<pair<int, int>> dots;\n    for (int i = 0; i < M; i++) {\n        dots.push_back(initial_dots[i]);\n        grid[initial_dots[i].first][initial_dots[i].second] = true;\n    }\n    \n    // Keep trying until no more valid operations\n    while (!time_limit_exceeded()) {\n        bool found = false;\n        \n        // Create candidate positions sorted by weight\n        vector<tuple<long long, int, int>> candidates;\n        for (int x = 1; x < N - 1; x++) {\n            for (int y = 1; y < N - 1; y++) {\n                if (!grid[x][y]) {\n                    long long w = weight(x, y);\n                    candidates.push_back({w, x, y});\n                }\n            }\n        }\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Try candidates in order of weight\n        for (const auto& candidate : candidates) {\n            if (time_limit_exceeded()) break;\n            \n            int x1 = get<1>(candidate);\n            int y1 = get<2>(candidate);\n            \n            // Try combinations of existing dots\n            int sz = dots.size();\n            \n            // Limit search to avoid timeout - focus on recent dots which are more likely to form rectangles\n            int start_idx = max(0, sz - 50);\n            int end_idx = sz;\n            \n            for (int i = start_idx; i < end_idx && !found; i++) {\n                for (int j = i + 1; j < end_idx && !found; j++) {\n                    for (int k = j + 1; k < end_idx && !found; k++) {\n                        if (time_limit_exceeded()) return;\n                        \n                        int x2 = dots[i].first, y2 = dots[i].second;\n                        int x3 = dots[j].first, y3 = dots[j].second;\n                        int x4 = dots[k].first, y4 = dots[k].second;\n                        \n                        // Try all permutations\n                        vector<vector<int>> perms = {\n                            {x2, y2, x3, y3, x4, y4},\n                            {x2, y2, x4, y4, x3, y3},\n                            {x3, y3, x2, y2, x4, y4},\n                            {x3, y3, x4, y4, x2, y2},\n                            {x4, y4, x2, y2, x3, y3},\n                            {x4, y4, x3, y3, x2, y2}\n                        };\n                        \n                        for (const auto& perm : perms) {\n                            if (is_valid_rectangle(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                if (no_dots_on_perimeter(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                    if (!has_edge_overlap(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5])) {\n                                        // Valid operation\n                                        operations.push_back(make_tuple(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]));\n                                        grid[x1][y1] = true;\n                                        dots.push_back({x1, y1});\n                                        add_rectangle_edges(x1, y1, perm[0], perm[1], perm[2], perm[3], perm[4], perm[5]);\n                                        found = true;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (found) break;\n        }\n        \n        if (!found) break;\n    }\n}\n\nint main() {\n    start_time = high_resolution_clock::now();\n    \n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    initial_dots.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> initial_dots[i].first >> initial_dots[i].second;\n    }\n    \n    solve();\n    \n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" \n             << get<2>(op) << \" \" << get<3>(op) << \" \"\n             << get<4>(op) << \" \" << get<5>(op) << \" \"\n             << get<6>(op) << \" \" << get<7>(op) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GRID_SIZE = 10;\nconst int TOTAL_CANDIES = 100;\n\n// Directions: F(forward/up), B(backward/down), L(left), R(right)\nconst vector<pair<int, int>> DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\nconst string DIR_CHARS = \"FBLR\";\n\nclass CandyBox {\nprivate:\n    vector<vector<int>> grid; // 0 = empty, 1,2,3 = flavors\n\npublic:\n    CandyBox() : grid(GRID_SIZE, vector<int>(GRID_SIZE, 0)) {}\n\n    void place_candy(int pos, int flavor) {\n        int empty_count = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] == 0) {\n                    empty_count++;\n                    if (empty_count == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    // Simulate tilting in given direction\n    void tilt(int dir_idx) {\n        auto [di, dj] = DIRS[dir_idx];\n        \n        if (dir_idx == 0) { // Forward (up) - process top to bottom\n            for (int i = 0; i < GRID_SIZE; i++) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 1) { // Backward (down) - process bottom to top\n            for (int i = GRID_SIZE - 1; i >= 0; i--) {\n                for (int j = 0; j < GRID_SIZE; j++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else if (dir_idx == 2) { // Left - process left to right\n            for (int j = 0; j < GRID_SIZE; j++) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        } else { // Right - process right to left\n            for (int j = GRID_SIZE - 1; j >= 0; j--) {\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    if (grid[i][j] != 0) {\n                        move_candy(i, j, di, dj);\n                    }\n                }\n            }\n        }\n    }\n\nprivate:\n    void move_candy(int i, int j, int di, int dj) {\n        int flavor = grid[i][j];\n        grid[i][j] = 0;\n        \n        int ni = i + di, nj = j + dj;\n        while (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == 0) {\n            i = ni;\n            j = nj;\n            ni += di;\n            nj += dj;\n        }\n        \n        grid[i][j] = flavor;\n    }\n\npublic:\n    // Simple but effective evaluation: sum of squares of component sizes\n    long long evaluate_clustering() {\n        vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n        long long total_score = 0;\n        \n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int component_size = dfs_component(i, j, grid[i][j], visited);\n                    total_score += (long long)component_size * component_size;\n                }\n            }\n        }\n        \n        return total_score;\n    }\n\nprivate:\n    int dfs_component(int i, int j, int flavor, vector<vector<bool>>& visited) {\n        if (i < 0 || i >= GRID_SIZE || j < 0 || j >= GRID_SIZE || \n            visited[i][j] || grid[i][j] != flavor) {\n            return 0;\n        }\n        \n        visited[i][j] = true;\n        int size = 1;\n        \n        // Check 4 adjacent cells\n        for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n            size += dfs_component(i + di, j + dj, flavor, visited);\n        }\n        \n        return size;\n    }\n\npublic:\n    CandyBox copy() const {\n        CandyBox new_box;\n        new_box.grid = grid;\n        return new_box;\n    }\n    \n    // Count immediate connections (adjacent same-flavor candies)\n    int count_connections() {\n        int connections = 0;\n        for (int i = 0; i < GRID_SIZE; i++) {\n            for (int j = 0; j < GRID_SIZE; j++) {\n                if (grid[i][j] != 0) {\n                    int flavor = grid[i][j];\n                    // Check adjacent cells\n                    for (auto [di, dj] : vector<pair<int, int>>{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}) {\n                        int ni = i + di, nj = j + dj;\n                        if (ni >= 0 && ni < GRID_SIZE && nj >= 0 && nj < GRID_SIZE && grid[ni][nj] == flavor) {\n                            connections++;\n                        }\n                    }\n                }\n            }\n        }\n        return connections / 2; // Each connection counted twice\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    vector<int> flavors(TOTAL_CANDIES);\n    for (int i = 0; i < TOTAL_CANDIES; i++) {\n        cin >> flavors[i];\n    }\n    \n    CandyBox box;\n    \n    for (int t = 0; t < TOTAL_CANDIES; t++) {\n        int pos;\n        cin >> pos;\n        \n        // Place the candy\n        box.place_candy(pos, flavors[t]);\n        \n        if (t == TOTAL_CANDIES - 1) {\n            // No need to output direction for last candy\n            break;\n        }\n        \n        // Evaluate each possible tilt direction\n        int best_direction = 0;\n        long long best_score = -1;\n        \n        // Try all directions and pick the best one\n        for (int dir = 0; dir < 4; dir++) {\n            CandyBox temp_box = box.copy();\n            temp_box.tilt(dir);\n            long long score = temp_box.evaluate_clustering();\n            \n            // Small bonus for creating more connections\n            score += temp_box.count_connections() * 2;\n            \n            if (score > best_score) {\n                best_score = score;\n                best_direction = dir;\n            }\n        }\n        \n        cout << DIR_CHARS[best_direction] << endl;\n        cout.flush();\n        \n        // Actually perform the tilt\n        box.tilt(best_direction);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n\nusing namespace std;\n\n// Fast I/O optimization\nstatic auto fast_io = []() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cout.tie(nullptr);\n    return 0;\n}();\n\n// Convert adjacency matrix to string representation\nstring graphToString(const vector<vector<int>>& adj, int n) {\n    string result;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            result += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return result;\n}\n\n// Convert string to adjacency matrix\nvector<vector<int>> stringToGraph(const string& s, int n) {\n    vector<vector<int>> adj(n, vector<int>(n, 0));\n    int idx = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            if (s[idx] == '1') {\n                adj[i][j] = adj[j][i] = 1;\n            }\n            idx++;\n        }\n    }\n    return adj;\n}\n\n// Count edges\nint countEdges(const vector<vector<int>>& adj, int n) {\n    int count = 0;\n    for (int i = 0; i < n; ++i) {\n        for (int j = i + 1; j < n; ++j) {\n            count += adj[i][j];\n        }\n    }\n    return count;\n}\n\n// Generate graphs with systematic edge distribution\nvector<string> generateGraphs(int M, int N) {\n    vector<string> graphs;\n    \n    int max_edges = N * (N - 1) / 2;\n    \n    for (int k = 0; k < M; ++k) {\n        vector<vector<int>> adj(N, vector<int>(N, 0));\n        \n        // Calculate target edge count with better distribution\n        int target_edges = 0;\n        if (M > 1) {\n            target_edges = (k * max_edges) / (M - 1);\n        }\n        \n        // Ensure valid range\n        target_edges = max(0, min(max_edges, target_edges));\n        \n        // Add edges systematically with improved pattern\n        int added = 0;\n        \n        // Use deterministic pattern based on k for better separation\n        for (int i = 0; i < N && added < target_edges; ++i) {\n            for (int j = i + 1; j < N && added < target_edges; ++j) {\n                // Better hash function for more even distribution\n                long long hash = (1LL * i * 11 + 1LL * j * 13 + 1LL * k * 17) % 29;\n                if (hash < 15) {\n                    adj[i][j] = adj[j][i] = 1;\n                    added++;\n                }\n            }\n        }\n        \n        // Fill remaining edges if needed\n        if (added < target_edges) {\n            for (int i = 0; i < N && added < target_edges; ++i) {\n                for (int j = i + 1; j < N && added < target_edges; ++j) {\n                    if (!adj[i][j]) {\n                        adj[i][j] = adj[j][i] = 1;\n                        added++;\n                    }\n                }\n            }\n        }\n        \n        graphs.push_back(graphToString(adj, N));\n    }\n    \n    return graphs;\n}\n\n// Prediction function with slight enhancement\nint predictGraph(const vector<vector<int>>& noisy_adj, int N, int M, double epsilon, \n                 const vector<int>& template_edge_counts) {\n    int edge_count = countEdges(noisy_adj, N);\n    \n    // Find the closest match\n    int best_match = 0;\n    int min_diff = abs(edge_count - template_edge_counts[0]);\n    \n    for (int i = 1; i < M; ++i) {\n        int diff = abs(edge_count - template_edge_counts[i]);\n        if (diff < min_diff) {\n            min_diff = diff;\n            best_match = i;\n        }\n    }\n    \n    return best_match;\n}\n\nint main() {\n    int M;\n    double epsilon;\n    cin >> M >> epsilon;\n    \n    // Conservative N selection based on proven good performance\n    int N;\n    if (epsilon > 0.3) {\n        // Very high noise: smaller graphs\n        N = max(6, min(12, 6 + M/8));\n    } else if (epsilon > 0.2) {\n        // High noise\n        N = max(8, min(18, 8 + M/6));\n    } else if (epsilon > 0.1) {\n        // Medium noise\n        N = max(10, min(25, 10 + M/4));\n    } else if (epsilon > 0.05) {\n        // Low-medium noise\n        N = max(12, min(35, 12 + M/3));\n    } else {\n        // Low noise: larger graphs for better discrimination\n        N = max(15, min(50, 15 + M/2));\n    }\n    \n    // Ensure bounds with better minimum for small M\n    if (M <= 20) {\n        N = max(N, 10);  // Ensure decent size for small M\n    }\n    \n    N = min(N, 100);\n    N = max(N, 4);\n    \n    // Generate template graphs\n    auto graphs = generateGraphs(M, N);\n    \n    // Precompute template edge counts\n    vector<int> template_edge_counts(M);\n    for (int i = 0; i < M; ++i) {\n        auto adj = stringToGraph(graphs[i], N);\n        template_edge_counts[i] = countEdges(adj, N);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    // Process queries\n    for (int q = 0; q < 100; ++q) {\n        string h_str;\n        cin >> h_str;\n        \n        auto noisy_adj = stringToGraph(h_str, N);\n        \n        // Predict which graph it came from\n        int prediction = predictGraph(noisy_adj, N, M, epsilon, template_edge_counts);\n        \n        cout << prediction << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\nconst int MAXN = 1005;\nconst int MAXM = 3005;\n\nstruct Edge {\n    int u, v, w, id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<vector<pair<int, int>>> adj;\n\n// Calculate edge scores - simpler but effective approach\nvector<pair<double, int>> scoreEdges() {\n    vector<pair<double, int>> scores(M);\n    \n    for (int i = 0; i < M; i++) {\n        const auto& e = edges[i];\n        \n        // Degree of endpoints\n        int deg_u = adj[e.u].size();\n        int deg_v = adj[e.v].size();\n        \n        // Common neighbors (measure of redundancy)\n        int common_neighbors = 0;\n        vector<bool> neighbor_u(N, false);\n        for (auto& p : adj[e.u]) {\n            if (p.first != e.v) {\n                neighbor_u[p.first] = true;\n            }\n        }\n        for (auto& p : adj[e.v]) {\n            if (p.first != e.u && neighbor_u[p.first]) {\n                common_neighbors++;\n            }\n        }\n        \n        // Criticality score: higher score = more critical (should be repaired later)\n        // Heuristic: lighter edges between low-degree vertices with few alternatives are more critical\n        double score = (1.0 / e.w) * sqrt((double)deg_u * deg_v) / (1.0 + common_neighbors);\n        \n        scores[i] = {score, i};\n    }\n    \n    return scores;\n}\n\n// Assign days with balanced distribution\nvector<int> assignDays() {\n    vector<int> result(M);\n    \n    // Get edge scores\n    auto scores = scoreEdges();\n    \n    // Sort by criticality (ascending - less critical first)\n    sort(scores.begin(), scores.end());\n    \n    // Distribute edges across days\n    vector<int> day_count(D, 0);\n    \n    // Assign edges trying to balance load\n    for (int i = 0; i < M; i++) {\n        int edge_id = scores[i].second;\n        \n        // Find the best day to place this edge\n        int best_day = 0;\n        int min_count = K + 1;\n        \n        // Prefer days under the limit with fewer edges\n        for (int day = 0; day < D; day++) {\n            if (day_count[day] < K && day_count[day] < min_count) {\n                min_count = day_count[day];\n                best_day = day;\n            }\n        }\n        \n        // If all days are at capacity, put in the least loaded day\n        if (min_count == K + 1) {\n            min_count = INF;\n            for (int day = 0; day < D; day++) {\n                if (day_count[day] < min_count) {\n                    min_count = day_count[day];\n                    best_day = day;\n                }\n            }\n        }\n        \n        result[edge_id] = best_day + 1;\n        day_count[best_day]++;\n    }\n    \n    return result;\n}\n\n// Simple fallback approach based purely on weights\nvector<int> weightBasedAssignment() {\n    vector<int> result(M);\n    \n    // Sort edges by weight (lighter edges first - more critical)\n    vector<pair<int, int>> weights(M);\n    for (int i = 0; i < M; i++) {\n        weights[i] = {edges[i].w, i};\n    }\n    sort(weights.begin(), weights.end());\n    \n    // Assign to days sequentially\n    for (int i = 0; i < M; i++) {\n        int edge_id = weights[i].second;\n        int day = min(i / K, D - 1);\n        result[edge_id] = day + 1;\n    }\n    \n    // Ensure we don't exceed K edges per day\n    vector<int> day_count(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_count[result[i]]++;\n    }\n    \n    // Fix violations by redistribution\n    vector<vector<int>> day_edges(D);\n    for (int i = 0; i < M; i++) {\n        day_edges[result[i] - 1].push_back(i);\n    }\n    \n    for (int day = 0; day < D; day++) {\n        while (day_edges[day].size() > K) {\n            int edge_id = day_edges[day].back();\n            day_edges[day].pop_back();\n            \n            // Find a day with space\n            bool placed = false;\n            for (int target_day = 0; target_day < D; target_day++) {\n                if (day_edges[target_day].size() < K) {\n                    day_edges[target_day].push_back(edge_id);\n                    result[edge_id] = target_day + 1;\n                    placed = true;\n                    break;\n                }\n            }\n            // If no space found, put in last resort day\n            if (!placed) {\n                if (day != D - 1) {\n                    day_edges[D - 1].push_back(edge_id);\n                    result[edge_id] = D;\n                }\n            }\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 >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        u--; v--; // Convert to 0-indexed\n        edges[i] = {u, v, w, i};\n    }\n    \n    // Skip coordinate input\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Build adjacency list\n    adj.assign(N, vector<pair<int, int>>());\n    for (const auto& e : edges) {\n        adj[e.u].push_back({e.v, e.w});\n        adj[e.v].push_back({e.u, e.w});\n    }\n    \n    // Use the better approach from solution 3\n    vector<int> result = assignDays();\n    \n    // Output result\n    for (int i = 0; i < M; i++) {\n        cout << result[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_D = 14;\nint D;\nchar f[2][MAX_D][MAX_D];\nchar r[2][MAX_D][MAX_D];\n\n// 3D grid for each construction\nint b[2][MAX_D][MAX_D][MAX_D];\n\n// Directions for 6-connectivity\nconst int dx[6] = {1, -1, 0, 0, 0, 0};\nconst int dy[6] = {0, 0, 1, -1, 0, 0};\nconst int dz[6] = {0, 0, 0, 0, 1, -1};\n\nbool isValid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n\n// Simple BFS to find connected component\nvector<tuple<int,int,int>> findComponent(int grid[MAX_D][MAX_D][MAX_D], \n                                        vector<vector<vector<bool>>>& visited,\n                                        int start_x, int start_y, int start_z) {\n    vector<tuple<int,int,int>> component;\n    \n    if (!isValid(start_x, start_y, start_z) || \n        grid[start_x][start_y][start_z] == 0 || \n        visited[start_x][start_y][start_z]) {\n        return component;\n    }\n    \n    queue<tuple<int,int,int>> q;\n    q.push({start_x, start_y, start_z});\n    visited[start_x][start_y][start_z] = true;\n    component.push_back({start_x, start_y, start_z});\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front(); q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            \n            if (isValid(nx, ny, nz) && \n                !visited[nx][ny][nz] && \n                grid[nx][ny][nz] == 1) {\n                visited[nx][ny][nz] = true;\n                q.push({nx, ny, nz});\n                component.push_back({nx, ny, nz});\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    \n    // Read input\n    for (int i = 0; i < 2; i++) {\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int x = 0; x < D; x++) {\n                f[i][z][x] = line[x];\n            }\n        }\n        for (int z = 0; z < D; z++) {\n            string line;\n            cin >> line;\n            for (int y = 0; y < D; y++) {\n                r[i][z][y] = line[y];\n            }\n        }\n    }\n    \n    // Smarter approach: Instead of placing cubes everywhere, \n    // try to satisfy silhouettes with minimal connected structures\n    \n    int valid_cubes[2][MAX_D][MAX_D][MAX_D] = {0};\n    \n    for (int constr = 0; constr < 2; constr++) {\n        // Strategy: For each z-level, create a minimal connected structure\n        // that satisfies both silhouette constraints\n        \n        for (int z = 0; z < D; z++) {\n            // Find valid x positions (from front silhouette)\n            vector<int> valid_x;\n            for (int x = 0; x < D; x++) {\n                if (f[constr][z][x] == '1') {\n                    valid_x.push_back(x);\n                }\n            }\n            \n            // Find valid y positions (from right silhouette)\n            vector<int> valid_y;\n            for (int y = 0; y < D; y++) {\n                if (r[constr][z][y] == '1') {\n                    valid_y.push_back(y);\n                }\n            }\n            \n            // Create a minimal structure that satisfies both constraints\n            if (!valid_x.empty() && !valid_y.empty()) {\n                // Simple strategy: place a single line that covers both constraints\n                int x_start = valid_x.front();\n                int x_end = valid_x.back();\n                int y_start = valid_y.front();\n                int y_end = valid_y.back();\n                \n                // Place a connected structure - for example, a \"L\" shape or line\n                // Connect x_range with y_range\n                \n                // Strategy: Place cubes along x-axis for a fixed y, and along y-axis for a fixed x\n                // This creates a connected structure with fewer total cubes\n                \n                // Place cubes along x-axis at y_start\n                for (int x : valid_x) {\n                    valid_cubes[constr][x][y_start][z] = 1;\n                }\n                \n                // Place cubes along y-axis at x_start (but avoid double placement)\n                for (int y : valid_y) {\n                    if (y != y_start || find(valid_x.begin(), valid_x.end(), x_start) == valid_x.end()) {\n                        valid_cubes[constr][x_start][y][z] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Reset output grid\n    memset(b, 0, sizeof(b));\n    \n    // Find connected components for each construction independently\n    int block_id = 1;\n    \n    // Process each construction\n    for (int constr = 0; constr < 2; constr++) {\n        vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (valid_cubes[constr][x][y][z] == 1 && !visited[x][y][z]) {\n                        auto component = findComponent(valid_cubes[constr], visited, x, y, z);\n                        if (!component.empty()) {\n                            // Assign a unique block ID to this connected component\n                            int current_block_id = block_id++;\n                            \n                            for (const auto& cube : component) {\n                                int cx = get<0>(cube), cy = get<1>(cube), cz = get<2>(cube);\n                                b[constr][cx][cy][cz] = current_block_id;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output result\n    cout << (block_id - 1) << \"\\n\";\n    \n    for (int constr = 0; constr < 2; constr++) {\n        bool first = true;\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                for (int z = 0; z < D; z++) {\n                    if (!first) cout << \" \";\n                    cout << b[constr][x][y][z];\n                    first = false;\n                }\n            }\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\nusing ld = long double;\nusing pii = pair<int, int>;\nusing pll = pair<ll, ll>;\n\nconst int MAX_N = 100;\nconst int MAX_M = 300;\nconst int MAX_K = 5000;\nconst int MAX_POWER = 5000;\n\nint N, M, K;\nvector<pair<int, int>> vertices;\nvector<tuple<int, int, int>> edges;\nvector<pair<int, int>> residents;\n\n// Distance calculation\nint euclidean_distance(int i, int j) {\n    int dx = vertices[i].first - vertices[j].first;\n    int dy = vertices[i].second - vertices[j].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\nint resident_to_vertex_distance(int res_idx, int vert_idx) {\n    int dx = residents[res_idx].first - vertices[vert_idx].first;\n    int dy = residents[res_idx].second - vertices[vert_idx].second;\n    return round(sqrt(dx * dx + dy * dy));\n}\n\n// Find minimum spanning tree using Prim's algorithm\nvector<bool> find_mst_edges() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vertex_reached[0] = true; // Start from vertex 1 (index 0)\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    \n    // Add all edges from vertex 1\n    for (int j = 0; j < M; j++) {\n        auto [u, v, w] = edges[j];\n        u--; v--; // Convert to 0-indexed\n        if (u == 0) {\n            pq.push({w, v, j});\n        } else if (v == 0) {\n            pq.push({w, u, j});\n        }\n    }\n    \n    while (!pq.empty()) {\n        auto [weight, to, edge_idx] = pq.top();\n        pq.pop();\n        \n        if (vertex_reached[to]) continue;\n        \n        vertex_reached[to] = true;\n        edge_used[edge_idx] = true;\n        \n        // Add edges from newly reached vertex\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            if (u == to && !vertex_reached[v]) {\n                pq.push({w, v, j});\n            } else if (v == to && !vertex_reached[u]) {\n                pq.push({w, u, j});\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\n// Calculate minimum power needed for each vertex to cover residents\nvector<int> calculate_min_power(const vector<bool>& vertex_active) {\n    vector<int> power(N, 0);\n    vector<bool> covered(K, false);\n    \n    // First pass: calculate required power for each active vertex\n    for (int i = 0; i < N; i++) {\n        if (!vertex_active[i]) continue;\n        \n        int max_dist = 0;\n        for (int k = 0; k < K; k++) {\n            int dist = resident_to_vertex_distance(k, i);\n            if (dist <= MAX_POWER) {\n                max_dist = max(max_dist, dist);\n            }\n        }\n        power[i] = max_dist;\n    }\n    \n    // Greedy approach: iteratively improve coverage\n    for (int iter = 0; iter < 3; iter++) {\n        fill(covered.begin(), covered.end(), false);\n        \n        // Mark covered residents\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i] || power[i] == 0) continue;\n            for (int k = 0; k < K; k++) {\n                if (resident_to_vertex_distance(k, i) <= power[i]) {\n                    covered[k] = true;\n                }\n            }\n        }\n        \n        // Find uncovered residents\n        vector<int> uncovered;\n        for (int k = 0; k < K; k++) {\n            if (!covered[k]) uncovered.push_back(k);\n        }\n        \n        if (uncovered.empty()) break;\n        \n        // For each active vertex, see how much additional power helps\n        for (int i = 0; i < N; i++) {\n            if (!vertex_active[i]) continue;\n            \n            int max_needed = 0;\n            for (int k : uncovered) {\n                int dist = resident_to_vertex_distance(k, i);\n                if (dist <= MAX_POWER) {\n                    max_needed = max(max_needed, dist);\n                }\n            }\n            power[i] = max(power[i], max_needed);\n        }\n    }\n    \n    return power;\n}\n\n// Improved approach: use a more sophisticated method\nvector<bool> improved_edge_selection() {\n    vector<bool> edge_used(M, false);\n    vector<bool> vertex_reached(N, false);\n    vector<bool> resident_covered(K, false);\n    vertex_reached[0] = true;\n    \n    // Precompute resident distances to all vertices\n    vector<vector<int>> resident_distances(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resident_distances[k][i] = resident_to_vertex_distance(k, i);\n        }\n    }\n    \n    // Greedily select edges that maximize coverage efficiency\n    for (int step = 0; step < N - 1; step++) {\n        int best_edge = -1;\n        double best_efficiency = -1e18;\n        \n        // Find the best edge to add\n        for (int j = 0; j < M; j++) {\n            auto [u, v, w] = edges[j];\n            u--; v--; // Convert to 0-indexed\n            \n            // Check if this edge connects a reached and unreached vertex\n            bool connects = (vertex_reached[u] && !vertex_reached[v]) || \n                           (vertex_reached[v] && !vertex_reached[u]);\n            \n            if (!connects) continue;\n            \n            int new_vertex = vertex_reached[u] ? v : u;\n            \n            // Calculate how many new residents this would cover\n            int new_coverage = 0;\n            for (int k = 0; k < K; k++) {\n                if (!resident_covered[k] && resident_distances[k][new_vertex] <= MAX_POWER) {\n                    new_coverage++;\n                }\n            }\n            \n            // Efficiency = coverage per cost\n            double efficiency = (double)new_coverage / max(w, 1);\n            \n            if (efficiency > best_efficiency) {\n                best_efficiency = efficiency;\n                best_edge = j;\n            }\n        }\n        \n        if (best_edge == -1) break;\n        \n        edge_used[best_edge] = true;\n        auto [u, v, w] = edges[best_edge];\n        u--; v--;\n        int new_vertex = vertex_reached[u] ? v : u;\n        vertex_reached[new_vertex] = true;\n        \n        // Update covered residents\n        for (int k = 0; k < K; k++) {\n            if (resident_distances[k][new_vertex] <= MAX_POWER) {\n                resident_covered[k] = true;\n            }\n        }\n    }\n    \n    return edge_used;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    \n    vertices.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    edges.resize(M);\n    for (int j = 0; j < M; j++) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        edges[j] = {u, v, w};\n    }\n    \n    residents.resize(K);\n    for (int k = 0; k < K; k++) {\n        cin >> residents[k].first >> residents[k].second;\n    }\n    \n    // Select edges using improved approach\n    vector<bool> edge_used = improved_edge_selection();\n    \n    // Determine which vertices are active\n    vector<bool> vertex_active(N, false);\n    vertex_active[0] = true; // Always include vertex 1\n    \n    // BFS to find all reachable vertices\n    queue<int> q;\n    q.push(0);\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int j = 0; j < M; j++) {\n            if (!edge_used[j]) continue;\n            \n            auto [v1, v2, w] = edges[j];\n            v1--; v2--; // Convert to 0-indexed\n            \n            if (v1 == u && !vertex_active[v2]) {\n                vertex_active[v2] = true;\n                q.push(v2);\n            } else if (v2 == u && !vertex_active[v1]) {\n                vertex_active[v1] = true;\n                q.push(v1);\n            }\n        }\n    }\n    \n    // Calculate power requirements\n    vector<int> power = calculate_min_power(vertex_active);\n    \n    // Output results\n    for (int i = 0; i < N; i++) {\n        cout << power[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    for (int j = 0; j < M; j++) {\n        cout << (edge_used[j] ? 1 : 0);\n        if (j < M - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 10000;\nconst int TOTAL_BALLS = N * (N + 1) / 2;\n\nstruct Position {\n    int x, y;\n    Position() : x(0), y(0) {}\n    Position(int _x, int _y) : x(_x), y(_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\n// Directions for adjacency (6 directions in triangular grid)\nconst vector<pair<int, int>> DIRECTIONS = {\n    {-1, -1}, {-1, 0}, {0, -1}, {0, 1}, {1, 0}, {1, 1}\n};\n\nclass Pyramid {\npublic:\n    int grid[N][N];\n    vector<pair<Position, Position>> operations;\n    \n    Pyramid() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                cin >> grid[i][j];\n            }\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y <= x;\n    }\n    \n    bool is_adjacent(int x1, int y1, int x2, int y2) {\n        for (auto& dir : DIRECTIONS) {\n            int nx = x1 + dir.first;\n            int ny = y1 + dir.second;\n            if (nx == x2 && ny == y2) return true;\n        }\n        return false;\n    }\n    \n    vector<Position> get_neighbors(int x, int y) {\n        vector<Position> neighbors;\n        for (auto& dir : DIRECTIONS) {\n            int nx = x + dir.first;\n            int ny = y + dir.second;\n            if (is_valid(nx, ny)) {\n                neighbors.emplace_back(nx, ny);\n            }\n        }\n        return neighbors;\n    }\n    \n    int count_violations() {\n        int count = 0;\n        for (int i = 0; i < N - 1; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] > grid[i+1][j]) count++;\n                if (grid[i][j] > grid[i+1][j+1]) count++;\n            }\n        }\n        return count;\n    }\n    \n    void swap_balls(int x1, int y1, int x2, int y2) {\n        if (!is_adjacent(x1, y1, x2, y2)) return;\n        if (operations.size() >= MAX_OPS) return;\n        \n        swap(grid[x1][y1], grid[x2][y2]);\n        operations.emplace_back(Position(x1, y1), Position(x2, y2));\n    }\n    \n    // Find position of a specific value\n    Position find_position(int value) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j <= i; j++) {\n                if (grid[i][j] == value) {\n                    return Position(i, j);\n                }\n            }\n        }\n        return Position(-1, -1);\n    }\n    \n    void output() {\n        cout << operations.size() << \"\\n\";\n        for (auto& op : operations) {\n            cout << op.first.x << \" \" << op.first.y << \" \" \n                 << op.second.x << \" \" << op.second.y << \"\\n\";\n        }\n    }\n    \n    // Bubble sort approach: move larger elements down\n    void bubble_sort_approach() {\n        // Multiple passes of bubble sort-like approach\n        for (int pass = 0; pass < 20 && operations.size() < MAX_OPS - 10; pass++) {\n            bool changed = false;\n            \n            // Go through each level from top to bottom-1\n            for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 2; level++) {\n                // Go through each position in the level\n                for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 2; pos++) {\n                    int current = grid[level][pos];\n                    int left_child = grid[level+1][pos];\n                    int right_child = grid[level+1][pos+1];\n                    \n                    // If current is larger than either child, swap with the smaller child\n                    if (current > left_child || current > right_child) {\n                        if (left_child <= right_child) {\n                            swap_balls(level, pos, level+1, pos);\n                        } else {\n                            swap_balls(level, pos, level+1, pos+1);\n                        }\n                        changed = true;\n                    }\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n    \n    // Improved approach: work systematically level by level\n    void systematic_approach() {\n        // For each position, try to get the minimum valid value there\n        for (int level = 0; level < N - 1 && operations.size() < MAX_OPS - 5; level++) {\n            for (int pos = 0; pos <= level && operations.size() < MAX_OPS - 5; pos++) {\n                // Ensure this position has value <= both children\n                int& current = grid[level][pos];\n                int& left_child = grid[level+1][pos];\n                int& right_child = grid[level+1][pos+1];\n                \n                // Keep swapping down while violation exists\n                while ((current > left_child || current > right_child) && operations.size() < MAX_OPS - 1) {\n                    if (current > left_child && (current > right_child ? left_child <= right_child : true)) {\n                        swap_balls(level, pos, level+1, pos);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else if (current > right_child) {\n                        swap_balls(level, pos, level+1, pos+1);\n                        if (operations.size() >= MAX_OPS - 1) return;\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Local optimization: fix immediate violations\n    void local_optimization() {\n        bool improved = true;\n        int iterations = 0;\n        const int MAX_ITERATIONS = 50;\n        \n        while (improved && iterations < MAX_ITERATIONS && operations.size() < MAX_OPS - 10) {\n            improved = false;\n            iterations++;\n            \n            // Scan through all positions and fix violations\n            for (int i = 0; i < N - 1 && operations.size() < MAX_OPS - 2; i++) {\n                for (int j = 0; j <= i && operations.size() < MAX_OPS - 2; j++) {\n                    int current = grid[i][j];\n                    int left_child = grid[i+1][j];\n                    int right_child = grid[i+1][j+1];\n                    \n                    // Fix violations\n                    if (current > left_child || current > right_child) {\n                        // Swap with smaller child\n                        if (left_child <= right_child) {\n                            swap_balls(i, j, i+1, j);\n                        } else {\n                            swap_balls(i, j, i+1, j+1);\n                        }\n                        improved = true;\n                        if (operations.size() >= MAX_OPS - 2) break;\n                    }\n                }\n                if (operations.size() >= MAX_OPS - 2) break;\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    Pyramid pyramid;\n    pyramid.read_input();\n    \n    // Try multiple strategies\n    pyramid.systematic_approach();\n    pyramid.local_optimization();\n    pyramid.bubble_sort_approach();\n    pyramid.local_optimization();\n    \n    pyramid.output();\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int D = 9;\nconst int ENTRANCE_ROW = 0;\nconst int ENTRANCE_COL = 4;\n\nint N;\nbool is_obstacle[D][D];\nbool has_container[D][D];\nint container_number[D][D];\nvector<pair<int, int>> obstacles;\n\n// Directions: up, down, left, right\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\n\n// Check if coordinates are valid\nbool is_valid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\n// Check if a cell is the entrance\nbool is_entrance(int x, int y) {\n    return x == ENTRANCE_ROW && y == ENTRANCE_COL;\n}\n\n// BFS to find all reachable empty cells from entrance\nvector<vector<bool>> get_reachable() {\n    vector<vector<bool>> reachable(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    reachable[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !has_container[nx][ny] && !reachable[nx][ny]) {\n                reachable[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\n// BFS to find all reachable cells with containers from entrance\nvector<pair<int, int>> get_reachable_containers() {\n    vector<vector<bool>> visited(D, vector<bool>(D, false));\n    queue<pair<int, int>> q;\n    vector<pair<int, int>> result;\n    \n    // Start from entrance\n    q.push({ENTRANCE_ROW, ENTRANCE_COL});\n    visited[ENTRANCE_ROW][ENTRANCE_COL] = true;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        // If this cell has a container, add it to result\n        if (has_container[x][y]) {\n            result.push_back({x, y});\n        }\n        \n        for (int i = 0; i < 4; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            \n            if (is_valid(nx, ny) && !is_obstacle[nx][ny] && !visited[nx][ny]) {\n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Calculate Manhattan distance from entrance\nint manhattan_distance(int x, int y) {\n    return abs(x - ENTRANCE_ROW) + abs(y - ENTRANCE_COL);\n}\n\n// Find best position to place a container\npair<int, int> find_best_position(int container_num, int total_containers) {\n    auto reachable = get_reachable();\n    \n    pair<int, int> best_pos = {-1, -1};\n    double best_score = -1e18;\n    \n    // Try all positions\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            // Skip if it's entrance, obstacle, or already has container\n            if (is_entrance(i, j) || is_obstacle[i][j] || has_container[i][j]) {\n                continue;\n            }\n            \n            // Skip if not reachable\n            if (!reachable[i][j]) {\n                continue;\n            }\n            \n            // Calculate score based on multiple factors\n            double distance_score = -manhattan_distance(i, j) * 0.1;\n            double position_score = 0;\n            \n            // Prefer positions that are less likely to block others\n            // Count how many cells would become unreachable if we place container here\n            has_container[i][j] = true;\n            auto new_reachable = get_reachable();\n            has_container[i][j] = false;\n            \n            int blocked_count = 0;\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (!is_entrance(x, y) && !is_obstacle[x][y] && !has_container[x][y]) {\n                        if (reachable[x][y] && !new_reachable[x][y]) {\n                            blocked_count++;\n                        }\n                    }\n                }\n            }\n            \n            double blocking_penalty = -blocked_count * 0.5;\n            \n            // Prefer corners and edges for higher numbers\n            double edge_bonus = 0;\n            if (i == 0 || i == D-1 || j == 0 || j == D-1) {\n                edge_bonus = 0.2;\n            }\n            \n            // For later containers, prefer positions further from entrance\n            double adaptive_distance = (double)container_num / total_containers;\n            double adaptive_score = -(manhattan_distance(i, j) - 4 * adaptive_distance) * 0.1;\n            \n            double total_score = distance_score + blocking_penalty + edge_bonus + adaptive_score;\n            \n            if (total_score > best_score) {\n                best_score = total_score;\n                best_pos = {i, j};\n            }\n        }\n    }\n    \n    return best_pos;\n}\n\nint main() {\n    // Read input\n    cin >> D >> N;\n    \n    // Initialize arrays\n    memset(is_obstacle, false, sizeof(is_obstacle));\n    memset(has_container, false, sizeof(has_container));\n    \n    // Read obstacles\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n        obstacles.push_back({r, c});\n    }\n    \n    int total_containers = D * D - 1 - N;\n    vector<pair<int, int>> placement_order(total_containers);\n    \n    // Process each container as it arrives\n    for (int d = 0; d < total_containers; d++) {\n        int container_num;\n        cin >> container_num;\n        \n        // Find best position\n        auto pos = find_best_position(container_num, total_containers);\n        \n        // Place container\n        has_container[pos.first][pos.second] = true;\n        container_number[pos.first][pos.second] = container_num;\n        placement_order[d] = pos;\n        \n        // Output position\n        cout << pos.first << \" \" << pos.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieve containers in optimal order\n    vector<pair<int, int>> retrieval_order;\n    vector<bool> transported(total_containers, false);\n    \n    // Greedy approach: always pick the smallest accessible container number\n    while (retrieval_order.size() < total_containers) {\n        auto reachable_containers = get_reachable_containers();\n        \n        // Find the container with minimum number among reachable ones\n        int min_num = INT_MAX;\n        pair<int, int> best_container = {-1, -1};\n        \n        for (auto& pos : reachable_containers) {\n            int num = container_number[pos.first][pos.second];\n            if (num < min_num) {\n                min_num = num;\n                best_container = pos;\n            }\n        }\n        \n        // Remove this container and add to retrieval order\n        has_container[best_container.first][best_container.second] = false;\n        retrieval_order.push_back(best_container);\n    }\n    \n    // Output retrieval order\n    for (auto& pos : retrieval_order) {\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 50;\nconst int M = 100;\n\nint n = 50, m = 100;\nint input_grid[N][N];\nint output_grid[N][N];\n\n// Adjacency information\nvector<set<int>> adj_list(M + 1);\nvector<vector<bool>> is_adj(M + 1, vector<bool>(M + 1, false));\n\n// Position information for each color\nvector<vector<pair<int, int>>> color_positions(M + 1);\n\n// Find connected components and adjacencies\nvoid analyze_input() {\n    // Collect positions for each color\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            color_positions[color].push_back({i, j});\n        }\n    }\n    \n    // Find adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int color = input_grid[i][j];\n            // Check 4 directions\n            int dx[] = {-1, 1, 0, 0};\n            int dy[] = {0, 0, -1, 1};\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = i + dx[k];\n                int nj = j + dy[k];\n                \n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int neighbor_color = input_grid[ni][nj];\n                    if (color != neighbor_color) {\n                        is_adj[color][neighbor_color] = true;\n                        is_adj[neighbor_color][color] = true;\n                        adj_list[color].insert(neighbor_color);\n                        adj_list[neighbor_color].insert(color);\n                    }\n                } else {\n                    // Boundary - adjacent to outside (color 0)\n                    is_adj[color][0] = true;\n                    is_adj[0][color] = true;\n                    adj_list[color].insert(0);\n                    adj_list[0].insert(color);\n                }\n            }\n        }\n    }\n}\n\n// Simple greedy approach: place colors in a compact way\nvoid generate_output() {\n    // Initialize output grid with 0s\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output_grid[i][j] = 0;\n        }\n    }\n    \n    // Place colors in a spiral pattern starting from center\n    int center_x = N / 2;\n    int center_y = N / 2;\n    \n    // Place color 0 (outside) everywhere first\n    // Then we'll overwrite with other colors\n    \n    vector<bool> placed(M + 1, false);\n    placed[0] = true;\n    \n    // Place colors in order, trying to make them adjacent as required\n    queue<int> to_place;\n    set<int> remaining;\n    \n    for (int i = 1; i <= m; i++) {\n        remaining.insert(i);\n    }\n    \n    // Start with color 1 at center\n    output_grid[center_x][center_y] = 1;\n    placed[1] = true;\n    remaining.erase(1);\n    to_place.push(1);\n    \n    // BFS-like placement to maintain adjacencies\n    int dx[] = {-1, 1, 0, 0};\n    int dy[] = {0, 0, -1, 1};\n    \n    while (!to_place.empty() && !remaining.empty()) {\n        int current_color = to_place.front();\n        to_place.pop();\n        \n        // Find adjacent positions that are still 0\n        vector<pair<int, int>> adjacent_empty;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (output_grid[i][j] == current_color) {\n                    for (int k = 0; k < 4; k++) {\n                        int ni = i + dx[k];\n                        int nj = j + dy[k];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                            if (output_grid[ni][nj] == 0) {\n                                adjacent_empty.push_back({ni, nj});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Place adjacent colors\n        for (int adj_color : adj_list[current_color]) {\n            if (!placed[adj_color] && !remaining.empty() && find(remaining.begin(), remaining.end(), adj_color) != remaining.end()) {\n                if (!adjacent_empty.empty()) {\n                    auto pos = adjacent_empty.back();\n                    adjacent_empty.pop_back();\n                    output_grid[pos.first][pos.second] = adj_color;\n                    placed[adj_color] = true;\n                    remaining.erase(adj_color);\n                    to_place.push(adj_color);\n                }\n            }\n        }\n    }\n    \n    // Place any remaining colors\n    for (int color : remaining) {\n        // Find any empty spot\n        bool placed_color = false;\n        for (int i = 0; i < N && !placed_color; i++) {\n            for (int j = 0; j < N && !placed_color; j++) {\n                if (output_grid[i][j] == 0) {\n                    output_grid[i][j] = color;\n                    placed_color = true;\n                }\n            }\n        }\n    }\n    \n    // Expand each color to make connected regions\n    for (int color = 1; color <= m; color++) {\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_grid[i][j] == color) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.empty()) continue;\n        \n        // Use BFS to expand this color to make it more connected\n        queue<pair<int, int>> q;\n        set<pair<int, int>> visited;\n        \n        for (auto pos : positions) {\n            q.push(pos);\n            visited.insert(pos);\n        }\n        \n        int expansions = min(3, 20 - (int)positions.size()); // Limit expansion\n        int expanded = 0;\n        \n        while (!q.empty() && expanded < expansions) {\n            auto current = q.front();\n            q.pop();\n            \n            for (int k = 0; k < 4; k++) {\n                int ni = current.first + dx[k];\n                int nj = current.second + dy[k];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    if (output_grid[ni][nj] == 0 && visited.find({ni, nj}) == visited.end()) {\n                        output_grid[ni][nj] = color;\n                        visited.insert({ni, nj});\n                        q.push({ni, nj});\n                        expanded++;\n                        if (expanded >= expansions) break;\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    cin >> n >> m;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> input_grid[i][j];\n        }\n    }\n    \n    // Analyze the input to understand adjacencies\n    analyze_input();\n    \n    // Generate optimized output\n    generate_output();\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << output_grid[i][j];\n            if (j < N - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 105;\nconst double EPS = 1e-12;\n\nint N, D, Q;\nvector<vector<int>> win_count, total_count;\nvector<double> weight_estimates;\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to query the balance\nstring query(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 result;\n    cin >> result;\n    return result;\n}\n\n// Weight estimation - simpler and more robust\nvoid estimate_weights() {\n    // Initialize comparison matrices\n    win_count.assign(N, vector<int>(N, 0));\n    total_count.assign(N, vector<int>(N, 0));\n    \n    int queries_used = 0;\n    \n    // Generate all pairs\n    vector<pair<int, int>> all_pairs;\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            all_pairs.push_back({i, j});\n        }\n    }\n    \n    // Shuffle pairs\n    shuffle(all_pairs.begin(), all_pairs.end(), rng);\n    \n    // Make pairwise comparisons\n    int pairwise_limit = min(Q, (int)all_pairs.size());\n    \n    for (int i = 0; i < pairwise_limit && queries_used < Q; i++) {\n        int a = all_pairs[i].first;\n        int b = all_pairs[i].second;\n        \n        vector<int> left = {a};\n        vector<int> right = {b};\n        string result = query(left, right);\n        queries_used++;\n        \n        total_count[a][b]++;\n        total_count[b][a]++;\n        \n        if (result == \">\") {\n            win_count[a][b]++;\n        } else if (result == \"<\") {\n            win_count[b][a]++;\n        } else { // '='\n            win_count[a][b]++;\n            win_count[b][a]++;\n        }\n    }\n    \n    // Simple scoring: items that win more are heavier\n    weight_estimates.assign(N, 0.0);\n    \n    for (int i = 0; i < N; i++) {\n        int total_wins = 0;\n        int total_comparisons = 0;\n        \n        for (int j = 0; j < N; j++) {\n            if (i != j && total_count[i][j] > 0) {\n                total_wins += win_count[i][j];\n                total_comparisons += total_count[i][j];\n            }\n        }\n        \n        if (total_comparisons > 0) {\n            weight_estimates[i] = (double)total_wins / total_comparisons;\n        } else {\n            weight_estimates[i] = 0.5; // Default\n        }\n    }\n}\n\n// Multi-way partitioning - LPT algorithm\nvector<int> multi_way_partition() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Create list of items sorted by weight (descending)\n    vector<pair<double, int>> sorted_items;\n    for (int i = 0; i < N; i++) {\n        sorted_items.push_back({weight_estimates[i], i});\n    }\n    sort(sorted_items.rbegin(), sorted_items.rend());\n    \n    // Assign each item to the group with minimum current sum\n    for (const auto& item : sorted_items) {\n        double weight = item.first;\n        int item_id = item.second;\n        \n        int best_group = 0;\n        double min_sum = group_sums[0];\n        \n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight;\n    }\n    \n    return assignment;\n}\n\n// Local search improvement\nvector<int> local_search(vector<int> initial_assignment) {\n    vector<int> assignment = initial_assignment;\n    vector<double> group_sums(D, 0.0);\n    \n    // Calculate initial group sums\n    for (int i = 0; i < N; i++) {\n        group_sums[assignment[i]] += weight_estimates[i];\n    }\n    \n    // Local search\n    bool improved = true;\n    int stagnation = 0;\n    const int MAX_STAGNATION = 50;\n    \n    while (improved && stagnation < MAX_STAGNATION) {\n        improved = false;\n        \n        // Try moving each item to a different group\n        for (int i = 0; i < N; i++) {\n            int current_group = assignment[i];\n            double item_weight = weight_estimates[i];\n            \n            for (int new_group = 0; new_group < D; new_group++) {\n                if (new_group == current_group) continue;\n                \n                // Calculate current variance\n                double current_mean = 0;\n                for (int g = 0; g < D; g++) current_mean += group_sums[g];\n                current_mean /= D;\n                \n                double current_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    double diff = group_sums[g] - current_mean;\n                    current_variance += diff * diff;\n                }\n                current_variance /= D;\n                \n                // Simulate move\n                group_sums[current_group] -= item_weight;\n                group_sums[new_group] += item_weight;\n                \n                // Calculate new variance\n                double new_mean = 0;\n                for (int g = 0; g < D; g++) new_mean += group_sums[g];\n                new_mean /= D;\n                \n                double new_variance = 0;\n                for (int g = 0; g < D; g++) {\n                    double diff = group_sums[g] - new_mean;\n                    new_variance += diff * diff;\n                }\n                new_variance /= D;\n                \n                // Accept improving move\n                if (new_variance < current_variance - EPS) {\n                    assignment[i] = new_group;\n                    improved = true;\n                    stagnation = 0;\n                    break;\n                } else {\n                    // Revert move\n                    group_sums[current_group] += item_weight;\n                    group_sums[new_group] -= item_weight;\n                }\n            }\n            \n            if (improved) break;\n        }\n        \n        if (!improved) {\n            stagnation++;\n        }\n    }\n    \n    return assignment;\n}\n\n// Simple greedy as alternative\nvector<int> simple_greedy() {\n    vector<int> assignment(N, 0);\n    vector<double> group_sums(D, 0.0);\n    \n    // Assign items in order of estimated weight (heaviest first)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.push_back({weight_estimates[i], i});\n    }\n    sort(items.rbegin(), items.rend());\n    \n    for (const auto& item : items) {\n        int item_id = item.second;\n        \n        // Find group with minimum sum\n        int best_group = 0;\n        double min_sum = group_sums[0];\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < min_sum) {\n                min_sum = group_sums[g];\n                best_group = g;\n            }\n        }\n        \n        assignment[item_id] = best_group;\n        group_sums[best_group] += weight_estimates[item_id];\n    }\n    \n    return assignment;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    // Estimate weights\n    estimate_weights();\n    \n    // Generate multiple solutions and pick the best\n    vector<int> solution1 = multi_way_partition();\n    vector<int> solution2 = local_search(solution1);\n    vector<int> solution3 = simple_greedy();\n    \n    // Evaluate solutions\n    auto evaluate_variance = [&](const vector<int>& assignment) -> double {\n        vector<double> sums(D, 0.0);\n        for (int i = 0; i < N; i++) {\n            sums[assignment[i]] += weight_estimates[i];\n        }\n        \n        double mean = 0;\n        for (int g = 0; g < D; g++) mean += sums[g];\n        mean /= D;\n        \n        double variance = 0;\n        for (int g = 0; g < D; g++) {\n            double diff = sums[g] - mean;\n            variance += diff * diff;\n        }\n        variance /= D;\n        \n        return variance;\n    };\n    \n    double var1 = evaluate_variance(solution1);\n    double var2 = evaluate_variance(solution2);\n    double var3 = evaluate_variance(solution3);\n    \n    // Output best solution\n    vector<int> best_solution;\n    if (var1 <= var2 && var1 <= var3) {\n        best_solution = solution1;\n    } else if (var2 <= var3) {\n        best_solution = solution2;\n    } else {\n        best_solution = solution3;\n    }\n    \n    // Output result\n    for (int i = 0; i < N; i++) {\n        cout << best_solution[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 200;\nconst int M = 10;\nconst int STACK_SIZE = N / M;\n\nstruct State {\n    vector<deque<int>> stacks;\n    vector<pair<int, int>> box_positions; // {stack_idx, position_in_stack}\n    vector<bool> removed;\n    int total_energy = 0;\n    vector<pair<int, int>> operations;\n    \n    State() : stacks(M), box_positions(N + 1), removed(N + 1, false) {}\n    \n    void initialize() {\n        for (int i = 0; i < M; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                int box = stacks[i][j];\n                box_positions[box] = {i, j};\n            }\n        }\n    }\n    \n    bool is_top(int box) {\n        auto [stack_idx, pos] = box_positions[box];\n        return pos == (int)stacks[stack_idx].size() - 1;\n    }\n    \n    int stack_height(int stack_idx) {\n        return stacks[stack_idx].size();\n    }\n    \n    pair<int, int> find_box_position(int box) {\n        return box_positions[box];\n    }\n};\n\nclass Solver {\nprivate:\n    State state;\n    \npublic:\n    Solver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Move target box to top if not already there\n            while (!state.is_top(target)) {\n                auto [stack_idx, pos] = state.find_box_position(target);\n                int boxes_above = state.stack_height(stack_idx) - pos - 1;\n                \n                // Find best destination stack\n                int best_dest = -1;\n                int min_cost = INT_MAX;\n                \n                for (int dest = 0; dest < M; dest++) {\n                    if (dest == stack_idx) continue;\n                    \n                    // Cost is number of boxes moved + 1\n                    int cost = boxes_above + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_dest = dest;\n                    }\n                }\n                \n                if (best_dest == -1) {\n                    // Fallback: pick any different stack\n                    best_dest = (stack_idx + 1) % M;\n                }\n                \n                // Execute move\n                execute_move(target, best_dest);\n            }\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\n// Improved solver with better heuristics\nclass ImprovedSolver {\nprivate:\n    State state;\n    \npublic:\n    ImprovedSolver(const vector<vector<int>>& input_stacks) {\n        for (int i = 0; i < M; i++) {\n            for (int box : input_stacks[i]) {\n                state.stacks[i].push_back(box);\n            }\n        }\n        state.initialize();\n    }\n    \n    vector<pair<int, int>> solve() {\n        for (int target = 1; target <= N; target++) {\n            if (state.removed[target]) continue;\n            \n            // Bring target to top with optimized strategy\n            bring_to_top(target);\n            \n            // Remove the box\n            execute_remove(target);\n        }\n        \n        return state.operations;\n    }\n    \nprivate:\n    void bring_to_top(int target) {\n        while (!state.is_top(target)) {\n            auto [source_stack, pos] = state.find_box_position(target);\n            int boxes_above = state.stack_height(source_stack) - pos - 1;\n            \n            // Smart destination selection\n            int best_dest = find_best_destination(source_stack, boxes_above);\n            \n            // Execute move\n            execute_move(target, best_dest);\n        }\n    }\n    \n    int find_best_destination(int source_stack, int boxes_above) {\n        // Prefer stacks with fewer boxes to minimize future conflicts\n        int best_dest = -1;\n        int min_height = INT_MAX;\n        \n        for (int dest = 0; dest < M; dest++) {\n            if (dest == source_stack) continue;\n            \n            int height = state.stack_height(dest);\n            if (height < min_height) {\n                min_height = height;\n                best_dest = dest;\n            }\n        }\n        \n        // If all stacks are full, pick one that's not the source\n        if (best_dest == -1) {\n            best_dest = (source_stack + 1) % M;\n        }\n        \n        return best_dest;\n    }\n    \n    void execute_move(int box, int dest_stack) {\n        auto [source_stack, pos] = state.find_box_position(box);\n        \n        // Calculate number of boxes to move\n        int boxes_to_move = state.stack_height(source_stack) - pos;\n        int cost = boxes_to_move;\n        \n        // Move boxes\n        vector<int> moved_boxes;\n        for (int i = pos; i < state.stack_height(source_stack); i++) {\n            moved_boxes.push_back(state.stacks[source_stack][i]);\n        }\n        \n        // Remove from source\n        state.stacks[source_stack].resize(pos);\n        \n        // Add to destination\n        for (int moved_box : moved_boxes) {\n            state.stacks[dest_stack].push_back(moved_box);\n        }\n        \n        // Update positions\n        for (int i = 0; i < moved_boxes.size(); i++) {\n            int moved_box = moved_boxes[i];\n            state.box_positions[moved_box] = {dest_stack, (int)state.stacks[dest_stack].size() - moved_boxes.size() + i};\n        }\n        \n        state.total_energy += cost;\n        state.operations.push_back({box, dest_stack + 1}); // 1-indexed output\n    }\n    \n    void execute_remove(int box) {\n        state.removed[box] = true;\n        state.operations.push_back({box, 0});\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    ImprovedSolver solver(stacks);\n    vector<pair<int, int>> operations = solver.solve();\n    \n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 45;\nint N;\nstring h[MAXN], v[MAXN];\nint d[MAXN][MAXN];\nbool visited[MAXN][MAXN];\n\n// Directions: Right, Down, Left, Up\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\n// Check if we can move from (i,j) to direction dir\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    \n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    // Check for walls\n    if (dir == 0 || dir == 2) { // Horizontal move\n        return v[i][min(j, nj)] == '0';\n    } else { // Vertical move\n        return h[min(i, ni)][j] == '0';\n    }\n}\n\n// DFS with priority to high dirtiness squares\nvoid dfs_priority(int i, int j, string& path) {\n    visited[i][j] = true;\n    \n    // Create list of valid unvisited neighbors\n    vector<pair<int, int>> neighbors;\n    for (int dir = 0; dir < 4; dir++) {\n        if (!can_move(i, j, dir)) continue;\n        \n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj]) {\n            neighbors.push_back({d[ni][nj], dir});\n        }\n    }\n    \n    // Sort by dirtiness (descending)\n    sort(neighbors.begin(), neighbors.end(), greater<pair<int, int>>());\n    \n    for (auto& neighbor : neighbors) {\n        int dir = neighbor.second;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        path += dir_char[dir];\n        dfs_priority(ni, nj, path);\n        path += dir_char[(dir + 2) % 4]; // Return move\n    }\n}\n\n// Create a more sophisticated path by doing multiple DFS passes\nvoid create_path(string& path) {\n    // First, do a basic DFS to ensure all squares are visited\n    memset(visited, false, sizeof(visited));\n    dfs_priority(0, 0, path);\n    \n    // If we have space, add more visits to high-value squares\n    if (path.length() < 80000) {\n        // Add a second pass, but be more selective\n        // We could implement a more complex strategy here\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    \n    // Read horizontal walls\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    // Read vertical walls\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    // Read dirtiness values\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    string path = \"\";\n    create_path(path);\n    \n    // Make sure path isn't too long\n    if (path.length() > 100000) {\n        path = path.substr(0, 100000);\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 15;\nconst int M = 200;\nconst int MAX_OPS = 5000;\n\nint n, m;\nint start_i, start_j;\nchar grid[N][N];\nvector<string> targets;\nvector<pair<int,int>> char_positions[26];\n\n// Preprocessing\nvoid preprocess() {\n    for (int i = 0; i < 26; i++) {\n        char_positions[i].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// Advanced position selection with better lookahead\npair<int, int> find_best_position(const string& s, int idx, int cur_i, int cur_j) {\n    char c = s[idx];\n    int best_score = -1e9;\n    pair<int, int> best_pos = {cur_i, cur_j};\n    \n    // Look ahead for better path planning\n    int lookahead = min(3, (int)s.length() - idx - 1);\n    \n    for (auto& pos : char_positions[c - 'A']) {\n        int move_cost = abs(pos.first - cur_i) + abs(pos.second - cur_j);\n        int total_cost = move_cost + 1; // +1 for typing\n        \n        // Calculate future costs\n        double future_cost = 0;\n        int future_pos_i = pos.first, future_pos_j = pos.second;\n        \n        for (int k = 1; k <= lookahead; k++) {\n            char next_c = s[idx + k];\n            int min_cost = 1e9;\n            pair<int, int> best_next_pos = {future_pos_i, future_pos_j};\n            \n            for (auto& next_pos : char_positions[next_c - 'A']) {\n                int cost = abs(next_pos.first - future_pos_i) + abs(next_pos.second - future_pos_j) + 1;\n                if (cost < min_cost) {\n                    min_cost = cost;\n                    best_next_pos = next_pos;\n                }\n            }\n            \n            future_cost += min_cost * pow(0.8, k); // Discount future costs\n            future_pos_i = best_next_pos.first;\n            future_pos_j = best_next_pos.second;\n        }\n        \n        // Score: higher is better (negative cost)\n        double score = -(total_cost + future_cost);\n        \n        if (score > best_score) {\n            best_score = score;\n            best_pos = pos;\n        }\n    }\n    \n    return best_pos;\n}\n\n// Calculate maximum overlap\nint calculate_max_overlap(const string& a, const string& b) {\n    int max_overlap = 0;\n    for (int i = 1; i <= min((int)a.length(), (int)b.length()); i++) {\n        if (a.substr(a.length() - i) == b.substr(0, i)) {\n            max_overlap = i;\n        }\n    }\n    return max_overlap;\n}\n\n// Very advanced superstring construction\nstring construct_advanced_superstring() {\n    vector<string> strings = targets;\n    random_shuffle(strings.begin(), strings.end());\n    \n    // Aggressive merging\n    while (strings.size() > 1) {\n        int max_overlap = -1;\n        int best_i = -1, best_j = -1;\n        string best_merged;\n        \n        int limit = min(70, (int)strings.size());\n        \n        // Exhaustive search for best merge\n        for (int i = 0; i < limit; i++) {\n            for (int j = i + 1; j < limit; j++) {\n                // Try a + b\n                int overlap1 = calculate_max_overlap(strings[i], strings[j]);\n                string merged1 = strings[i] + strings[j].substr(overlap1);\n                \n                // Try b + a\n                int overlap2 = calculate_max_overlap(strings[j], strings[i]);\n                string merged2 = strings[j] + strings[i].substr(overlap2);\n                \n                if (overlap1 > max_overlap) {\n                    max_overlap = overlap1;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged1;\n                }\n                \n                if (overlap2 > max_overlap) {\n                    max_overlap = overlap2;\n                    best_i = i;\n                    best_j = j;\n                    best_merged = merged2;\n                }\n            }\n        }\n        \n        // If no good overlap, merge first two\n        if (best_i == -1 && strings.size() >= 2) {\n            best_merged = strings[0] + strings[1];\n            best_i = 0;\n            best_j = 1;\n        } else if (best_i == -1) {\n            break;\n        }\n        \n        // Update strings\n        if (best_i > best_j) swap(best_i, best_j);\n        strings.erase(strings.begin() + best_j);\n        strings.erase(strings.begin() + best_i);\n        strings.push_back(best_merged);\n    }\n    \n    // Final combination\n    string result;\n    for (const string& s : strings) {\n        if (result.empty()) {\n            result = s;\n        } else {\n            int overlap = calculate_max_overlap(result, s);\n            result += s.substr(overlap);\n        }\n    }\n    \n    return result;\n}\n\n// Generate highly optimized path\nvector<pair<int, int>> generate_highly_optimized_path(const string& s) {\n    vector<pair<int, int>> path;\n    int cur_i = start_i, cur_j = start_j;\n    \n    for (int i = 0; i < (int)s.length(); i++) {\n        auto pos = find_best_position(s, i, cur_i, cur_j);\n        path.push_back(pos);\n        cur_i = pos.first;\n        cur_j = pos.second;\n    }\n    \n    return path;\n}\n\n// Count targets efficiently\nint count_targets_efficiently(const string& s) {\n    int count = 0;\n    for (const string& target : targets) {\n        if (s.find(target) != string::npos) {\n            count++;\n        }\n    }\n    return count;\n}\n\n// Smart coverage ensuring\nstring ensure_smart_coverage(string s) {\n    vector<bool> covered(m, false);\n    \n    // Check current coverage\n    for (int i = 0; i < m; i++) {\n        if (s.find(targets[i]) != string::npos) {\n            covered[i] = true;\n        }\n    }\n    \n    // Add missing targets intelligently\n    for (int i = 0; i < m; i++) {\n        if (!covered[i]) {\n            // Try various merge strategies\n            bool added = false;\n            \n            // Strategy 1: Overlap at end\n            for (int overlap = min(4, (int)s.length()); overlap >= 1; overlap--) {\n                string suffix = s.substr(s.length() - overlap);\n                if (targets[i].length() >= overlap && targets[i].substr(0, overlap) == suffix) {\n                    s += targets[i].substr(overlap);\n                    added = true;\n                    break;\n                }\n            }\n            \n            // Strategy 2: Overlap at beginning with current end\n            if (!added) {\n                for (int overlap = min(4, (int)targets[i].length()); overlap >= 1; overlap--) {\n                    string prefix = targets[i].substr(0, overlap);\n                    if (s.length() >= overlap && s.substr(s.length() - overlap) == prefix) {\n                        s = s.substr(0, s.length() - overlap) + targets[i];\n                        added = true;\n                        break;\n                    }\n                }\n            }\n            \n            // Strategy 3: Simple append if space allows\n            if (!added && s.length() + 5 <= 3500) {\n                s += targets[i];\n                added = true;\n            }\n            \n            // Strategy 4: Insert in middle if beneficial (complex, skip for now)\n        }\n    }\n    \n    return s;\n}\n\n// Get ultimate construction\nstring get_ultimate_construction() {\n    string best_string;\n    int best_coverage = -1;\n    \n    // Strategy 1: Advanced superstring (multiple trials)\n    for (int trial = 0; trial < 12; trial++) {\n        string candidate = construct_advanced_superstring();\n        int coverage = count_targets_efficiently(candidate);\n        \n        if (coverage > best_coverage || (coverage == best_coverage && candidate.length() < best_string.length())) {\n            best_coverage = coverage;\n            best_string = candidate;\n        }\n    }\n    \n    // Strategy 2: First N targets\n    string alternative1;\n    for (int i = 0; i < min(90, m); i++) {\n        alternative1 += targets[i];\n    }\n    int alt1_coverage = count_targets_efficiently(alternative1);\n    \n    if (alt1_coverage > best_coverage || (alt1_coverage == best_coverage && alternative1.length() < best_string.length())) {\n        best_string = alternative1;\n        best_coverage = alt1_coverage;\n    }\n    \n    // Strategy 3: All targets\n    string alternative2;\n    for (int i = 0; i < m; i++) {\n        alternative2 += targets[i];\n    }\n    int alt2_coverage = count_targets_efficiently(alternative2);\n    \n    if (alt2_coverage > best_coverage || (alt2_coverage == best_coverage && alternative2.length() < best_string.length())) {\n        best_string = alternative2;\n        best_coverage = alt2_coverage;\n    }\n    \n    // Ensure complete coverage\n    best_string = ensure_smart_coverage(best_string);\n    \n    return best_string;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> m;\n    cin >> start_i >> start_j;\n    \n    for (int i = 0; i < n; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < n; j++) {\n            grid[i][j] = line[j];\n        }\n    }\n    \n    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i];\n    }\n    \n    preprocess();\n    \n    // Get ultimate construction\n    string final_string = get_ultimate_construction();\n    \n    // Generate highly optimized path\n    auto path = generate_highly_optimized_path(final_string);\n    \n    // Limit operations\n    if (path.size() > MAX_OPS) {\n        path.resize(MAX_OPS);\n    }\n    \n    // Output\n    for (const auto& pos : path) {\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\n\nusing namespace std;\n\nconst int MAX_N = 20;\n\nint N, M;\ndouble epsilon;\nvector<vector<pair<int,int>>> oil_fields;\nvector<vector<bool>> has_oil;\nvector<vector<bool>> queried;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    // Read input\n    cin >> N >> M >> epsilon;\n    oil_fields.resize(M);\n    \n    for (int i = 0; i < M; i++) {\n        int d;\n        cin >> d;\n        oil_fields[i].resize(d);\n        for (int j = 0; j < d; j++) {\n            cin >> oil_fields[i][j].first >> oil_fields[i][j].second;\n        }\n    }\n    \n    // Initialize tracking arrays\n    has_oil.assign(N, vector<bool>(N, false));\n    queried.assign(N, vector<bool>(N, false));\n    \n    // Simple strategy: query all squares individually\n    // This is the baseline from the sample solution but more robust\n    vector<pair<int,int>> oil_squares;\n    \n    int max_queries = 2 * N * N - N * N / 2; // Leave some buffer for the answer\n    int query_count = 0;\n    \n    // Query squares in a systematic way\n    for (int i = 0; i < N && query_count < max_queries; i++) {\n        for (int j = 0; j < N && query_count < max_queries; j++) {\n            // Query this square\n            cout << \"q 1 \" << i << \" \" << j << \"\\n\";\n            cout.flush();\n            query_count++;\n            \n            int result;\n            cin >> result;\n            \n            if (result > 0) {\n                has_oil[i][j] = true;\n                oil_squares.push_back({i, j});\n            }\n            queried[i][j] = true;\n        }\n    }\n    \n    // Collect all squares that have oil\n    vector<pair<int,int>> result_squares;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (has_oil[i][j]) {\n                result_squares.push_back({i, j});\n            }\n        }\n    }\n    \n    // Submit answer\n    cout << \"a \" << result_squares.size();\n    for (const auto& sq : result_squares) {\n        cout << \" \" << sq.first << \" \" << sq.second;\n    }\n    cout << \"\\n\";\n    cout.flush();\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int W = 1000;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int _i0, int _j0, int _i1, int _j1) : i0(_i0), j0(_j0), i1(_i1), j1(_j1) {}\n    int area() const { return (i1 - i0) * (j1 - j0); }\n};\n\n// Back to the working approach that gave good results\nvector<Rectangle> workingApproach(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Grid-based approach\n    int grid_dim = max(1, (int)ceil(sqrt(n)));\n    int cell_size = W / grid_dim;\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Grid position\n        int row = k / grid_dim;\n        int col = k % grid_dim;\n        \n        // Cell boundaries\n        int cell_top = row * cell_size;\n        int cell_left = col * cell_size;\n        int cell_bottom = min(W, (row + 1) * cell_size);\n        int cell_right = min(W, (col + 1) * cell_size);\n        \n        // Available space\n        int h_avail = max(1, cell_bottom - cell_top);\n        int w_avail = max(1, cell_right - cell_left);\n        \n        // Calculate dimensions for required area\n        int height = max(1, min(h_avail, (int)sqrt(required)));\n        int width = max(1, (required + height - 1) / height); // ceil division\n        \n        // Adjust if too large\n        if (width > w_avail) {\n            width = w_avail;\n            height = max(1, (required + width - 1) / width);\n            height = min(height, h_avail);\n        }\n        \n        // Small improvement: if we're significantly under target, try to expand\n        long long current_area = (long long)height * width;\n        long long target_area = required;\n        \n        // Only try to expand if we're more than 5% under target\n        if (current_area < target_area && (target_area - current_area) * 20 > target_area) {\n            // Try to expand width\n            if (width < w_avail) {\n                int expand_by = min(w_avail - width, (int)((target_area - current_area) / max(1, height)));\n                if (expand_by > 0) {\n                    width += expand_by;\n                    current_area = (long long)height * width;\n                }\n            }\n            \n            // Try to expand height if still needed\n            if (current_area < target_area && height < h_avail) {\n                int expand_by = min(h_avail - height, (int)((target_area - current_area) / max(1, width)));\n                if (expand_by > 0) {\n                    height += expand_by;\n                }\n            }\n        }\n        \n        // Final bounds enforcement\n        height = max(1, min(height, h_avail));\n        width = max(1, min(width, w_avail));\n        \n        // Position in cell (centered)\n        int top = cell_top + max(0, (h_avail - height) / 2);\n        int left = cell_left + max(0, (w_avail - width) / 2);\n        \n        // Final safety check\n        height = min(height, W - top);\n        width = min(width, W - left);\n        height = max(1, height);\n        width = max(1, width);\n        \n        result.emplace_back(top, left, top + height, left + width);\n    }\n    \n    return result;\n}\n\n// Even more conservative approach - just small tweaks to the proven method\nvector<Rectangle> refinedWorkingApproach(const vector<int>& required_areas) {\n    vector<Rectangle> result;\n    result.reserve(required_areas.size());\n    \n    int n = required_areas.size();\n    \n    // Grid approach\n    int grid_rows = max(1, (int)sqrt(n));\n    int grid_cols = (n + grid_rows - 1) / grid_rows;\n    \n    int cell_height = W / max(1, grid_rows);\n    int cell_width = W / max(1, grid_cols);\n    \n    for (int k = 0; k < n; k++) {\n        int required = required_areas[k];\n        \n        // Grid position\n        int row = k / grid_cols;\n        int col = k % grid_cols;\n        \n        // Cell boundaries\n        int cell_top = row * cell_height;\n        int cell_left = col * cell_width;\n        int cell_bottom = min(W, (row + 1) * cell_height);\n        int cell_right = min(W, (col + 1) * cell_width);\n        \n        // Available space\n        int h_avail = max(1, cell_bottom - cell_top);\n        int w_avail = max(1, cell_right - cell_left);\n        \n        // Calculate dimensions\n        int height = max(1, min(h_avail, (int)sqrt(required)));\n        int width = max(1, (required + height - 1) / height); // ceil division\n        \n        // Adjust if too wide\n        if (width > w_avail) {\n            width = w_avail;\n            height = max(1, (required + width - 1) / width);\n            height = min(height, h_avail);\n        }\n        \n        // Very conservative improvement: just ensure we're using available space well\n        // If we have extra space and are under target, expand a little\n        long long current_area = (long long)height * width;\n        if (current_area < required && width < w_avail) {\n            int extra_width = min(w_avail - width, 1); // Just add 1 pixel\n            if (extra_width > 0) {\n                width += extra_width;\n                current_area = (long long)height * width;\n            }\n        }\n        \n        if (current_area < required && height < h_avail) {\n            int extra_height = min(h_avail - height, 1); // Just add 1 pixel\n            if (extra_height > 0) {\n                height += extra_height;\n            }\n        }\n        \n        // Final bounds check\n        height = max(1, min(height, h_avail));\n        width = max(1, min(width, w_avail));\n        \n        // Position in cell\n        int top = cell_top + max(0, (h_avail - height) / 2);\n        int left = cell_left + max(0, (w_avail - width) / 2);\n        \n        // Final safety bounds\n        height = min(height, W - top);\n        width = min(width, W - left);\n        height = max(1, height);\n        width = max(1, width);\n        \n        result.emplace_back(top, left, top + height, left + width);\n    }\n    \n    return result;\n}\n\nvector<vector<Rectangle>> solve(const vector<vector<int>>& all_areas) {\n    int D = all_areas.size();\n    vector<vector<Rectangle>> result(D);\n    \n    for (int d = 0; d < D; d++) {\n        result[d] = refinedWorkingApproach(all_areas[d]);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W_input, D, N;\n    cin >> W_input >> D >> N;\n    \n    vector<vector<int>> all_areas(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> all_areas[d][k];\n        }\n    }\n    \n    // Solve\n    auto solution = solve(all_areas);\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << solution[d][k].i0 << \" \" << solution[d][k].j0 << \" \" \n                 << solution[d][k].i1 << \" \" << solution[d][k].j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint N = 9, M = 20, K = 81;\nlong long a[9][9];\nlong long s[20][3][3];\n\nstruct Operation {\n    int stamp, row, col;\n};\n\n// Calculate the gain in sum of remainders from applying a stamp at position (r,c)\nlong long calculate_gain(long long board[9][9], int stamp, int r, int c) {\n    long long gain = 0;\n    \n    // Calculate sum of remainders for affected cells before and after\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = r + i, col = c + j;\n            long long original_remainder = board[row][col] % MOD;\n            long long new_value = board[row][col] + s[stamp][i][j];\n            long long new_remainder = new_value % MOD;\n            gain += (long long)new_remainder - (long long)original_remainder;\n        }\n    }\n    \n    return gain;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> K;\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 (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> s[m][i][j];\n            }\n        }\n    }\n    \n    // Keep track of actual values (not modded yet)\n    long long board[9][9];\n    for (int i = 0; i < 9; i++) {\n        for (int j = 0; j < 9; j++) {\n            board[i][j] = a[i][j];\n        }\n    }\n    \n    vector<Operation> operations;\n    \n    // More sophisticated approach: \n    // 1. First, cover the board systematically\n    // 2. Then, apply additional operations greedily on high-impact areas\n    \n    // Phase 1: Systematic coverage (use about half the operations)\n    int phase1_ops = min(K / 2, 9);  // At most 9 non-overlapping operations\n    for (int base_r = 0; base_r < 9; base_r += 3) {\n        for (int base_c = 0; base_c < 9; base_c += 3) {\n            if ((int)operations.size() >= phase1_ops) break;\n            \n            // Find the best stamp for this region\n            long long best_increase = -1;\n            int best_stamp = 0;\n            \n            for (int stamp = 0; stamp < M; stamp++) {\n                long long gain = calculate_gain(board, stamp, base_r, base_c);\n                if (gain > best_increase) {\n                    best_increase = gain;\n                    best_stamp = stamp;\n                }\n            }\n            \n            // Apply the best stamp\n            operations.push_back({best_stamp, base_r, base_c});\n            \n            // Update board values\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[base_r + i][base_c + j] += s[best_stamp][i][j];\n                }\n            }\n        }\n        if ((int)operations.size() >= phase1_ops) break;\n    }\n    \n    // Phase 2: Greedy optimization with remaining operations\n    int remaining_ops = K - operations.size();\n    for (int op = 0; op < remaining_ops; op++) {\n        long long best_gain = -1;\n        int best_stamp = -1, best_row = -1, best_col = -1;\n        \n        // Try all possible stamp placements, but prioritize high-impact ones\n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int r = 0; r <= 6; r++) {\n                for (int c = 0; c <= 6; c++) {\n                    long long gain = calculate_gain(board, stamp, r, c);\n                    if (gain > best_gain) {\n                        best_gain = gain;\n                        best_stamp = stamp;\n                        best_row = r;\n                        best_col = c;\n                    }\n                }\n            }\n        }\n        \n        // If no positive gain, stop early\n        if (best_gain <= 0) {\n            break;\n        }\n        \n        // Apply the best operation\n        operations.push_back({best_stamp, best_row, best_col});\n        \n        // Update board values\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_row + i][best_col + j] += s[best_stamp][i][j];\n            }\n        }\n    }\n    \n    // Output result\n    cout << operations.size() << \"\\n\";\n    for (const auto& op : operations) {\n        cout << op.stamp << \" \" << op.row << \" \" << op.col << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nvoid solve() {\n    // Read input\n    int n;\n    cin >> n;\n    vector<vector<int>> A(5, vector<int>(5));\n    for (int i = 0; i < 5; i++) {\n        for (int j = 0; j < 5; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    // Create actions for each crane\n    vector<string> actions(5);\n    \n    // Optimized strategy with better timing\n    for (int turn = 0; turn < 500; turn++) {\n        for (int crane_id = 0; crane_id < 5; crane_id++) {\n            // Staggered pattern with better spacing\n            int cycle_position = (turn + crane_id * 20) % 100;\n            \n            if (cycle_position == 0) {\n                actions[crane_id] += 'P';  // Pick up container\n            } else if (cycle_position >= 1 && cycle_position <= 4) {\n                actions[crane_id] += 'R';  // Move right toward dispatch gate\n            } else if (cycle_position == 5) {\n                actions[crane_id] += 'Q';  // Drop at dispatch gate\n            } else if (cycle_position >= 6 && cycle_position <= 9) {\n                actions[crane_id] += 'L';  // Move back toward receiving gate\n            } else {\n                actions[crane_id] += '.';\n            }\n        }\n    }\n    \n    // Ensure all action strings have the same length\n    int max_len = 0;\n    for (int i = 0; i < 5; i++) {\n        max_len = max(max_len, (int)actions[i].length());\n    }\n    \n    // Pad to required length\n    max_len = max(max_len, 500);\n    \n    for (int i = 0; i < 5; i++) {\n        while ((int)actions[i].length() < max_len) {\n            actions[i] += '.';\n        }\n        if (actions[i].empty()) actions[i] = \".\";\n        cout << actions[i] << \"\\n\";\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    solve();\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\n// Manhattan distance\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\n// Get moves to go from (x1,y1) to (x2,y2)\nvector<string> get_path(int x1, int y1, int x2, int y2) {\n    vector<string> moves;\n    while (x1 < x2) {\n        moves.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        moves.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        moves.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        moves.push_back(\"L\");\n        y1--;\n    }\n    return moves;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<int>> grid(n, vector<int>(n));\n    vector<pair<int, int>> positives, negatives;\n    vector<int> pos_amounts, neg_amounts;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n            if (grid[i][j] > 0) {\n                positives.push_back({i, j});\n                pos_amounts.push_back(grid[i][j]);\n            } else if (grid[i][j] < 0) {\n                negatives.push_back({i, j});\n                neg_amounts.push_back(-grid[i][j]);\n            }\n        }\n    }\n    \n    vector<string> result;\n    int curr_x = 0, curr_y = 0;\n    \n    // Improved greedy approach: prioritize cells closer to current position\n    vector<int> pos_remaining = pos_amounts;\n    vector<int> neg_remaining = neg_amounts;\n    vector<bool> pos_done(positives.size(), false);\n    \n    // Continue until all positive cells are processed\n    while (true) {\n        // Find the nearest positive cell with remaining soil\n        int best_pos = -1;\n        int best_dist = 1e9;\n        \n        for (int i = 0; i < positives.size(); i++) {\n            if (pos_remaining[i] > 0 && !pos_done[i]) {\n                int px = positives[i].first;\n                int py = positives[i].second;\n                int dist = manhattan(curr_x, curr_y, px, py);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pos = i;\n                }\n            }\n        }\n        \n        if (best_pos == -1) break; // No more positive cells\n        \n        int i = best_pos;\n        pos_done[i] = true;\n        \n        int px = positives[i].first;\n        int py = positives[i].second;\n        int amount_to_distribute = pos_remaining[i];\n        \n        // Create list of negative cells with distances from THIS positive cell\n        vector<pair<int, int>> neg_cells_with_dist; // {distance, index}\n        for (int j = 0; j < negatives.size(); j++) {\n            if (neg_remaining[j] > 0) {\n                int nx = negatives[j].first;\n                int ny = negatives[j].second;\n                int dist = manhattan(px, py, nx, ny);\n                neg_cells_with_dist.push_back({dist, j});\n            }\n        }\n        \n        // Sort by distance (nearest first)\n        sort(neg_cells_with_dist.begin(), neg_cells_with_dist.end());\n        \n        // Distribute to nearest negatives\n        for (auto& [dist, j] : neg_cells_with_dist) {\n            if (amount_to_distribute <= 0) break;\n            if (neg_remaining[j] <= 0) continue;\n            \n            int transfer_amount = min(amount_to_distribute, neg_remaining[j]);\n            \n            // Go to positive cell (if not already there)\n            if (curr_x != px || curr_y != py) {\n                auto moves = get_path(curr_x, curr_y, px, py);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = px;\n                curr_y = py;\n            }\n            \n            // Load\n            result.push_back(\"+\" + to_string(transfer_amount));\n            \n            // Go to negative cell\n            int nx = negatives[j].first;\n            int ny = negatives[j].second;\n            if (curr_x != nx || curr_y != ny) {\n                auto moves = get_path(curr_x, curr_y, nx, ny);\n                result.insert(result.end(), moves.begin(), moves.end());\n                curr_x = nx;\n                curr_y = ny;\n            }\n            \n            // Unload\n            result.push_back(\"-\" + to_string(transfer_amount));\n            \n            amount_to_distribute -= transfer_amount;\n            neg_remaining[j] -= transfer_amount;\n        }\n        \n        pos_remaining[i] = amount_to_distribute;\n    }\n    \n    // Output results\n    for (const string& s : result) {\n        cout << s << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 6;\nconst int M = 15;\nconst int SEED_COUNT = 2 * N * (N - 1); // 72\n\n// Structure to hold seed information\nstruct Seed {\n    int id;\n    vector<int> values;\n    int total_value;\n    \n    Seed() : id(0), values(M, 0), total_value(0) {}\n    \n    Seed(int _id, const vector<int>& _values) : id(_id), values(_values) {\n        total_value = accumulate(values.begin(), values.end(), 0);\n    }\n};\n\n// Calculate how much a seed contributes to potential trait maxima\nint calculatePotentialScore(const Seed& seed, const vector<int>& current_max_traits) {\n    int score = seed.total_value;\n    int bonus = 0;\n    \n    // Bonus for seeds that have high values in traits\n    for (int i = 0; i < M; i++) {\n        if (seed.values[i] >= current_max_traits[i] * 0.8) {\n            bonus += 5; // Bonus for being close to trait maximum\n        }\n        if (seed.values[i] >= current_max_traits[i] * 0.95) {\n            bonus += 10; // Extra bonus for being very close to maximum\n        }\n    }\n    \n    return score + bonus;\n}\n\n// Select best seeds considering both total value and trait contributions\nvector<Seed> selectOptimalSeeds(vector<Seed>& all_seeds) {\n    // Calculate current maximum for each trait\n    vector<int> trait_max(M, 0);\n    for (const auto& seed : all_seeds) {\n        for (int i = 0; i < M; i++) {\n            trait_max[i] = max(trait_max[i], seed.values[i]);\n        }\n    }\n    \n    // Score each seed\n    vector<pair<int, int>> seed_scores; // {score, id}\n    for (int i = 0; i < SEED_COUNT; i++) {\n        int score = calculatePotentialScore(all_seeds[i], trait_max);\n        seed_scores.push_back({score, i});\n    }\n    \n    // Sort by score descending\n    sort(seed_scores.begin(), seed_scores.end(), greater<pair<int, int>>());\n    \n    // Select top N*N seeds\n    vector<Seed> selected;\n    for (int i = 0; i < N * N; i++) {\n        selected.push_back(all_seeds[seed_scores[i].second]);\n    }\n    \n    return selected;\n}\n\n// Generate placement positions with spiral pattern from center outward\nvector<pair<int, int>> generateSpiralCenterOrder() {\n    vector<pair<int, int>> positions;\n    \n    // Create all 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    // Sort by a combination of distance to center and strategic value\n    int center_i = N / 2;\n    int center_j = N / 2;\n    \n    sort(positions.begin(), positions.end(), \n         [center_i, center_j](const pair<int, int>& a, const pair<int, int>& b) {\n             // Distance to center\n             int dist_a = abs(a.first - center_i) + abs(a.second - center_j);\n             int dist_b = abs(b.first - center_i) + abs(b.second - center_j);\n             \n             // Prefer center positions, but also consider corners and edges strategically\n             // Center is most valuable (4 neighbors), then edge centers, then corners\n             if (dist_a != dist_b) {\n                 return dist_a < dist_b;\n             }\n             \n             // For same distance, prefer positions that are more \"central\"\n             int central_a = abs(abs(a.first - center_i) - abs(a.second - center_j));\n             int central_b = abs(abs(b.first - center_i) - abs(b.second - center_j));\n             \n             return central_a < central_b;\n         });\n    \n    return positions;\n}\n\n// Advanced placement considering seed compatibility\nvector<vector<int>> placeSeedsAdvanced(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending) as primary strategy\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Get positions ordered by strategic priority\n    vector<pair<int, int>> positions = generateSpiralCenterOrder();\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = seeds[i].id;\n    }\n    \n    return grid;\n}\n\n// Simple but effective placement (fallback)\nvector<vector<int>> placeSeedsSimple(vector<Seed>& seeds) {\n    vector<vector<int>> grid(N, vector<int>(N, -1));\n    \n    // Sort seeds by total value (descending)\n    sort(seeds.begin(), seeds.end(), [](const Seed& a, const Seed& b) {\n        return a.total_value > b.total_value;\n    });\n    \n    // Simple row-major order with best seeds in center area\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    // Prioritize center positions\n    int center_i = N / 2;\n    int center_j = N / 2;\n    \n    sort(positions.begin(), positions.end(), \n         [center_i, center_j](const pair<int, int>& a, const pair<int, int>& b) {\n             int dist_a = abs(a.first - center_i) + abs(a.second - center_j);\n             int dist_b = abs(b.first - center_i) + abs(b.second - center_j);\n             return dist_a < dist_b;\n         });\n    \n    // Assign seeds to positions\n    for (int i = 0; i < N * N; i++) {\n        int row = positions[i].first;\n        int col = positions[i].second;\n        grid[row][col] = seeds[i].id;\n    }\n    \n    return grid;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N_input, M_input, T;\n    cin >> N_input >> M_input >> T;\n    \n    vector<Seed> seeds(SEED_COUNT);\n    \n    // Read initial seeds\n    for (int i = 0; i < SEED_COUNT; i++) {\n        vector<int> values(M);\n        for (int j = 0; j < M; j++) {\n            cin >> values[j];\n        }\n        seeds[i] = Seed(i, values);\n    }\n    \n    // Process each turn\n    for (int turn = 0; turn < T; turn++) {\n        // Select and place seeds\n        vector<Seed> selected_seeds = selectOptimalSeeds(seeds);\n        vector<vector<int>> grid = placeSeedsSimple(selected_seeds);\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            vector<int> values(M);\n            for (int j = 0; j < M; j++) {\n                cin >> values[j];\n            }\n            seeds[i] = Seed(i, values);\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<vector<int>> source(N, vector<int>(N, 0));\n    vector<vector<int>> target(N, vector<int>(N, 0));\n    vector<vector<int>> state(N, vector<int>(N, 0));\n    \n    // Read input\n    string line;\n    for (int i = 0; i < N; i++) {\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            source[i][j] = line[j] - '0';\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            target[i][j] = line[j] - '0';\n        }\n    }\n    \n    // Copy initial state\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            state[i][j] = source[i][j];\n        }\n    }\n    \n    // Stick with simple 2-vertex working solution\n    cout << \"2\\n\";\n    cout << \"0 1\\n\";\n    int root_x = N/2;\n    int root_y = N/2;\n    cout << root_x << \" \" << root_y << \"\\n\";\n    \n    // Only one fingertip (vertex 1)\n    vector<bool> holding(2, false);\n    \n    // Run for reasonable number of turns\n    for (int turn = 0; turn < 1000; turn++) {\n        string command = \"....\"; // 4 chars for 2-vertex arm\n        \n        // Move root randomly but safely\n        int dir = rand() % 5;\n        if (dir < 4) {\n            int dx[] = {0, 1, 0, -1};\n            int dy[] = {1, 0, -1, 0};\n            int nx = root_x + dx[dir];\n            int ny = root_y + dy[dir];\n            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {\n                root_x = nx;\n                root_y = ny;\n                command[0] = \"RDLU\"[dir];\n            }\n        }\n        \n        // Fingertip is at (root_x, root_y + 1)\n        int fx = root_x;\n        int fy = root_y + 1;\n        \n        // Act only if in bounds\n        if (fx >= 0 && fx < N && fy >= 0 && fy < N) {\n            // Careful pickup\n            if (!holding[1] && state[fx][fy] == 1 && target[fx][fy] == 0) {\n                state[fx][fy] = 0;\n                holding[1] = true;\n                command[3] = 'P';\n            }\n            // Careful drop\n            else if (holding[1] && state[fx][fy] == 0 && target[fx][fy] == 1) {\n                state[fx][fy] = 1;\n                holding[1] = false;\n                command[3] = 'P';\n            }\n        }\n        \n        cout << command << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_N = 5000;\nconst int MAX_COORD = 100000;\nconst int MAX_VERTICES = 1000;\nconst long long MAX_PERIMETER = 400000LL;\n\nstruct Point {\n    int x, y;\n    bool is_mackerel;\n    \n    Point() : x(0), y(0), is_mackerel(false) {}\n    Point(int _x, int _y, bool _is_mackerel) : x(_x), y(_y), is_mackerel(_is_mackerel) {}\n};\n\nstruct Rectangle {\n    int x1, y1, x2, y2;\n    \n    Rectangle() : x1(0), y1(0), x2(0), y2(0) {}\n    Rectangle(int _x1, int _y1, int _x2, int _y2) : x1(_x1), y1(_y1), x2(_x2), y2(_y2) {}\n    \n    long long perimeter() const {\n        return 2LL * (abs(x2 - x1) + abs(y2 - y1));\n    }\n    \n    bool isValid() const {\n        return x1 >= 0 && x2 <= MAX_COORD && y1 >= 0 && y2 <= MAX_COORD && \n               x1 <= x2 && y1 <= y2;\n    }\n};\n\nvector<Point> points;\nvector<Point> mackerels, sardines;\n\nclock_t start_time;\n\npair<int, int> countPointsInRect(const Rectangle& rect) {\n    int mackerel_count = 0, sardine_count = 0;\n    \n    for (const auto& p : points) {\n        if (p.x >= rect.x1 && p.x <= rect.x2 && p.y >= rect.y1 && p.y <= rect.y2) {\n            if (p.is_mackerel) {\n                mackerel_count++;\n            } else {\n                sardine_count++;\n            }\n        }\n    }\n    \n    return {mackerel_count, sardine_count};\n}\n\nint calculateScore(const Rectangle& rect) {\n    if (!rect.isValid()) return 0;\n    if (rect.perimeter() > MAX_PERIMETER) return 0;\n    \n    auto [m, s] = countPointsInRect(rect);\n    return max(0, m - s + 1);\n}\n\nbool hasTime() {\n    clock_t current = clock();\n    double elapsed = ((double)(current - start_time)) / CLOCKS_PER_SEC;\n    return elapsed < 1.75;\n}\n\nvector<pair<int, int>> sampleCenters() {\n    vector<pair<int, int>> centers;\n    \n    // Efficient sampling\n    int sample_rate = max(1, (int)mackerels.size() / 100);\n    for (int i = 0; i < (int)mackerels.size() && hasTime(); i += sample_rate) {\n        centers.push_back({mackerels[i].x, mackerels[i].y});\n    }\n    \n    // Strategic points\n    if (!mackerels.empty() && hasTime()) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        centers.push_back({(min_x + max_x) / 2, (min_y + max_y) / 2});\n        centers.push_back({min_x, min_y});\n        centers.push_back({max_x, min_y});\n        centers.push_back({min_x, max_y});\n        centers.push_back({max_x, max_y});\n        \n        // Grid points\n        int grid_size = 3;\n        for (int i = 0; i <= grid_size && hasTime() && (int)centers.size() < 120; i++) {\n            for (int j = 0; j <= grid_size && hasTime() && (int)centers.size() < 120; j++) {\n                int x = min_x + (long long)(max_x - min_x) * i / grid_size;\n                int y = min_y + (long long)(max_y - min_y) * j / grid_size;\n                centers.push_back({x, y});\n            }\n        }\n    }\n    \n    return centers;\n}\n\nRectangle findBestRectangle() {\n    Rectangle best_rect;\n    int best_score = 0;\n    \n    auto centers = sampleCenters();\n    \n    // Effective dimensions\n    vector<pair<int, int>> dimensions = {\n        {1000, 1000}, {2000, 2000}, {3000, 3000}, {4000, 4000}, {5000, 5000},\n        {6000, 6000}, {8000, 8000}, {10000, 10000}, {12000, 12000}, {15000, 15000},\n        {20000, 20000}, {25000, 25000}, {30000, 30000},\n        {2000, 8000}, {8000, 2000}, {3000, 12000}, {12000, 3000},\n        {4000, 15000}, {15000, 4000}, {5000, 20000}, {20000, 5000}\n    };\n    \n    for (const auto& center : centers) {\n        if (!hasTime()) break;\n        \n        int cx = center.first;\n        int cy = center.second;\n        \n        for (const auto& dim : dimensions) {\n            if (!hasTime()) break;\n            \n            int w = dim.first;\n            int h = dim.second;\n            \n            // Offset pattern\n            vector<pair<int, int>> offsets = {{0, 0}, {-1, -1}, {-1, 0}, {0, -1}, {1, 1}, {1, 0}, {0, 1}};\n            \n            for (const auto& offset : offsets) {\n                if (!hasTime()) break;\n                \n                int offset_x = offset.first * w / 6;\n                int offset_y = offset.second * h / 6;\n                \n                int x1 = max(0, cx + offset_x - w/2);\n                int y1 = max(0, cy + offset_y - h/2);\n                int x2 = min(MAX_COORD, cx + offset_x + w/2);\n                int y2 = min(MAX_COORD, cy + offset_y + h/2);\n                \n                if (x2 > x1 && y2 > y1) {\n                    Rectangle rect(x1, y1, x2, y2);\n                    if (rect.perimeter() <= MAX_PERIMETER) {\n                        int score = calculateScore(rect);\n                        if (score > best_score) {\n                            best_score = score;\n                            best_rect = rect;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\n// Enhanced optimization with multi-directional approach\nRectangle optimizeRectangle(Rectangle rect) {\n    Rectangle best_rect = rect;\n    int best_score = calculateScore(rect);\n    \n    // Multi-stage optimization\n    vector<vector<int>> stage_steps = {\n        {1000, 500},      // Coarse optimization\n        {200, 100, 50},   // Medium optimization\n        {25, 10}          // Fine optimization\n    };\n    \n    for (const auto& steps : stage_steps) {\n        if (!hasTime()) break;\n        \n        for (int step : steps) {\n            if (!hasTime()) break;\n            \n            bool improved = true;\n            int iterations = 0;\n            const int MAX_ITER = 20;\n            \n            while (improved && iterations < MAX_ITER && hasTime()) {\n                improved = false;\n                \n                // Individual boundary adjustments\n                vector<pair<int*, int>> boundaries = {\n                    {&rect.x1, -1}, {&rect.y1, -1},\n                    {&rect.x2, 1}, {&rect.y2, 1}\n                };\n                \n                for (const auto& boundary : boundaries) {\n                    if (!hasTime() || iterations >= MAX_ITER) break;\n                    \n                    int* coord = boundary.first;\n                    int direction = boundary.second;\n                    int original_value = *coord;\n                    \n                    *coord += direction * step;\n                    if (rect.isValid() && rect.perimeter() <= MAX_PERIMETER) {\n                        int score = calculateScore(rect);\n                        if (score > best_score) {\n                            best_score = score;\n                            best_rect = rect;\n                            improved = true;\n                            iterations++;\n                            break;\n                        }\n                    }\n                    *coord = original_value;\n                }\n                \n                // Simultaneous adjustments for better shapes\n                if (!improved && step >= 100 && hasTime() && iterations < MAX_ITER) {\n                    // Try expanding/shrinking in both directions\n                    vector<tuple<pair<int*, int*>, int, int>> adjustments = {\n                        {{&rect.x1, &rect.x2}, -1, 1}, // Shrink horizontally\n                        {{&rect.x1, &rect.x2}, 1, -1}, // Expand horizontally\n                        {{&rect.y1, &rect.y2}, -1, 1}, // Shrink vertically\n                        {{&rect.y1, &rect.y2}, 1, -1}  // Expand vertically\n                    };\n                    \n                    for (const auto& adj : adjustments) {\n                        if (!hasTime() || iterations >= MAX_ITER) break;\n                        \n                        auto coords = get<0>(adj);\n                        int dir1 = get<1>(adj);\n                        int dir2 = get<2>(adj);\n                        \n                        int orig1 = *(coords.first);\n                        int orig2 = *(coords.second);\n                        \n                        *(coords.first) += dir1 * step;\n                        *(coords.second) += dir2 * step;\n                        \n                        if (rect.isValid() && rect.perimeter() <= MAX_PERIMETER) {\n                            int score = calculateScore(rect);\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                                improved = true;\n                                iterations++;\n                                break;\n                            }\n                        }\n                        \n                        *(coords.first) = orig1;\n                        *(coords.second) = orig2;\n                    }\n                }\n            }\n        }\n    }\n    \n    return best_rect;\n}\n\nvector<pair<int, int>> rectangleToPolygon(const Rectangle& rect) {\n    vector<pair<int, int>> polygon;\n    polygon.push_back({rect.x1, rect.y1});\n    polygon.push_back({rect.x2, rect.y1});\n    polygon.push_back({rect.x2, rect.y2});\n    polygon.push_back({rect.x1, rect.y2});\n    return polygon;\n}\n\nint main() {\n    start_time = clock();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    points.reserve(2 * N);\n    mackerels.reserve(N);\n    sardines.reserve(N);\n    \n    // Read mackerels\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, true);\n        points.push_back(p);\n        mackerels.push_back(p);\n    }\n    \n    // Read sardines\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        Point p(x, y, false);\n        points.push_back(p);\n        sardines.push_back(p);\n    }\n    \n    // Find best rectangle\n    Rectangle best_rect = findBestRectangle();\n    \n    // Enhanced optimization\n    int initial_score = calculateScore(best_rect);\n    if (hasTime() && initial_score > 15) {\n        Rectangle optimized = optimizeRectangle(best_rect);\n        if (calculateScore(optimized) > initial_score) {\n            best_rect = optimized;\n        }\n    }\n    \n    // Simple effective fallback\n    if (calculateScore(best_rect) < 30 && !mackerels.empty()) {\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        int pad = 4000;\n        Rectangle fallback(\n            max(0, min_x - pad),\n            max(0, min_y - pad),\n            min(MAX_COORD, max_x + pad),\n            min(MAX_COORD, max_y + pad)\n        );\n        \n        if (calculateScore(fallback) > calculateScore(best_rect)) {\n            best_rect = fallback;\n        }\n    }\n    \n    // Convert to polygon\n    auto polygon = rectangleToPolygon(best_rect);\n    \n    // Output result\n    cout << polygon.size() << \"\\n\";\n    for (const auto& vertex : polygon) {\n        cout << vertex.first << \" \" << vertex.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Random number generator\nmt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Utility functions\ninline double random_double() {\n    return uniform_real_distribution<double>(0, 1)(rng);\n}\n\ninline int random_int(int a, int b) {\n    return uniform_int_distribution<int>(a, b)(rng);\n}\n\nstruct Rectangle {\n    int w, h;\n    int idx;\n    \n    Rectangle() : w(0), h(0), idx(0) {}\n    Rectangle(int _w, int _h, int _idx) : w(_w), h(_h), idx(_idx) {}\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n    \n    Placement(int _p, int _r, char _d, int _b) : p(_p), r(_r), d(_d), b(_b) {}\n};\n\nclass Packer {\nprivate:\n    int N, T, sigma;\n    vector<Rectangle> rectangles;\n    \npublic:\n    Packer() {\n        cin >> N >> T >> sigma;\n        rectangles.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            int w, h;\n            cin >> w >> h;\n            rectangles[i] = Rectangle(w, h, i);\n        }\n    }\n    \n    // Select first k rectangles\n    vector<int> selectFirst(int count) {\n        vector<int> selected;\n        count = min(count, N);\n        for (int i = 0; i < count; i++) {\n            selected.push_back(i);\n        }\n        return selected;\n    }\n    \n    // Simple placement strategy\n    vector<Placement> simplePacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle at origin\n        placements.emplace_back(selected_indices[0], random_int(0, 1), 'U', -1);\n        \n        // For remaining rectangles\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            char dir = (random_int(0, 1) == 0) ? 'U' : 'L';\n            int base = random_int(-1, i - 1);\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    // Slightly improved placement\n    vector<Placement> improvedPacking(const vector<int>& selected_indices) {\n        vector<Placement> placements;\n        \n        if (selected_indices.empty()) return placements;\n        \n        // Place first rectangle\n        placements.emplace_back(selected_indices[0], random_int(0, 1), 'U', -1);\n        \n        // Try to build more structured placement\n        for (int i = 1; i < (int)selected_indices.size(); i++) {\n            int idx = selected_indices[i];\n            int rotate = random_int(0, 1);\n            \n            // Slight bias toward vertical placement (often works better)\n            char dir = (random_double() < 0.6) ? 'U' : 'L';\n            \n            // Prefer recent bases but allow wall attachment\n            int base;\n            if (random_double() < 0.25) {\n                base = -1; // Wall attachment\n            } else {\n                base = random_int(0, i - 1); // Rectangle attachment\n            }\n            \n            placements.emplace_back(idx, rotate, dir, base);\n        }\n        \n        return placements;\n    }\n    \n    void run() {\n        for (int t = 0; t < T; t++) {\n            vector<Placement> best_placement;\n            \n            // Strategy cycling - clean and simple\n            int strategy = t % 4;\n            \n            switch (strategy) {\n                case 0: {\n                    // Use first half with simple packing\n                    int count = max(N/2, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = simplePacking(selected);\n                    break;\n                }\n                case 1: {\n                    // Use 3/4 of rectangles with improved packing\n                    int count = max(3*N/4, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = improvedPacking(selected);\n                    break;\n                }\n                case 2: {\n                    // Use all rectangles with simple packing\n                    vector<int> selected = selectFirst(N);\n                    best_placement = simplePacking(selected);\n                    break;\n                }\n                case 3: {\n                    // Use first 1/3 with improved packing\n                    int count = max(N/3, 1);\n                    vector<int> selected = selectFirst(count);\n                    best_placement = improvedPacking(selected);\n                    break;\n                }\n            }\n            \n            // Safety fallback\n            if (best_placement.empty()) {\n                vector<int> single = {0};\n                best_placement = simplePacking(single);\n            }\n            \n            // Output placement\n            cout << best_placement.size() << \"\\n\";\n            for (const auto& p : best_placement) {\n                cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << \"\\n\";\n            }\n            cout.flush();\n            \n            // Read measurement result\n            int W_meas, H_meas;\n            cin >> W_meas >> H_meas;\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.run();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXN = 1000;\nconst int MAXH = 10;\n\nint N, M, H;\nvector<int> beauty;\nvector<vector<int>> adj;\nvector<pair<int, int>> coords;\nvector<int> parent;\n\n// Strategy 1: High beauty first with smart expansion\nvoid solve_strategy1() {\n    vector<int> temp_parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Create priority queue with beauty values\n    priority_queue<pair<int, int>> pq;\n    for (int i = 0; i < N; i++) {\n        pq.push({beauty[i], i});\n    }\n    \n    while (!pq.empty()) {\n        int root = -1;\n        while (!pq.empty()) {\n            auto [b, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        temp_parent[root] = -1;\n        \n        // Build tree level by level\n        vector<vector<int>> levels(H + 1);\n        levels[0].push_back(root);\n        \n        for (int level = 0; level < H; level++) {\n            // Collect candidates with scoring function\n            vector<tuple<double, int, int>> candidates;\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Scoring: beauty divided by level penalty, plus connectivity bonus\n                        double score = (double)beauty[v] / sqrt(level + 2.0);\n                        // Bonus for vertices with more connections to unassigned nodes\n                        int unassigned_neighbors = 0;\n                        for (int w : adj[v]) {\n                            if (!assigned[w]) unassigned_neighbors++;\n                        }\n                        score += unassigned_neighbors * 0.5; // Connectivity bonus\n                        \n                        candidates.push_back({score, v, u});\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), greater<tuple<double, int, int>>());\n            \n            // Add top candidates with adaptive width\n            int max_add = min(35, max(15, 50 - level * 3)); // Wider trees early, narrower later\n            \n            int added = 0;\n            for (const auto& [score, vertex, parent_vertex] : candidates) {\n                if (added >= max_add) break;\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    temp_parent[vertex] = parent_vertex;\n                    levels[level + 1].push_back(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n    \n    parent = temp_parent;\n}\n\n// Strategy 2: Degree-based approach\nvoid solve_strategy2() {\n    vector<int> temp_parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Calculate combined score: beauty * degree\n    priority_queue<pair<long long, int>> pq; // {beauty * degree, vertex}\n    for (int i = 0; i < N; i++) {\n        long long score = (long long)beauty[i] * adj[i].size();\n        pq.push({score, i});\n    }\n    \n    while (!pq.empty()) {\n        int root = -1;\n        while (!pq.empty()) {\n            auto [score, v] = pq.top(); pq.pop();\n            if (!assigned[v]) {\n                root = v;\n                break;\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        temp_parent[root] = -1;\n        \n        // Build tree with level-aware expansion\n        vector<vector<int>> levels(H + 1);\n        levels[0].push_back(root);\n        \n        for (int level = 0; level < H; level++) {\n            vector<tuple<long long, int, int>> candidates; // {score, vertex, parent}\n            \n            for (int u : levels[level]) {\n                for (int v : adj[u]) {\n                    if (!assigned[v]) {\n                        // Comprehensive scoring function\n                        long long base_score = (long long)beauty[v] * 1000LL;\n                        \n                        // Level preference (earlier levels preferred)\n                        base_score += (long long)(H - level) * 20LL;\n                        \n                        // Expansion potential bonus\n                        int expand_potential = 0;\n                        for (int w : adj[v]) {\n                            if (!assigned[w]) expand_potential++;\n                        }\n                        base_score += expand_potential * 15LL;\n                        \n                        // Degree bonus\n                        base_score += adj[v].size() * 5LL;\n                        \n                        candidates.push_back({base_score, v, u});\n                    }\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), greater<tuple<long long, int, int>>());\n            \n            // Adaptive selection based on level\n            int quota = 0;\n            if (level == 0) quota = 40;\n            else if (level == 1) quota = 30;\n            else if (level == 2) quota = 25;\n            else quota = 20;\n            \n            int added = 0;\n            for (const auto& [score, vertex, parent_vertex] : candidates) {\n                if (added >= quota) break;\n                if (!assigned[vertex]) {\n                    assigned[vertex] = true;\n                    temp_parent[vertex] = parent_vertex;\n                    levels[level + 1].push_back(vertex);\n                    added++;\n                }\n            }\n            \n            if (levels[level + 1].empty()) break;\n        }\n    }\n    \n    // Adopt this solution if it's better\n    vector<int> level_current(N, -1);\n    for (int i = 0; i < N; i++) {\n        if (parent[i] == -1) level_current[i] = 0;\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (level_current[i] == 0) q.push(i);\n    }\n    \n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int v : adj[u]) {\n            if (parent[v] == u && level_current[v] == -1 && level_current[u] < H) {\n                level_current[v] = level_current[u] + 1;\n                q.push(v);\n            }\n        }\n    }\n    \n    long long current_score = 0;\n    for (int i = 0; i < N; i++) {\n        if (level_current[i] != -1) {\n            current_score += (long long)(level_current[i] + 1) * beauty[i];\n        }\n    }\n    \n    // Score new solution\n    vector<int> level_new(N, -1);\n    for (int i = 0; i < N; i++) {\n        if (temp_parent[i] == -1) level_new[i] = 0;\n    }\n    \n    queue<int> q2;\n    for (int i = 0; i < N; i++) {\n        if (level_new[i] == 0) q2.push(i);\n    }\n    \n    while (!q2.empty()) {\n        int u = q2.front(); q2.pop();\n        for (int v : adj[u]) {\n            if (temp_parent[v] == u && level_new[v] == -1 && level_new[u] < H) {\n                level_new[v] = level_new[u] + 1;\n                q2.push(v);\n            }\n        }\n    }\n    \n    long long new_score = 0;\n    for (int i = 0; i < N; i++) {\n        if (level_new[i] != -1) {\n            new_score += (long long)(level_new[i] + 1) * beauty[i];\n        }\n    }\n    \n    if (new_score > current_score) {\n        parent = temp_parent;\n    }\n}\n\n// Simple local improvement: try swapping parents for better vertices\nvoid simple_local_improvement() {\n    // For each vertex, see if moving it to a better parent helps\n    for (int v = 0; v < N; v++) {\n        if (parent[v] == -1) continue; // Skip roots\n        \n        int current_parent = parent[v];\n        long long current_contribution = 0;\n        \n        // Calculate current contribution through BFS\n        vector<int> current_level(N, -1);\n        for (int i = 0; i < N; i++) {\n            if (parent[i] == -1) current_level[i] = 0;\n        }\n        \n        queue<int> q;\n        for (int i = 0; i < N; i++) {\n            if (current_level[i] == 0) q.push(i);\n        }\n        \n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int w : adj[u]) {\n                if (parent[w] == u && current_level[w] == -1 && current_level[u] < H) {\n                    current_level[w] = current_level[u] + 1;\n                    q.push(w);\n                }\n            }\n        }\n        \n        current_contribution = (long long)(current_level[v] + 1) * beauty[v];\n        \n        // Try each neighbor as a new parent\n        for (int new_parent : adj[v]) {\n            if (new_parent == current_parent) continue;\n            \n            parent[v] = new_parent;\n            \n            // Check validity quickly\n            vector<int> new_level(N, -1);\n            vector<int> in_degree(N, 0);\n            for (int i = 0; i < N; i++) {\n                if (parent[i] != -1) {\n                    in_degree[parent[i]]++;\n                }\n            }\n            \n            // Simple cycle check would be complex, so just revert for now\n            parent[v] = current_parent;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> H;\n    \n    beauty.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> beauty[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Start with strategy 1\n    solve_strategy1();\n    \n    // Try strategy 2 and keep better solution\n    solve_strategy2();\n    \n    // Apply simple local improvement\n    simple_local_improvement();\n    \n    for (int i = 0; i < N; i++) {\n        cout << parent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\n// Check if column j has any Fukunokami above row i\nbool hasFukuAbove(const vector<vector<char>>& board, int i, int j) {\n    for (int r = 0; r < i; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if column j has any Fukunokami below row i\nbool hasFukuBelow(const vector<vector<char>>& board, int i, int j) {\n    for (int r = i + 1; r < N; r++) {\n        if (board[r][j] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the left of column j\nbool hasFukuLeft(const vector<vector<char>>& board, int i, int j) {\n    for (int c = 0; c < j; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\n// Check if row i has any Fukunokami to the right of column j\nbool hasFukuRight(const vector<vector<char>>& board, int i, int j) {\n    for (int c = j + 1; c < N; c++) {\n        if (board[i][c] == 'o') return true;\n    }\n    return false;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int n;\n    cin >> n;\n    \n    vector<vector<char>> board(N, vector<char>(N));\n    vector<pair<int, int>> oniPositions;\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            board[i][j] = line[j];\n            if (line[j] == 'x') {\n                oniPositions.push_back({i, j});\n            }\n        }\n    }\n    \n    vector<pair<char, int>> moves;\n    \n    // Strategy: Alternate between processing rows and columns based on efficiency\n    // Keep track of which Oni we've \"handled\"\n    vector<bool> handled(oniPositions.size(), false);\n    \n    // Group Oni by row and column\n    vector<vector<int>> oniInRow(N);\n    vector<vector<int>> oniInCol(N);\n    \n    for (int idx = 0; idx < (int)oniPositions.size(); idx++) {\n        int i = oniPositions[idx].first;\n        int j = oniPositions[idx].second;\n        oniInRow[i].push_back(idx);\n        oniInCol[j].push_back(idx);\n    }\n    \n    // Process in rounds - alternate between rows and columns\n    bool processRows = true;\n    int rounds = 0;\n    \n    while (rounds < 40) { // Safety limit\n        bool didSomething = false;\n        \n        if (processRows) {\n            // Process rows\n            for (int i = 0; i < N; i++) {\n                if (oniInRow[i].empty()) continue;\n                \n                // Check if there are unhandled Oni in this row\n                vector<int> unhandledOni;\n                for (int idx : oniInRow[i]) {\n                    if (!handled[idx]) {\n                        unhandledOni.push_back(idx);\n                    }\n                }\n                \n                if (unhandledOni.empty()) continue;\n                \n                // Get column positions of unhandled Oni\n                vector<int> cols;\n                for (int idx : unhandledOni) {\n                    cols.push_back(oniPositions[idx].second);\n                }\n                \n                // Check safety for shifting left or right\n                bool canShiftLeft = true, canShiftRight = true;\n                \n                for (int idx : unhandledOni) {\n                    int col = oniPositions[idx].second;\n                    if (hasFukuLeft(board, i, col)) {\n                        canShiftLeft = false;\n                    }\n                    if (hasFukuRight(board, i, col)) {\n                        canShiftRight = false;\n                    }\n                }\n                \n                if (canShiftLeft || canShiftRight) {\n                    if (canShiftLeft && canShiftRight) {\n                        int maxLeft = *max_element(cols.begin(), cols.end());\n                        int maxRight = N - 1 - *min_element(cols.begin(), cols.end());\n                        \n                        if (maxLeft <= maxRight) {\n                            // Shift left\n                            for (int k = 0; k < maxLeft; k++) {\n                                moves.push_back({'L', i});\n                            }\n                            for (int k = 0; k < maxLeft; k++) {\n                                moves.push_back({'R', i});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInRow[i].clear();\n                        } else {\n                            // Shift right\n                            for (int k = 0; k < maxRight; k++) {\n                                moves.push_back({'R', i});\n                            }\n                            for (int k = 0; k < maxRight; k++) {\n                                moves.push_back({'L', i});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInRow[i].clear();\n                        }\n                    } else if (canShiftLeft) {\n                        int maxLeft = *max_element(cols.begin(), cols.end());\n                        for (int k = 0; k < maxLeft; k++) {\n                            moves.push_back({'L', i});\n                        }\n                        for (int k = 0; k < maxLeft; k++) {\n                            moves.push_back({'R', i});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInRow[i].clear();\n                    } else if (canShiftRight) {\n                        int maxRight = N - 1 - *min_element(cols.begin(), cols.end());\n                        for (int k = 0; k < maxRight; k++) {\n                            moves.push_back({'R', i});\n                        }\n                        for (int k = 0; k < maxRight; k++) {\n                            moves.push_back({'L', i});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInRow[i].clear();\n                    }\n                    \n                    didSomething = true;\n                }\n            }\n        } else {\n            // Process columns\n            for (int j = 0; j < N; j++) {\n                if (oniInCol[j].empty()) continue;\n                \n                // Check if there are unhandled Oni in this column\n                vector<int> unhandledOni;\n                for (int idx : oniInCol[j]) {\n                    if (!handled[idx]) {\n                        unhandledOni.push_back(idx);\n                    }\n                }\n                \n                if (unhandledOni.empty()) continue;\n                \n                // Get row positions of unhandled Oni\n                vector<int> rows;\n                for (int idx : unhandledOni) {\n                    rows.push_back(oniPositions[idx].first);\n                }\n                \n                // Check safety for shifting up or down\n                bool canShiftUp = true, canShiftDown = true;\n                \n                for (int idx : unhandledOni) {\n                    int row = oniPositions[idx].first;\n                    if (hasFukuAbove(board, row, j)) {\n                        canShiftUp = false;\n                    }\n                    if (hasFukuBelow(board, row, j)) {\n                        canShiftDown = false;\n                    }\n                }\n                \n                if (canShiftUp || canShiftDown) {\n                    if (canShiftUp && canShiftDown) {\n                        int maxUp = *max_element(rows.begin(), rows.end());\n                        int maxDown = N - 1 - *min_element(rows.begin(), rows.end());\n                        \n                        if (maxUp <= maxDown) {\n                            // Shift up\n                            for (int k = 0; k < maxUp; k++) {\n                                moves.push_back({'U', j});\n                            }\n                            for (int k = 0; k < maxUp; k++) {\n                                moves.push_back({'D', j});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInCol[j].clear();\n                        } else {\n                            // Shift down\n                            for (int k = 0; k < maxDown; k++) {\n                                moves.push_back({'D', j});\n                            }\n                            for (int k = 0; k < maxDown; k++) {\n                                moves.push_back({'U', j});\n                            }\n                            // Mark these Oni as handled\n                            for (int idx : unhandledOni) {\n                                handled[idx] = true;\n                            }\n                            oniInCol[j].clear();\n                        }\n                    } else if (canShiftUp) {\n                        int maxUp = *max_element(rows.begin(), rows.end());\n                        for (int k = 0; k < maxUp; k++) {\n                            moves.push_back({'U', j});\n                        }\n                        for (int k = 0; k < maxUp; k++) {\n                            moves.push_back({'D', j});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInCol[j].clear();\n                    } else if (canShiftDown) {\n                        int maxDown = N - 1 - *min_element(rows.begin(), rows.end());\n                        for (int k = 0; k < maxDown; k++) {\n                            moves.push_back({'D', j});\n                        }\n                        for (int k = 0; k < maxDown; k++) {\n                            moves.push_back({'U', j});\n                        }\n                        // Mark these Oni as handled\n                        for (int idx : unhandledOni) {\n                            handled[idx] = true;\n                        }\n                        oniInCol[j].clear();\n                    }\n                    \n                    didSomething = true;\n                }\n            }\n        }\n        \n        if (!didSomething) {\n            // Try the other approach\n            processRows = !processRows;\n            rounds++;\n            if (rounds > 40) break;\n        } else {\n            processRows = !processRows; // Switch between rows and columns\n            rounds++;\n        }\n        \n        // Check if all Oni are handled\n        bool allHandled = true;\n        for (bool h : handled) {\n            if (!h) {\n                allHandled = false;\n                break;\n            }\n        }\n        if (allHandled) break;\n    }\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 100;\n\nint target[N];\nint a[N], b[N];\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    srand(42);\n    \n    int dummy_L, L;\n    cin >> dummy_L >> L;\n    for (int i = 0; i < N; i++) {\n        cin >> target[i];\n    }\n    \n    // Simple ring structure - proven to work reasonably well\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 2) % N;\n    }\n    \n    // Very conservative adjustments - only make a few strategic ones\n    vector<pair<int, int>> targets;\n    for (int i = 0; i < N; i++) {\n        targets.push_back({target[i], i});\n    }\n    sort(targets.begin(), targets.end(), greater<pair<int, int>>());\n    \n    // Only adjust the top 10 employees, and do it minimally\n    for (int i = 0; i < min(10, N/10); i++) {\n        int favored_emp = targets[i].second;\n        int favored_target = targets[i].first;\n        \n        // Very conservative - only 2-3 adjustments\n        int adjustments = min(3, max(1, favored_target / 2000));\n        \n        for (int j = 0; j < adjustments; j++) {\n            int from_emp = rand() % N;\n            // Always adjust 'a' for more predictable behavior\n            a[from_emp] = favored_emp;\n        }\n    }\n    \n    // Output result\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\nconst int N = 800;\nconst int MAX_Q = 400;\nconst int MAX_L = 15;\n\nint n, m, q, L, W;\nvector<int> G;\nvector<int> lx, rx, ly, ry;\nvector<pair<long long, long long>> centers;\nvector<vector<int>> groups;\nint queries_used = 0;\nmap<pair<int, int>, bool> known_edges; // Edges we know are in some MST\n\n// Query function with proper count tracking\nvector<pair<int, int>> query(const vector<int>& cities) {\n    if (queries_used >= q) {\n        return {}; // Don't make more queries than allowed\n    }\n    \n    if ((int)cities.size() < 2 || (int)cities.size() > L) {\n        return {};\n    }\n    \n    cout << \"? \" << (int)cities.size();\n    for (int city : cities) {\n        cout << \" \" << city;\n    }\n    cout << endl;\n    cout.flush();\n    \n    queries_used++;\n    \n    vector<pair<int, int>> result;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        if (u > v) swap(u, v);\n        result.push_back({u, v});\n        known_edges[{u, v}] = true;\n    }\n    \n    return result;\n}\n\n// Calculate center coordinates\nlong long get_center_x(int i) {\n    return (long long)(lx[i] + rx[i]);\n}\n\nlong long get_center_y(int i) {\n    return (long long)(ly[i] + ry[i]);\n}\n\n// Calculate squared distance between centers\nlong long calc_center_distance_sq(int i, int j) {\n    long long cx1 = get_center_x(i);\n    long long cy1 = get_center_y(i);\n    long long cx2 = get_center_x(j);\n    long long cy2 = get_center_y(j);\n    return (cx1 - cx2) * (cx1 - cx2) + (cy1 - cy2) * (cy1 - cy2);\n}\n\n// Simple but effective clustering - this worked well\nvoid simple_effective_clustering() {\n    // Calculate centers\n    centers.clear();\n    for (int i = 0; i < n; i++) {\n        long long cx = get_center_x(i);\n        long long cy = get_center_y(i);\n        centers.push_back({cx, cy});\n    }\n    \n    // Create list of all cities\n    vector<int> cities(n);\n    iota(cities.begin(), cities.end(), 0);\n    \n    // Sort cities by x-coordinate primarily, y-coordinate secondarily\n    sort(cities.begin(), cities.end(), [&](int a, int b) {\n        long long ax = centers[a].first;\n        long long ay = centers[a].second;\n        long long bx = centers[b].first;\n        long long by = centers[b].second;\n        \n        if (ax != bx) return ax < bx;\n        return ay < by;\n    });\n    \n    // Initialize groups\n    groups.clear();\n    groups.resize(m);\n    \n    // Assign to groups sequentially\n    int idx = 0;\n    for (int i = 0; i < m; i++) {\n        groups[i].clear();\n        for (int j = 0; j < G[i]; j++) {\n            if (idx < n) {\n                groups[i].push_back(cities[idx]);\n                idx++;\n            }\n        }\n    }\n}\n\n// Improved querying strategy - use more queries on smaller groups\nvoid improved_querying() {\n    // Create list of groups sorted by size (ascending)\n    vector<pair<int, int>> group_info; // {size, index}\n    for (int i = 0; i < m; i++) {\n        if (G[i] > 1) {\n            group_info.push_back({G[i], i});\n        }\n    }\n    \n    sort(group_info.begin(), group_info.end());\n    \n    // Query smaller groups first - they give more value per query\n    for (const auto& gi : group_info) {\n        if (queries_used >= q) break;\n        \n        int group_idx = gi.second;\n        int group_size = gi.first;\n        \n        if (group_size <= 1) continue;\n        \n        // If group is small enough, query the whole group\n        if (group_size <= L) {\n            query(groups[group_idx]);\n            if (queries_used >= q) return;\n        }\n    }\n    \n    // For larger groups, use strategic windowing\n    for (const auto& gi : group_info) {\n        if (queries_used >= q) break;\n        \n        int group_idx = gi.second;\n        int group_size = gi.first;\n        \n        if (group_size <= L) continue;\n        if (group_size <= 1) continue;\n        \n        // Use overlapping windows - but be more strategic\n        int window_size = min(L, group_size);\n        \n        // Query first window\n        vector<int> window1;\n        int end1 = min(window_size, group_size);\n        for (int j = 0; j < end1; j++) {\n            window1.push_back(groups[group_idx][j]);\n        }\n        if ((int)window1.size() >= 2) {\n            query(window1);\n        }\n        \n        if (queries_used >= q) break;\n        \n        // Query last window\n        vector<int> window2;\n        int start2 = max(0, group_size - window_size);\n        for (int j = start2; j < group_size; j++) {\n            window2.push_back(groups[group_idx][j]);\n        }\n        if ((int)window2.size() >= 2 && start2 > 0) {\n            query(window2);\n        }\n        \n        if (queries_used >= q) break;\n        \n        // For very large groups, query middle section\n        if (group_size > 2 * L && queries_used < q) {\n            vector<int> window3;\n            int mid_start = group_size / 2 - window_size/2;\n            int mid_end = min(mid_start + window_size, group_size);\n            if (mid_start > end1 && mid_end < start2) {\n                for (int j = mid_start; j < mid_end; j++) {\n                    window3.push_back(groups[group_idx][j]);\n                }\n                if ((int)window3.size() >= 2) {\n                    query(window3);\n                }\n            }\n        }\n    }\n    \n    // Use remaining queries for validation of small groups\n    for (const auto& gi : group_info) {\n        if (queries_used >= q) break;\n        \n        int group_idx = gi.second;\n        int group_size = gi.first;\n        \n        // Extra validation for very small but important groups\n        if (group_size <= 3 && group_size > 1) {\n            query(groups[group_idx]);\n        }\n    }\n}\n\n// Union-Find data structure for MST\nclass UnionFind {\nprivate:\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int root_x = find(x);\n        int root_y = find(y);\n        \n        if (root_x == root_y) return false;\n        \n        if (rank[root_x] < rank[root_y]) {\n            swap(root_x, root_y);\n        }\n        parent[root_y] = root_x;\n        if (rank[root_x] == rank[root_y]) {\n            rank[root_x]++;\n        }\n        return true;\n    }\n};\n\n// Build MST with better use of known information\nvector<pair<int, int>> build_group_mst_optimized(const vector<int>& group) {\n    if ((int)group.size() <= 1) return {};\n    \n    // If we can query the entire group and still have queries left\n    if ((int)group.size() <= L && queries_used < q) {\n        return query(group);\n    }\n    \n    // Create fast lookup for group membership\n    unordered_set<int> group_set(group.begin(), group.end());\n    \n    // Build edge list with smart prioritization\n    vector<tuple<long long, int, int>> edges; // {weight, u, v}\n    \n    // Add known MST edges with highest priority\n    for (const auto& edge : known_edges) {\n        int u = edge.first.first;\n        int v = edge.first.second;\n        if (group_set.count(u) && group_set.count(v)) {\n            edges.push_back({0LL, u, v}); // Zero weight = highest priority\n        }\n    }\n    \n    // Add all other possible edges with distance-based weights\n    for (int i = 0; i < (int)group.size(); i++) {\n        for (int j = i + 1; j < (int)group.size(); j++) {\n            int u = group[i];\n            int v = group[j];\n            if (u > v) swap(u, v);\n            \n            // Skip if already added as known edge\n            if (!known_edges.count({u, v})) {\n                long long dist = calc_center_distance_sq(u, v);\n                edges.push_back({dist, u, v});\n            }\n        }\n    }\n    \n    // Sort edges by weight\n    sort(edges.begin(), edges.end());\n    \n    // Apply Kruskal's algorithm\n    UnionFind uf(n);\n    vector<pair<int, int>> mst;\n    \n    for (const auto& edge : edges) {\n        long long weight;\n        int u, v;\n        tie(weight, u, v) = edge;\n        \n        if (uf.unite(u, v)) {\n            mst.push_back({min(u, v), max(u, v)});\n            if ((int)mst.size() == (int)group.size() - 1) break;\n        }\n    }\n    \n    // Fallback: sequential connection if something went wrong\n    if ((int)mst.size() < (int)group.size() - 1) {\n        mst.clear();\n        for (int i = 0; i < (int)group.size() - 1; i++) {\n            int u = group[i];\n            int v = group[i + 1];\n            if (u > v) swap(u, v);\n            mst.push_back({u, v});\n        }\n    }\n    \n    return mst;\n}\n\n// Build MSTs for all groups\nvector<vector<pair<int, int>>> build_all_msts() {\n    vector<vector<pair<int, int>>> result(m);\n    \n    for (int i = 0; i < m; i++) {\n        result[i] = build_group_mst_optimized(groups[i]);\n    }\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++) {\n        cin >> G[i];\n    }\n    \n    lx.resize(n);\n    rx.resize(n);\n    ly.resize(n);\n    ry.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n    }\n    \n    // Use simple but effective clustering\n    simple_effective_clustering();\n    \n    // Use improved querying\n    improved_querying();\n    \n    // Build MSTs for final answer\n    vector<vector<pair<int, int>>> msts = build_all_msts();\n    \n    // Output final answer\n    cout << \"!\" << endl;\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)groups[i].size(); j++) {\n            cout << groups[i][j];\n            if (j < (int)groups[i].size() - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n        \n        for (const auto& edge : msts[i]) {\n            cout << edge.first << \" \" << edge.second << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int INF = 1e9;\n\n// Directions: U, D, L, R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char dir_chars[4] = {'U', 'D', 'L', 'R'};\n\nstruct Point {\n    int x, y;\n    Point() : x(0), y(0) {}\n    Point(int _x, int _y) : x(_x), y(_y) {}\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nclass SkatingSolver {\nprivate:\n    int grid[N][N]; // 0 = empty, 1 = block\n    Point pos;\n    vector<Point> targets;\n    vector<string> actions;\n    \npublic:\n    SkatingSolver() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void read_input() {\n        int n, m;\n        cin >> n >> m;\n        int x, y;\n        cin >> x >> y;\n        pos = Point(x, y);\n        \n        targets.resize(m);\n        for (int i = 0; i < m; i++) {\n            cin >> targets[i].x >> targets[i].y;\n        }\n    }\n    \n    bool is_valid(int x, int y) {\n        return x >= 0 && x < N && y >= 0 && y < N;\n    }\n    \n    void add_action(char action, char direction) {\n        actions.push_back(string(1, action) + \" \" + string(1, direction));\n    }\n    \n    // Move one step in given direction\n    bool move(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (!is_valid(nx, ny) || grid[nx][ny] == 1) {\n            return false;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('M', dir_chars[dir]);\n        return true;\n    }\n    \n    // Slide until hitting a block or boundary\n    void slide(int dir) {\n        int nx = pos.x, ny = pos.y;\n        \n        while (true) {\n            int tx = nx + dx[dir];\n            int ty = ny + dy[dir];\n            \n            if (!is_valid(tx, ty) || grid[tx][ty] == 1) {\n                break;\n            }\n            \n            nx = tx;\n            ny = ty;\n        }\n        \n        pos.x = nx;\n        pos.y = ny;\n        add_action('S', dir_chars[dir]);\n    }\n    \n    // Place or remove block\n    void alter(int dir) {\n        int nx = pos.x + dx[dir];\n        int ny = pos.y + dy[dir];\n        \n        if (is_valid(nx, ny)) {\n            grid[nx][ny] = 1 - grid[nx][ny];\n        }\n        \n        add_action('A', dir_chars[dir]);\n    }\n    \n    // Find direction from point a to point b\n    int get_direction(Point a, Point b) {\n        if (a.x > b.x) return 0; // U\n        if (a.x < b.x) return 1; // D\n        if (a.y > b.y) return 2; // L\n        if (a.y < b.y) return 3; // R\n        return -1; // Same position\n    }\n    \n    // Manhattan distance\n    int manhattan_distance(Point a, Point b) {\n        return abs(a.x - b.x) + abs(a.y - b.y);\n    }\n    \n    // Simple path finding using moves only\n    void move_to_target(Point target) {\n        // Use greedy approach - move in the direction that reduces distance\n        for (int step = 0; step < 1000 && !(pos == target); step++) {\n            int best_dir = -1;\n            int min_dist = manhattan_distance(pos, target);\n            \n            // Try all directions\n            for (int dir = 0; dir < 4; dir++) {\n                int nx = pos.x + dx[dir];\n                int ny = pos.y + dy[dir];\n                \n                if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                    int dist = abs(nx - target.x) + abs(ny - target.y);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        best_dir = dir;\n                    }\n                }\n            }\n            \n            if (best_dir != -1) {\n                move(best_dir);\n            } else {\n                // If stuck, try any valid move\n                bool moved = false;\n                for (int dir = 0; dir < 4; dir++) {\n                    if (move(dir)) {\n                        moved = true;\n                        break;\n                    }\n                }\n                if (!moved) break;\n            }\n        }\n    }\n    \n    // Enhanced strategy using slides when possible\n    void smart_move_to_target(Point target) {\n        if (pos == target) return;\n        \n        // If in same row or column, consider sliding\n        if (pos.x == target.x || pos.y == target.y) {\n            int dir = get_direction(pos, target);\n            if (dir != -1) {\n                // Check if we can slide directly\n                bool can_slide_directly = true;\n                Point temp_pos = pos;\n                \n                while (!(temp_pos == target)) {\n                    int nx = temp_pos.x + dx[dir];\n                    int ny = temp_pos.y + dy[dir];\n                    \n                    if (!is_valid(nx, ny)) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    if (grid[nx][ny] == 1) {\n                        can_slide_directly = false;\n                        break;\n                    }\n                    \n                    temp_pos.x = nx;\n                    temp_pos.y = ny;\n                }\n                \n                if (can_slide_directly) {\n                    slide(dir);\n                    return;\n                }\n            }\n        }\n        \n        // Otherwise use regular move-to-target\n        move_to_target(target);\n    }\n    \n    void solve() {\n        // Visit each target in order\n        for (int i = 1; i < (int)targets.size(); i++) {\n            // If target has a block, remove it first\n            if (grid[targets[i].x][targets[i].y] == 1) {\n                // Find adjacent empty spot to remove block\n                for (int dir = 0; dir < 4; dir++) {\n                    int nx = targets[i].x + dx[dir];\n                    int ny = targets[i].y + dy[dir];\n                    \n                    if (is_valid(nx, ny) && grid[nx][ny] == 0) {\n                        // Move to adjacent position and remove block\n                        Point adj_pos(nx, ny);\n                        \n                        // Move to adjacent position\n                        move_to_target(adj_pos);\n                        \n                        // Remove block (opposite direction)\n                        int opposite_dir = (dir == 0) ? 1 : (dir == 1) ? 0 : (dir == 2) ? 3 : 2;\n                        alter(opposite_dir);\n                        break;\n                    }\n                }\n            }\n            \n            // Move to target\n            smart_move_to_target(targets[i]);\n        }\n    }\n    \n    void print_solution() {\n        for (const string& action : actions) {\n            cout << action << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    SkatingSolver solver;\n    solver.read_input();\n    solver.solve();\n    solver.print_solution();\n    \n    return 0;\n}"}}}